summaryrefslogtreecommitdiffstats
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 8b81032..dcf0311 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 8d87492..80b78bc 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 187ece1..b897c9c 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 af52c2c..e20f2e7 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 a403e8c..b2c7cad 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 c30954c..477f6ab 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 a96187f..58dea57 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 519e8a5..812ddfd 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 6ca873e..d471d5d 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 d69c74c..b860a09 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 c30709c..f43f2d09 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 4fbf1d5..cb06d6d 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 208c8a8..e7a4cf6 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 e4ab4bc..c1b0e6f 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 8747634..f50069d 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 c728fff..31a711e 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 26d5841..8e611c0 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 a0c5747..cacc217 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;
}
OpenPOWER on IntegriCloud