summary refs log tree commit diff stats
path: root/hw
diff options
context:
space:
mode:
Diffstat (limited to 'hw')
-rw-r--r--hw/bonito.c1
-rw-r--r--hw/e1000.c17
-rw-r--r--hw/etraxfs_eth.c1
-rw-r--r--hw/ide/core.c4
-rw-r--r--hw/ide/via.c1
-rw-r--r--hw/mips_int.c32
-rw-r--r--hw/pc.c6
-rw-r--r--hw/pc_piix.c6
-rw-r--r--hw/ppc440_bamboo.c2
-rw-r--r--hw/scsi-bus.c12
-rw-r--r--hw/scsi-disk.c5
-rw-r--r--hw/scsi.h1
-rw-r--r--hw/sun4m.c53
-rw-r--r--hw/virtio-9p-debug.c2
-rw-r--r--hw/virtio-blk.c10
-rw-r--r--hw/virtio-pci.c5
-rw-r--r--hw/virtio-serial-bus.c4
-rw-r--r--hw/vt82c686.c5
18 files changed, 123 insertions, 44 deletions
diff --git a/hw/bonito.c b/hw/bonito.c
index 8b810321ad..dcf031134e 100644
--- a/hw/bonito.c
+++ b/hw/bonito.c
@@ -775,7 +775,6 @@ PCIBus *bonito_init(qemu_irq *pic)
                          pci_bonito_map_irq, pic, 0x28, 32);
     pcihost->bus = b;
     qdev_init_nofail(dev);
-    pci_bus_set_mem_base(pcihost->bus, 0x10000000);
 
     d = pci_create_simple(b, PCI_DEVFN(0, 0), "Bonito");
     s = DO_UPCAST(PCIBonitoState, dev, d);
diff --git a/hw/e1000.c b/hw/e1000.c
index 8d87492e0b..80b78bc618 100644
--- a/hw/e1000.c
+++ b/hw/e1000.c
@@ -262,21 +262,20 @@ set_eecd(E1000State *s, int index, uint32_t val)
 
     s->eecd_state.old_eecd = val & (E1000_EECD_SK | E1000_EECD_CS |
             E1000_EECD_DI|E1000_EECD_FWE_MASK|E1000_EECD_REQ);
+    if (!(E1000_EECD_CS & val))			// CS inactive; nothing to do
+	return;
+    if (E1000_EECD_CS & (val ^ oldval)) {	// CS rise edge; reset state
+	s->eecd_state.val_in = 0;
+	s->eecd_state.bitnum_in = 0;
+	s->eecd_state.bitnum_out = 0;
+	s->eecd_state.reading = 0;
+    }
     if (!(E1000_EECD_SK & (val ^ oldval)))	// no clock edge
         return;
     if (!(E1000_EECD_SK & val)) {		// falling edge
         s->eecd_state.bitnum_out++;
         return;
     }
-    if (!(val & E1000_EECD_CS)) {		// rising, no CS (EEPROM reset)
-        memset(&s->eecd_state, 0, sizeof s->eecd_state);
-        /*
-         * restore old_eecd's E1000_EECD_SK (known to be on)
-         * to avoid false detection of a clock edge
-         */
-        s->eecd_state.old_eecd = E1000_EECD_SK;
-        return;
-    }
     s->eecd_state.val_in <<= 1;
     if (val & E1000_EECD_DI)
         s->eecd_state.val_in |= 1;
diff --git a/hw/etraxfs_eth.c b/hw/etraxfs_eth.c
index 187ece19ea..b897c9c167 100644
--- a/hw/etraxfs_eth.c
+++ b/hw/etraxfs_eth.c
@@ -437,6 +437,7 @@ eth_writel (void *opaque, target_phys_addr_t addr, uint32_t value)
 				eth_validate_duplex(eth);
 			}
 			eth->mdio_bus.mdc = !!(value & 4);
+			eth->regs[addr] = value;
 			break;
 
 		case RW_REC_CTRL:
diff --git a/hw/ide/core.c b/hw/ide/core.c
index af52c2cb2d..e20f2e7cbb 100644
--- a/hw/ide/core.c
+++ b/hw/ide/core.c
@@ -2630,6 +2630,10 @@ int ide_init_drive(IDEState *s, BlockDriverState *bs,
         s->drive_kind = IDE_CD;
         bdrv_set_change_cb(bs, cdrom_change_cb, s);
     } else {
+        if (!bdrv_is_inserted(s->bs)) {
+            error_report("Device needs media, but drive is empty");
+            return -1;
+        }
         if (bdrv_is_read_only(bs)) {
             error_report("Can't use a read-only drive");
             return -1;
diff --git a/hw/ide/via.c b/hw/ide/via.c
index a403e8cd98..b2c7cad622 100644
--- a/hw/ide/via.c
+++ b/hw/ide/via.c
@@ -150,7 +150,6 @@ static int vt82c686b_ide_initfn(PCIDevice *dev)
     pci_config_set_class(pci_conf, PCI_CLASS_STORAGE_IDE);
     pci_config_set_prog_interface(pci_conf, 0x8a); /* legacy ATA mode */
     pci_config_set_revision(pci_conf,0x06); /* Revision 0.6 */
-    pci_conf[PCI_HEADER_TYPE] = PCI_HEADER_TYPE_NORMAL; /* header_type */
     pci_set_long(pci_conf + PCI_CAPABILITY_LIST, 0x000000c0);
 
     qemu_register_reset(via_reset, d);
diff --git a/hw/mips_int.c b/hw/mips_int.c
index c30954caaf..477f6abf95 100644
--- a/hw/mips_int.c
+++ b/hw/mips_int.c
@@ -24,22 +24,6 @@
 #include "mips_cpudevs.h"
 #include "cpu.h"
 
-/* Raise IRQ to CPU if necessary. It must be called every time the active
-   IRQ may change */
-void cpu_mips_update_irq(CPUState *env)
-{
-    if ((env->CP0_Status & (1 << CP0St_IE)) &&
-        !(env->CP0_Status & (1 << CP0St_EXL)) &&
-        !(env->CP0_Status & (1 << CP0St_ERL)) &&
-        !(env->hflags & MIPS_HFLAG_DM)) {
-        if ((env->CP0_Status & env->CP0_Cause & CP0Ca_IP_mask) &&
-            !(env->interrupt_request & CPU_INTERRUPT_HARD)) {
-            cpu_interrupt(env, CPU_INTERRUPT_HARD);
-	}
-    } else
-        cpu_reset_interrupt(env, CPU_INTERRUPT_HARD);
-}
-
 static void cpu_mips_irq_request(void *opaque, int irq, int level)
 {
     CPUState *env = (CPUState *)opaque;
@@ -52,7 +36,12 @@ static void cpu_mips_irq_request(void *opaque, int irq, int level)
     } else {
         env->CP0_Cause &= ~(1 << (irq + CP0Ca_IP));
     }
-    cpu_mips_update_irq(env);
+
+    if (env->CP0_Cause & CP0Ca_IP_mask) {
+        cpu_interrupt(env, CPU_INTERRUPT_HARD);
+    } else {
+        cpu_reset_interrupt(env, CPU_INTERRUPT_HARD);
+    }
 }
 
 void cpu_mips_irq_init_cpu(CPUState *env)
@@ -65,3 +54,12 @@ void cpu_mips_irq_init_cpu(CPUState *env)
         env->irq[i] = qi[i];
     }
 }
+
+void cpu_mips_soft_irq(CPUState *env, int irq, int level)
+{
+    if (irq < 0 || irq > 2) {
+        return;
+    }
+
+    qemu_set_irq(env->irq[irq], level);
+}
diff --git a/hw/pc.c b/hw/pc.c
index a96187f5b5..58dea57f8e 100644
--- a/hw/pc.c
+++ b/hw/pc.c
@@ -916,8 +916,10 @@ void pc_memory_init(ram_addr_t ram_size,
                  below_4g_mem_size - 0x100000,
                  ram_addr + 0x100000);
 #if TARGET_PHYS_ADDR_BITS > 32
-    cpu_register_physical_memory(0x100000000ULL, above_4g_mem_size,
-                                 ram_addr + below_4g_mem_size);
+    if (above_4g_mem_size > 0) {
+        cpu_register_physical_memory(0x100000000ULL, above_4g_mem_size,
+                                     ram_addr + below_4g_mem_size);
+    }
 #endif
 
     /* BIOS load */
diff --git a/hw/pc_piix.c b/hw/pc_piix.c
index 519e8a5ccb..812ddfd679 100644
--- a/hw/pc_piix.c
+++ b/hw/pc_piix.c
@@ -226,7 +226,7 @@ static QEMUMachine pc_machine_v0_12 = {
     .compat_props = (GlobalProperty[]) {
         {
             .driver   = "virtio-serial-pci",
-            .property = "max_nr_ports",
+            .property = "max_ports",
             .value    = stringify(1),
         },{
             .driver   = "virtio-serial-pci",
@@ -249,7 +249,7 @@ static QEMUMachine pc_machine_v0_11 = {
             .value    = stringify(0),
         },{
             .driver   = "virtio-serial-pci",
-            .property = "max_nr_ports",
+            .property = "max_ports",
             .value    = stringify(1),
         },{
             .driver   = "virtio-serial-pci",
@@ -288,7 +288,7 @@ static QEMUMachine pc_machine_v0_10 = {
             .value    = stringify(PCI_CLASS_DISPLAY_OTHER),
         },{
             .driver   = "virtio-serial-pci",
-            .property = "max_nr_ports",
+            .property = "max_ports",
             .value    = stringify(1),
         },{
             .driver   = "virtio-serial-pci",
diff --git a/hw/ppc440_bamboo.c b/hw/ppc440_bamboo.c
index 6ca873ee7e..d471d5df77 100644
--- a/hw/ppc440_bamboo.c
+++ b/hw/ppc440_bamboo.c
@@ -186,7 +186,7 @@ static QEMUMachine bamboo_machine_v0_12 = {
     .compat_props = (GlobalProperty[]) {
         {
             .driver   = "virtio-serial-pci",
-            .property = "max_nr_ports",
+            .property = "max_ports",
             .value    = stringify(1),
         },{
             .driver   = "virtio-serial-pci",
diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c
index d69c74c4ef..b860a09edf 100644
--- a/hw/scsi-bus.c
+++ b/hw/scsi-bus.c
@@ -142,6 +142,7 @@ SCSIRequest *scsi_req_alloc(size_t size, SCSIDevice *d, uint32_t tag, uint32_t l
     req->tag = tag;
     req->lun = lun;
     req->status = -1;
+    req->enqueued = true;
     QTAILQ_INSERT_TAIL(&d->requests, req, next);
     return req;
 }
@@ -158,9 +159,17 @@ SCSIRequest *scsi_req_find(SCSIDevice *d, uint32_t tag)
     return NULL;
 }
 
+static void scsi_req_dequeue(SCSIRequest *req)
+{
+    if (req->enqueued) {
+        QTAILQ_REMOVE(&req->dev->requests, req, next);
+        req->enqueued = false;
+    }
+}
+
 void scsi_req_free(SCSIRequest *req)
 {
-    QTAILQ_REMOVE(&req->dev->requests, req, next);
+    scsi_req_dequeue(req);
     qemu_free(req);
 }
 
@@ -512,6 +521,7 @@ void scsi_req_print(SCSIRequest *req)
 void scsi_req_complete(SCSIRequest *req)
 {
     assert(req->status != -1);
+    scsi_req_dequeue(req);
     req->bus->complete(req->bus, SCSI_REASON_DONE,
                        req->tag,
                        req->status);
diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c
index c30709c550..f43f2d097c 100644
--- a/hw/scsi-disk.c
+++ b/hw/scsi-disk.c
@@ -1059,6 +1059,11 @@ static int scsi_disk_initfn(SCSIDevice *dev)
     s->bs = s->qdev.conf.bs;
     is_cd = bdrv_get_type_hint(s->bs) == BDRV_TYPE_CDROM;
 
+    if (!is_cd && !bdrv_is_inserted(s->bs)) {
+        error_report("Device needs media, but drive is empty");
+        return -1;
+    }
+
     if (bdrv_get_on_error(s->bs, 1) != BLOCK_ERR_REPORT) {
         error_report("Device doesn't support drive option rerror");
         return -1;
diff --git a/hw/scsi.h b/hw/scsi.h
index 4fbf1d5dfd..cb06d6d824 100644
--- a/hw/scsi.h
+++ b/hw/scsi.h
@@ -43,6 +43,7 @@ typedef struct SCSIRequest {
         enum SCSIXferMode mode;
     } cmd;
     BlockDriverAIOCB  *aiocb;
+    bool enqueued;
     QTAILQ_ENTRY(SCSIRequest) next;
 } SCSIRequest;
 
diff --git a/hw/sun4m.c b/hw/sun4m.c
index 208c8a86df..e7a4cf6c92 100644
--- a/hw/sun4m.c
+++ b/hw/sun4m.c
@@ -89,6 +89,7 @@
 
 #define MAX_CPUS 16
 #define MAX_PILS 16
+#define MAX_VSIMMS 4
 
 #define ESCC_CLOCK 4915200
 
@@ -98,6 +99,10 @@ struct sun4m_hwdef {
     target_phys_addr_t serial_base, fd_base;
     target_phys_addr_t afx_base, idreg_base, dma_base, esp_base, le_base;
     target_phys_addr_t tcx_base, cs_base, apc_base, aux1_base, aux2_base;
+    target_phys_addr_t bpp_base, dbri_base, sx_base;
+    struct {
+        target_phys_addr_t reg_base, vram_base;
+    } vsimm[MAX_VSIMMS];
     target_phys_addr_t ecc_base;
     uint32_t ecc_version;
     uint8_t nvram_machine_id;
@@ -810,6 +815,7 @@ static void sun4m_hw_init(const struct sun4m_hwdef *hwdef, ram_addr_t RAM_size,
     unsigned long kernel_size;
     DriveInfo *fd[MAX_FD];
     void *fw_cfg;
+    unsigned int num_vsimms;
 
     /* init CPUs */
     if (!cpu_model)
@@ -872,8 +878,22 @@ static void sun4m_hw_init(const struct sun4m_hwdef *hwdef, ram_addr_t RAM_size,
         fprintf(stderr, "qemu: Unsupported depth: %d\n", graphic_depth);
         exit (1);
     }
-    tcx_init(hwdef->tcx_base, 0x00100000, graphic_width, graphic_height,
-             graphic_depth);
+    num_vsimms = 0;
+    if (num_vsimms == 0) {
+        tcx_init(hwdef->tcx_base, 0x00100000, graphic_width, graphic_height,
+                 graphic_depth);
+    }
+
+    for (i = num_vsimms; i < MAX_VSIMMS; i++) {
+        /* vsimm registers probed by OBP */
+        if (hwdef->vsimm[i].reg_base) {
+            empty_slot_init(hwdef->vsimm[i].reg_base, 0x2000);
+        }
+    }
+
+    if (hwdef->sx_base) {
+        empty_slot_init(hwdef->sx_base, 0x2000);
+    }
 
     lance_init(&nd_table[0], hwdef->le_base, ledma, ledma_irq);
 
@@ -920,6 +940,19 @@ static void sun4m_hw_init(const struct sun4m_hwdef *hwdef, ram_addr_t RAM_size,
                              slavio_irq[5]);
     }
 
+    if (hwdef->dbri_base) {
+        /* ISDN chip with attached CS4215 audio codec */
+        /* prom space */
+        empty_slot_init(hwdef->dbri_base+0x1000, 0x30);
+        /* reg space */
+        empty_slot_init(hwdef->dbri_base+0x10000, 0x100);
+    }
+
+    if (hwdef->bpp_base) {
+        /* parallel port */
+        empty_slot_init(hwdef->bpp_base, 0x20);
+    }
+
     kernel_size = sun4m_load_kernel(kernel_filename, initrd_filename,
                                     RAM_size);
 
@@ -1063,9 +1096,25 @@ static const struct sun4m_hwdef sun4m_hwdefs[] = {
         .dma_base     = 0xef0400000ULL,
         .esp_base     = 0xef0800000ULL,
         .le_base      = 0xef0c00000ULL,
+        .bpp_base     = 0xef4800000ULL,
         .apc_base     = 0xefa000000ULL, // XXX should not exist
         .aux1_base    = 0xff1800000ULL,
         .aux2_base    = 0xff1a01000ULL,
+        .dbri_base    = 0xee0000000ULL,
+        .sx_base      = 0xf80000000ULL,
+        .vsimm        = {
+            {
+                .reg_base  = 0x9c000000ULL,
+                .vram_base = 0xfc000000ULL
+            }, {
+                .reg_base  = 0x90000000ULL,
+                .vram_base = 0xf0000000ULL
+            }, {
+                .reg_base  = 0x94000000ULL
+            }, {
+                .reg_base  = 0x98000000ULL
+            }
+        },
         .ecc_base     = 0xf00000000ULL,
         .ecc_version  = 0x20000000, // version 0, implementation 2
         .nvram_machine_id = 0x72,
diff --git a/hw/virtio-9p-debug.c b/hw/virtio-9p-debug.c
index e4ab4bca5f..c1b0e6f066 100644
--- a/hw/virtio-9p-debug.c
+++ b/hw/virtio-9p-debug.c
@@ -327,6 +327,8 @@ void pprint_pdu(V9fsPDU *pdu)
         llogfile = fopen("/tmp/pdu.log", "w");
     }
 
+    BUG_ON(!llogfile);
+
     switch (pdu->id) {
     case P9_TVERSION:
         fprintf(llogfile, "TVERSION: (");
diff --git a/hw/virtio-blk.c b/hw/virtio-blk.c
index 8747634fbe..f50069d20b 100644
--- a/hw/virtio-blk.c
+++ b/hw/virtio-blk.c
@@ -12,6 +12,7 @@
  */
 
 #include <qemu-common.h>
+#include "qemu-error.h"
 #include "virtio-blk.h"
 #ifdef __linux__
 # include <scsi/sg.h>
@@ -490,6 +491,15 @@ VirtIODevice *virtio_blk_init(DeviceState *dev, BlockConf *conf)
     static int virtio_blk_id;
     DriveInfo *dinfo;
 
+    if (!conf->bs) {
+        error_report("virtio-blk-pci: drive property not set");
+        return NULL;
+    }
+    if (!bdrv_is_inserted(conf->bs)) {
+        error_report("Device needs media, but drive is empty");
+        return NULL;
+    }
+
     s = (VirtIOBlock *)virtio_common_init("virtio-blk", VIRTIO_ID_BLOCK,
                                           sizeof(struct virtio_blk_config),
                                           sizeof(VirtIOBlock));
diff --git a/hw/virtio-pci.c b/hw/virtio-pci.c
index c728fffd73..31a711ef41 100644
--- a/hw/virtio-pci.c
+++ b/hw/virtio-pci.c
@@ -546,11 +546,10 @@ static int virtio_blk_init_pci(PCIDevice *pci_dev)
         proxy->class_code != PCI_CLASS_STORAGE_OTHER)
         proxy->class_code = PCI_CLASS_STORAGE_SCSI;
 
-    if (!proxy->block.bs) {
-        error_report("virtio-blk-pci: drive property not set");
+    vdev = virtio_blk_init(&pci_dev->qdev, &proxy->block);
+    if (!vdev) {
         return -1;
     }
-    vdev = virtio_blk_init(&pci_dev->qdev, &proxy->block);
     vdev->nvectors = proxy->nvectors;
     virtio_init_pci(proxy, vdev,
                     PCI_VENDOR_ID_REDHAT_QUMRANET,
diff --git a/hw/virtio-serial-bus.c b/hw/virtio-serial-bus.c
index 26d5841154..8e611c03e0 100644
--- a/hw/virtio-serial-bus.c
+++ b/hw/virtio-serial-bus.c
@@ -117,6 +117,7 @@ static void do_flush_queued_data(VirtIOSerialPort *port, VirtQueue *vq,
     VirtQueueElement elem;
 
     assert(port || discard);
+    assert(virtio_queue_ready(vq));
 
     while ((discard || !port->throttled) && virtqueue_pop(vq, &elem)) {
         uint8_t *buf;
@@ -139,6 +140,9 @@ static void flush_queued_data(VirtIOSerialPort *port, bool discard)
 {
     assert(port);
 
+    if (!virtio_queue_ready(port->ovq)) {
+        return;
+    }
     do_flush_queued_data(port, port->ovq, &port->vser->vdev, discard);
 }
 
diff --git a/hw/vt82c686.c b/hw/vt82c686.c
index a0c5747b59..cacc21767b 100644
--- a/hw/vt82c686.c
+++ b/hw/vt82c686.c
@@ -468,7 +468,6 @@ static int vt82c686b_pm_initfn(PCIDevice *dev)
     pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_VIA_ACPI);
     pci_config_set_class(pci_conf, PCI_CLASS_BRIDGE_OTHER);
     pci_config_set_revision(pci_conf, 0x40);
-    pci_conf[PCI_HEADER_TYPE] = PCI_HEADER_TYPE_NORMAL; // header_type
 
     pci_set_word(pci_conf + PCI_COMMAND, 0);
     pci_set_word(pci_conf + PCI_STATUS, PCI_STATUS_FAST_BACK |
@@ -556,8 +555,6 @@ static int vt82c686b_initfn(PCIDevice *d)
     pci_config_set_class(pci_conf, PCI_CLASS_BRIDGE_ISA);
     pci_config_set_prog_interface(pci_conf, 0x0);
     pci_config_set_revision(pci_conf,0x40); /* Revision 4.0 */
-    pci_conf[PCI_HEADER_TYPE] =
-        PCI_HEADER_TYPE_NORMAL | PCI_HEADER_TYPE_MULTI_FUNCTION;
 
     wmask = d->wmask;
     for (i = 0x00; i < 0xff; i++) {
@@ -575,7 +572,7 @@ int vt82c686b_init(PCIBus *bus, int devfn)
 {
     PCIDevice *d;
 
-    d = pci_create_simple(bus, devfn, "VT82C686B");
+    d = pci_create_simple_multifunction(bus, devfn, true, "VT82C686B");
 
     return d->devfn;
 }