diff options
Diffstat (limited to 'hw')
-rw-r--r-- | hw/bonito.c | 1 | ||||
-rw-r--r-- | hw/e1000.c | 17 | ||||
-rw-r--r-- | hw/etraxfs_eth.c | 1 | ||||
-rw-r--r-- | hw/ide/core.c | 4 | ||||
-rw-r--r-- | hw/ide/via.c | 1 | ||||
-rw-r--r-- | hw/mips_int.c | 32 | ||||
-rw-r--r-- | hw/pc.c | 6 | ||||
-rw-r--r-- | hw/pc_piix.c | 6 | ||||
-rw-r--r-- | hw/ppc440_bamboo.c | 2 | ||||
-rw-r--r-- | hw/scsi-bus.c | 12 | ||||
-rw-r--r-- | hw/scsi-disk.c | 5 | ||||
-rw-r--r-- | hw/scsi.h | 1 | ||||
-rw-r--r-- | hw/sun4m.c | 53 | ||||
-rw-r--r-- | hw/virtio-9p-debug.c | 2 | ||||
-rw-r--r-- | hw/virtio-blk.c | 10 | ||||
-rw-r--r-- | hw/virtio-pci.c | 5 | ||||
-rw-r--r-- | hw/virtio-serial-bus.c | 4 | ||||
-rw-r--r-- | hw/vt82c686.c | 5 |
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); @@ -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); +} @@ -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; @@ -43,6 +43,7 @@ typedef struct SCSIRequest { enum SCSIXferMode mode; } cmd; BlockDriverAIOCB *aiocb; + bool enqueued; QTAILQ_ENTRY(SCSIRequest) next; } SCSIRequest; @@ -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; } |