diff options
Diffstat (limited to 'hw')
60 files changed, 779 insertions, 560 deletions
diff --git a/hw/9pfs/virtio-9p-local.c b/hw/9pfs/virtio-9p-local.c index a183eee662..d05c91779f 100644 --- a/hw/9pfs/virtio-9p-local.c +++ b/hw/9pfs/virtio-9p-local.c @@ -332,7 +332,6 @@ static ssize_t local_readlink(FsContext *fs_ctx, V9fsPath *fs_path, tsize = read(fd, (void *)buf, bufsz); } while (tsize == -1 && errno == EINTR); close(fd); - return tsize; } else if ((fs_ctx->export_flags & V9FS_SM_PASSTHROUGH) || (fs_ctx->export_flags & V9FS_SM_NONE)) { buffer = rpath(fs_ctx, path); diff --git a/hw/arm/digic_boards.c b/hw/arm/digic_boards.c index 2a4b8720a6..7114c36e38 100644 --- a/hw/arm/digic_boards.c +++ b/hw/arm/digic_boards.c @@ -65,7 +65,7 @@ static void digic4_board_init(DigicBoard *board) s->digic = DIGIC(object_new(TYPE_DIGIC)); object_property_set_bool(OBJECT(s->digic), true, "realized", &err); if (err != NULL) { - error_report("Couldn't realize DIGIC SoC: %s\n", + error_report("Couldn't realize DIGIC SoC: %s", error_get_pretty(err)); exit(1); } @@ -104,13 +104,13 @@ static void digic_load_rom(DigicBoardState *s, hwaddr addr, char *fn = qemu_find_file(QEMU_FILE_TYPE_BIOS, filename); if (!fn) { - error_report("Couldn't find rom image '%s'.\n", filename); + error_report("Couldn't find rom image '%s'.", filename); exit(1); } rom_size = load_image_targphys(fn, addr, max_size); if (rom_size < 0 || rom_size > max_size) { - error_report("Couldn't load rom image '%s'.\n", filename); + error_report("Couldn't load rom image '%s'.", filename); exit(1); } } diff --git a/hw/arm/vexpress.c b/hw/arm/vexpress.c index 5933454cfd..8496c1622a 100644 --- a/hw/arm/vexpress.c +++ b/hw/arm/vexpress.c @@ -515,9 +515,9 @@ static pflash_t *ve_pflash_cfi01_register(hwaddr base, const char *name, { DeviceState *dev = qdev_create(NULL, "cfi.pflash01"); - if (di && qdev_prop_set_drive(dev, "drive", - blk_by_legacy_dinfo(di))) { - abort(); + if (di) { + qdev_prop_set_drive(dev, "drive", blk_by_legacy_dinfo(di), + &error_abort); } qdev_prop_set_uint32(dev, "num-blocks", diff --git a/hw/arm/virt.c b/hw/arm/virt.c index 69f51ac0da..93b7605722 100644 --- a/hw/arm/virt.c +++ b/hw/arm/virt.c @@ -522,9 +522,9 @@ static void create_one_flash(const char *name, hwaddr flashbase, DeviceState *dev = qdev_create(NULL, "cfi.pflash01"); const uint64_t sectorlength = 256 * 1024; - if (dinfo && qdev_prop_set_drive(dev, "drive", - blk_by_legacy_dinfo(dinfo))) { - abort(); + if (dinfo) { + qdev_prop_set_drive(dev, "drive", blk_by_legacy_dinfo(dinfo), + &error_abort); } qdev_prop_set_uint32(dev, "num-blocks", flashsize / sectorlength); diff --git a/hw/block/block.c b/hw/block/block.c index a625773d44..f7243e5b94 100644 --- a/hw/block/block.c +++ b/hw/block/block.c @@ -25,6 +25,30 @@ void blkconf_serial(BlockConf *conf, char **serial) } } +void blkconf_blocksizes(BlockConf *conf) +{ + BlockBackend *blk = conf->blk; + BlockSizes blocksizes; + int backend_ret; + + backend_ret = blk_probe_blocksizes(blk, &blocksizes); + /* fill in detected values if they are not defined via qemu command line */ + if (!conf->physical_block_size) { + if (!backend_ret) { + conf->physical_block_size = blocksizes.phys; + } else { + conf->physical_block_size = BDRV_SECTOR_SIZE; + } + } + if (!conf->logical_block_size) { + if (!backend_ret) { + conf->logical_block_size = blocksizes.log; + } else { + conf->logical_block_size = BDRV_SECTOR_SIZE; + } + } +} + void blkconf_geometry(BlockConf *conf, int *ptrans, unsigned cyls_max, unsigned heads_max, unsigned secs_max, Error **errp) diff --git a/hw/block/hd-geometry.c b/hw/block/hd-geometry.c index 6fcf74df44..b187878fac 100644 --- a/hw/block/hd-geometry.c +++ b/hw/block/hd-geometry.c @@ -121,8 +121,16 @@ void hd_geometry_guess(BlockBackend *blk, int *ptrans) { int cylinders, heads, secs, translation; + HDGeometry geo; - if (guess_disk_lchs(blk, &cylinders, &heads, &secs) < 0) { + /* Try to probe the backing device geometry, otherwise fallback + to the old logic. (as of 12/2014 probing only succeeds on DASDs) */ + if (blk_probe_geometry(blk, &geo) == 0) { + *pcyls = geo.cylinders; + *psecs = geo.sectors; + *pheads = geo.heads; + translation = BIOS_ATA_TRANSLATION_NONE; + } else if (guess_disk_lchs(blk, &cylinders, &heads, &secs) < 0) { /* no LCHS guess: use a standard physical disk geometry */ guess_chs_for_size(blk, pcyls, pheads, psecs); translation = hd_bios_chs_auto_trans(*pcyls, *pheads, *psecs); diff --git a/hw/block/nand.c b/hw/block/nand.c index 1882a0cbeb..61d2cec032 100644 --- a/hw/block/nand.c +++ b/hw/block/nand.c @@ -393,7 +393,7 @@ static void nand_realize(DeviceState *dev, Error **errp) nand_init_2048(s); break; default: - error_setg(errp, "Unsupported NAND block size %#x\n", + error_setg(errp, "Unsupported NAND block size %#x", 1 << s->page_shift); return; } diff --git a/hw/block/nvme.c b/hw/block/nvme.c index ce079aefdd..0f3dfb90ea 100644 --- a/hw/block/nvme.c +++ b/hw/block/nvme.c @@ -765,6 +765,7 @@ static int nvme_init(PCIDevice *pci_dev) if (!n->serial) { return -1; } + blkconf_blocksizes(&n->conf); pci_conf = pci_dev->config; pci_conf[PCI_INTERRUPT_PIN] = 1; diff --git a/hw/block/pflash_cfi01.c b/hw/block/pflash_cfi01.c index 89d380e59d..d282695086 100644 --- a/hw/block/pflash_cfi01.c +++ b/hw/block/pflash_cfi01.c @@ -969,8 +969,8 @@ pflash_t *pflash_cfi01_register(hwaddr base, { DeviceState *dev = qdev_create(NULL, TYPE_CFI_PFLASH01); - if (blk && qdev_prop_set_drive(dev, "drive", blk)) { - abort(); + if (blk) { + qdev_prop_set_drive(dev, "drive", blk, &error_abort); } qdev_prop_set_uint32(dev, "num-blocks", nb_blocs); qdev_prop_set_uint64(dev, "sector-length", sector_len); diff --git a/hw/block/pflash_cfi02.c b/hw/block/pflash_cfi02.c index 389b4aa1f4..074a005f69 100644 --- a/hw/block/pflash_cfi02.c +++ b/hw/block/pflash_cfi02.c @@ -773,8 +773,8 @@ pflash_t *pflash_cfi02_register(hwaddr base, { DeviceState *dev = qdev_create(NULL, TYPE_CFI_PFLASH02); - if (blk && qdev_prop_set_drive(dev, "drive", blk)) { - abort(); + if (blk) { + qdev_prop_set_drive(dev, "drive", blk, &error_abort); } qdev_prop_set_uint32(dev, "num-blocks", nb_blocs); qdev_prop_set_uint32(dev, "sector-length", sector_len); diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c index 1e5b918620..000c38d2a1 100644 --- a/hw/block/virtio-blk.c +++ b/hw/block/virtio-blk.c @@ -201,6 +201,7 @@ static int virtio_blk_handle_scsi_req(VirtIOBlockReq *req) #ifdef __linux__ int i; VirtIOBlockIoctlReq *ioctl_req; + BlockAIOCB *acb; #endif /* @@ -278,8 +279,13 @@ static int virtio_blk_handle_scsi_req(VirtIOBlockReq *req) ioctl_req->hdr.sbp = elem->in_sg[elem->in_num - 3].iov_base; ioctl_req->hdr.mx_sb_len = elem->in_sg[elem->in_num - 3].iov_len; - blk_aio_ioctl(blk->blk, SG_IO, &ioctl_req->hdr, - virtio_blk_ioctl_complete, ioctl_req); + acb = blk_aio_ioctl(blk->blk, SG_IO, &ioctl_req->hdr, + virtio_blk_ioctl_complete, ioctl_req); + if (!acb) { + g_free(ioctl_req); + status = VIRTIO_BLK_S_UNSUPP; + goto fail; + } return -EINPROGRESS; #else abort(); @@ -591,12 +597,6 @@ static void virtio_blk_handle_output(VirtIODevice *vdev, VirtQueue *vq) if (mrb.num_reqs) { virtio_blk_submit_multireq(s->blk, &mrb); } - - /* - * FIXME: Want to check for completions before returning to guest mode, - * so cached reads and writes are reported as quickly as possible. But - * that should be done in the generic block layer. - */ } static void virtio_blk_dma_restart_bh(void *opaque) @@ -884,6 +884,7 @@ static void virtio_blk_device_realize(DeviceState *dev, Error **errp) error_propagate(errp, err); return; } + blkconf_blocksizes(&conf->conf); virtio_init(vdev, "virtio-blk", VIRTIO_ID_BLOCK, sizeof(struct virtio_blk_config)); diff --git a/hw/char/virtio-serial-bus.c b/hw/char/virtio-serial-bus.c index 9a029d2130..c86814f059 100644 --- a/hw/char/virtio-serial-bus.c +++ b/hw/char/virtio-serial-bus.c @@ -64,7 +64,7 @@ static VirtIOSerialPort *find_port_by_name(char *name) VirtIOSerialPort *port; QTAILQ_FOREACH(port, &vser->ports, next) { - if (!strcmp(port->name, name)) { + if (port->name && !strcmp(port->name, name)) { return port; } } diff --git a/hw/core/qdev-properties-system.c b/hw/core/qdev-properties-system.c index a2e44bd4e8..c413226a97 100644 --- a/hw/core/qdev-properties-system.c +++ b/hw/core/qdev-properties-system.c @@ -341,27 +341,25 @@ PropertyInfo qdev_prop_vlan = { .set = set_vlan, }; -int qdev_prop_set_drive(DeviceState *dev, const char *name, - BlockBackend *value) +void qdev_prop_set_drive(DeviceState *dev, const char *name, + BlockBackend *value, Error **errp) { - Error *err = NULL; - object_property_set_str(OBJECT(dev), - value ? blk_name(value) : "", name, &err); - if (err) { - qerror_report_err(err); - error_free(err); - return -1; - } - return 0; + object_property_set_str(OBJECT(dev), value ? blk_name(value) : "", + name, errp); } void qdev_prop_set_drive_nofail(DeviceState *dev, const char *name, BlockBackend *value) { - if (qdev_prop_set_drive(dev, name, value) < 0) { + Error *err = NULL; + + qdev_prop_set_drive(dev, name, value, &err); + if (err) { + error_report_err(err); exit(1); } } + void qdev_prop_set_chr(DeviceState *dev, const char *name, CharDriverState *value) { diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c index 5a4e4d5ec8..570d5f0bad 100644 --- a/hw/core/qdev-properties.c +++ b/hw/core/qdev-properties.c @@ -580,7 +580,8 @@ static void set_blocksize(Object *obj, Visitor *v, void *opaque, error_propagate(errp, local_err); return; } - if (value < min || value > max) { + /* value of 0 means "unset" */ + if (value && (value < min || value > max)) { error_set(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE, dev->id?:"", name, (int64_t)value, min, max); return; diff --git a/hw/core/sysbus.c b/hw/core/sysbus.c index 84af59379d..b53c351aa4 100644 --- a/hw/core/sysbus.c +++ b/hw/core/sysbus.c @@ -91,6 +91,8 @@ bool sysbus_has_irq(SysBusDevice *dev, int n) ObjectProperty *r; r = object_property_find(OBJECT(dev), prop, NULL); + g_free(prop); + return (r != NULL); } diff --git a/hw/dma/pl330.c b/hw/dma/pl330.c index 16cf77e7b2..5be3df521d 100644 --- a/hw/dma/pl330.c +++ b/hw/dma/pl330.c @@ -1566,7 +1566,7 @@ static void pl330_realize(DeviceState *dev, Error **errp) s->cfg[1] |= 5; break; default: - error_setg(errp, "Bad value for i-cache_len property: %" PRIx8 "\n", + error_setg(errp, "Bad value for i-cache_len property: %" PRIx8, s->i_cache_len); return; } @@ -1601,7 +1601,7 @@ static void pl330_realize(DeviceState *dev, Error **errp) s->cfg[CFG_CRD] |= 0x4; break; default: - error_setg(errp, "Bad value for data_width property: %" PRIx8 "\n", + error_setg(errp, "Bad value for data_width property: %" PRIx8, s->data_width); return; } diff --git a/hw/i386/pc.c b/hw/i386/pc.c index 79eaad5fec..b5b2aadb52 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -25,6 +25,8 @@ #include "hw/i386/pc.h" #include "hw/char/serial.h" #include "hw/i386/apic.h" +#include "hw/i386/topology.h" +#include "sysemu/cpus.h" #include "hw/block/fdc.h" #include "hw/ide.h" #include "hw/pci/pci.h" @@ -629,6 +631,39 @@ bool e820_get_entry(int idx, uint32_t type, uint64_t *address, uint64_t *length) return false; } +/* Enables contiguous-apic-ID mode, for compatibility */ +static bool compat_apic_id_mode; + +void enable_compat_apic_id_mode(void) +{ + compat_apic_id_mode = true; +} + +/* Calculates initial APIC ID for a specific CPU index + * + * Currently we need to be able to calculate the APIC ID from the CPU index + * alone (without requiring a CPU object), as the QEMU<->Seabios interfaces have + * no concept of "CPU index", and the NUMA tables on fw_cfg need the APIC ID of + * all CPUs up to max_cpus. + */ +static uint32_t x86_cpu_apic_id_from_index(unsigned int cpu_index) +{ + uint32_t correct_id; + static bool warned; + + correct_id = x86_apicid_from_cpu_idx(smp_cores, smp_threads, cpu_index); + if (compat_apic_id_mode) { + if (cpu_index != correct_id && !warned) { + error_report("APIC IDs set in compatibility mode, " + "CPU topology won't match the configuration"); + warned = true; + } + return cpu_index; + } else { + return correct_id; + } +} + /* Calculates the limit to CPU APIC ID values * * This function returns the limit for the APIC ID value, so that all diff --git a/hw/ide/ahci.c b/hw/ide/ahci.c index 5651372be3..e1ae36f7cd 100644 --- a/hw/ide/ahci.c +++ b/hw/ide/ahci.c @@ -1160,6 +1160,11 @@ static void ahci_start_dma(IDEDMA *dma, IDEState *s, dma_cb(s, 0); } +static void ahci_restart_dma(IDEDMA *dma) +{ + /* Nothing to do, ahci_start_dma already resets s->io_buffer_offset. */ +} + /** * Called in DMA R/W chains to read the PRDT, utilizing ahci_populate_sglist. * Not currently invoked by PIO R/W chains, @@ -1226,12 +1231,6 @@ static int ahci_dma_rw_buf(IDEDMA *dma, int is_write) return 1; } -static int ahci_dma_set_unit(IDEDMA *dma, int unit) -{ - /* only a single unit per link */ - return 0; -} - static void ahci_cmd_done(IDEDMA *dma) { AHCIDevice *ad = DO_UPCAST(AHCIDevice, dma, dma); @@ -1252,19 +1251,14 @@ static void ahci_irq_set(void *opaque, int n, int level) { } -static void ahci_dma_restart_cb(void *opaque, int running, RunState state) -{ -} - static const IDEDMAOps ahci_dma_ops = { .start_dma = ahci_start_dma, + .restart_dma = ahci_restart_dma, .start_transfer = ahci_start_transfer, .prepare_buf = ahci_dma_prepare_buf, .commit_buf = ahci_commit_buf, .rw_buf = ahci_dma_rw_buf, - .set_unit = ahci_dma_set_unit, .cmd_done = ahci_cmd_done, - .restart_cb = ahci_dma_restart_cb, }; void ahci_init(AHCIState *s, DeviceState *qdev, AddressSpace *as, int ports) @@ -1294,6 +1288,7 @@ void ahci_init(AHCIState *s, DeviceState *qdev, AddressSpace *as, int ports) ad->port_no = i; ad->port.dma = &ad->dma; ad->port.dma->ops = &ahci_dma_ops; + ide_register_restart_cb(&ad->port); } } @@ -1333,6 +1328,7 @@ static const VMStateDescription vmstate_ahci_device = { .version_id = 1, .fields = (VMStateField[]) { VMSTATE_IDE_BUS(port, AHCIDevice), + VMSTATE_IDE_DRIVE(port.ifs[0], AHCIDevice), VMSTATE_UINT32(port_state, AHCIDevice), VMSTATE_UINT32(finished, AHCIDevice), VMSTATE_UINT32(port_regs.lst_addr, AHCIDevice), @@ -1371,16 +1367,23 @@ static int ahci_state_post_load(void *opaque, int version_id) map_page(s->as, &ad->res_fis, ((uint64_t)pr->fis_addr_hi << 32) | pr->fis_addr, 256); /* - * All pending i/o should be flushed out on a migrate. However, - * we might not have cleared the busy_slot since this is done - * in a bh. Also, issue i/o against any slots that are pending. + * If an error is present, ad->busy_slot will be valid and not -1. + * In this case, an operation is waiting to resume and will re-check + * for additional AHCI commands to execute upon completion. + * + * In the case where no error was present, busy_slot will be -1, + * and we should check to see if there are additional commands waiting. */ - if ((ad->busy_slot != -1) && - !(ad->port.ifs[0].status & (BUSY_STAT|DRQ_STAT))) { - pr->cmd_issue &= ~(1 << ad->busy_slot); - ad->busy_slot = -1; + if (ad->busy_slot == -1) { + check_cmd(s, i); + } else { + /* We are in the middle of a command, and may need to access + * the command header in guest memory again. */ + if (ad->busy_slot < 0 || ad->busy_slot >= AHCI_MAX_CMDS) { + return -1; + } + ad->cur_cmd = &((AHCICmdHdr *)ad->lst)[ad->busy_slot]; } - check_cmd(s, i); } return 0; diff --git a/hw/ide/atapi.c b/hw/ide/atapi.c index 1bf8b34528..950e311d31 100644 --- a/hw/ide/atapi.c +++ b/hw/ide/atapi.c @@ -252,7 +252,6 @@ static void ide_atapi_cmd_reply(IDEState *s, int size, int max_size) s->packet_transfer_size = size; s->io_buffer_size = size; /* dma: send the reply data as one chunk */ s->elementary_transfer_size = 0; - s->io_buffer_index = 0; if (s->atapi_dma) { block_acct_start(blk_get_stats(s->blk), &s->acct, size, @@ -261,6 +260,7 @@ static void ide_atapi_cmd_reply(IDEState *s, int size, int max_size) ide_start_dma(s, ide_atapi_cmd_read_dma_cb); } else { s->status = READY_STAT | SEEK_STAT; + s->io_buffer_index = 0; ide_atapi_cmd_reply_end(s); } } @@ -368,7 +368,6 @@ static void ide_atapi_cmd_read_dma(IDEState *s, int lba, int nb_sectors, { s->lba = lba; s->packet_transfer_size = nb_sectors * sector_size; - s->io_buffer_index = 0; s->io_buffer_size = 0; s->cd_sector_size = sector_size; diff --git a/hw/ide/cmd646.c b/hw/ide/cmd646.c index dafa9ec7c7..66fb9d96d5 100644 --- a/hw/ide/cmd646.c +++ b/hw/ide/cmd646.c @@ -368,8 +368,7 @@ static void pci_cmd646_ide_realize(PCIDevice *dev, Error **errp) bmdma_init(&d->bus[i], &d->bmdma[i], d); d->bmdma[i].bus = &d->bus[i]; - qemu_add_vm_change_state_handler(d->bus[i].dma->ops->restart_cb, - &d->bmdma[i].dma); + ide_register_restart_cb(&d->bus[i]); } vmstate_register(DEVICE(dev), 0, &vmstate_ide_pci, d); diff --git a/hw/ide/core.c b/hw/ide/core.c index ac3f015a8d..ef52f3516f 100644 --- a/hw/ide/core.c +++ b/hw/ide/core.c @@ -561,6 +561,8 @@ static bool ide_sect_range_ok(IDEState *s, return true; } +static void ide_sector_read(IDEState *s); + static void ide_sector_read_cb(void *opaque, int ret) { IDEState *s = opaque; @@ -595,7 +597,7 @@ static void ide_sector_read_cb(void *opaque, int ret) s->io_buffer_offset += 512 * n; } -void ide_sector_read(IDEState *s) +static void ide_sector_read(IDEState *s) { int64_t sector_num; int n; @@ -646,6 +648,9 @@ static void dma_buf_commit(IDEState *s, uint32_t tx_bytes) void ide_set_inactive(IDEState *s, bool more) { s->bus->dma->aiocb = NULL; + s->bus->retry_unit = -1; + s->bus->retry_sector_num = 0; + s->bus->retry_nsector = 0; if (s->bus->dma->ops->set_inactive) { s->bus->dma->ops->set_inactive(s->bus->dma, more); } @@ -666,7 +671,7 @@ static int ide_handle_rw_error(IDEState *s, int error, int op) BlockErrorAction action = blk_get_error_action(s->blk, is_read, error); if (action == BLOCK_ERROR_ACTION_STOP) { - s->bus->dma->ops->set_unit(s->bus->dma, s->unit); + assert(s->bus->retry_unit == s->unit); s->bus->error_status = op; } else if (action == BLOCK_ERROR_ACTION_REPORT) { if (op & IDE_RETRY_DMA) { @@ -679,7 +684,7 @@ static int ide_handle_rw_error(IDEState *s, int error, int op) return action != BLOCK_ERROR_ACTION_IGNORE; } -void ide_dma_cb(void *opaque, int ret) +static void ide_dma_cb(void *opaque, int ret) { IDEState *s = opaque; int n; @@ -777,7 +782,6 @@ eot: static void ide_sector_start_dma(IDEState *s, enum ide_dma_cmd dma_cmd) { s->status = READY_STAT | SEEK_STAT | DRQ_STAT | BUSY_STAT; - s->io_buffer_index = 0; s->io_buffer_size = 0; s->dma_cmd = dma_cmd; @@ -799,11 +803,17 @@ static void ide_sector_start_dma(IDEState *s, enum ide_dma_cmd dma_cmd) void ide_start_dma(IDEState *s, BlockCompletionFunc *cb) { + s->io_buffer_index = 0; + s->bus->retry_unit = s->unit; + s->bus->retry_sector_num = ide_get_sector(s); + s->bus->retry_nsector = s->nsector; if (s->bus->dma->ops->start_dma) { s->bus->dma->ops->start_dma(s->bus->dma, s, cb); } } +static void ide_sector_write(IDEState *s); + static void ide_sector_write_timer_cb(void *opaque) { IDEState *s = opaque; @@ -863,7 +873,7 @@ static void ide_sector_write_cb(void *opaque, int ret) } } -void ide_sector_write(IDEState *s) +static void ide_sector_write(IDEState *s) { int64_t sector_num; int n; @@ -917,7 +927,7 @@ static void ide_flush_cb(void *opaque, int ret) ide_set_irq(s->bus); } -void ide_flush_cache(IDEState *s) +static void ide_flush_cache(IDEState *s) { if (s->blk == NULL) { ide_flush_cb(s, 0); @@ -2314,22 +2324,101 @@ static int ide_nop_int(IDEDMA *dma, int x) return 0; } -static int32_t ide_nop_int32(IDEDMA *dma, int x) +static void ide_nop(IDEDMA *dma) { - return 0; } -static void ide_nop_restart(void *opaque, int x, RunState y) +static int32_t ide_nop_int32(IDEDMA *dma, int x) { + return 0; } static const IDEDMAOps ide_dma_nop_ops = { .prepare_buf = ide_nop_int32, + .restart_dma = ide_nop, .rw_buf = ide_nop_int, - .set_unit = ide_nop_int, - .restart_cb = ide_nop_restart, }; +static void ide_restart_dma(IDEState *s, enum ide_dma_cmd dma_cmd) +{ + s->unit = s->bus->retry_unit; + ide_set_sector(s, s->bus->retry_sector_num); + s->nsector = s->bus->retry_nsector; + s->bus->dma->ops->restart_dma(s->bus->dma); + s->io_buffer_size = 0; + s->dma_cmd = dma_cmd; + ide_start_dma(s, ide_dma_cb); +} + +static void ide_restart_bh(void *opaque) +{ + IDEBus *bus = opaque; + IDEState *s; + bool is_read; + int error_status; + + qemu_bh_delete(bus->bh); + bus->bh = NULL; + + error_status = bus->error_status; + if (bus->error_status == 0) { + return; + } + + s = idebus_active_if(bus); + is_read = (bus->error_status & IDE_RETRY_READ) != 0; + + /* The error status must be cleared before resubmitting the request: The + * request may fail again, and this case can only be distinguished if the + * called function can set a new error status. */ + bus->error_status = 0; + + if (error_status & IDE_RETRY_DMA) { + if (error_status & IDE_RETRY_TRIM) { + ide_restart_dma(s, IDE_DMA_TRIM); + } else { + ide_restart_dma(s, is_read ? IDE_DMA_READ : IDE_DMA_WRITE); + } + } else if (error_status & IDE_RETRY_PIO) { + if (is_read) { + ide_sector_read(s); + } else { + ide_sector_write(s); + } + } else if (error_status & IDE_RETRY_FLUSH) { + ide_flush_cache(s); + } else { + /* + * We've not got any bits to tell us about ATAPI - but + * we do have the end_transfer_func that tells us what + * we're trying to do. + */ + if (s->end_transfer_func == ide_atapi_cmd) { + ide_atapi_dma_restart(s); + } + } +} + +static void ide_restart_cb(void *opaque, int running, RunState state) +{ + IDEBus *bus = opaque; + + if (!running) + return; + + if (!bus->bh) { + bus->bh = qemu_bh_new(ide_restart_bh, bus); + qemu_bh_schedule(bus->bh); + } +} + +void ide_register_restart_cb(IDEBus *bus) +{ + if (bus->dma->ops->restart_dma) { + qemu_add_vm_change_state_handler(ide_restart_cb, bus); + } +} + static IDEDMA ide_dma_nop = { .ops = &ide_dma_nop_ops, .aiocb = NULL, @@ -2557,10 +2646,13 @@ const VMStateDescription vmstate_ide_drive = { static const VMStateDescription vmstate_ide_error_status = { .name ="ide_bus/error", - .version_id = 1, + .version_id = 2, .minimum_version_id = 1, .fields = (VMStateField[]) { VMSTATE_INT32(error_status, IDEBus), + VMSTATE_INT64_V(retry_sector_num, IDEBus, 2), + VMSTATE_UINT32_V(retry_nsector, IDEBus, 2), + VMSTATE_UINT8_V(retry_unit, IDEBus, 2), VMSTATE_END_OF_LIST() } }; diff --git a/hw/ide/internal.h b/hw/ide/internal.h index ee9a57f039..965cc55cb8 100644 --- a/hw/ide/internal.h +++ b/hw/ide/internal.h @@ -436,10 +436,9 @@ struct IDEDMAOps { DMAInt32Func *prepare_buf; DMAu32Func *commit_buf; DMAIntFunc *rw_buf; - DMAIntFunc *set_unit; + DMAVoidFunc *restart_dma; DMAStopFunc *set_inactive; DMAVoidFunc *cmd_done; - DMARestartFunc *restart_cb; DMAVoidFunc *reset; }; @@ -455,6 +454,8 @@ struct IDEBus { IDEDevice *master; IDEDevice *slave; IDEState ifs[2]; + QEMUBH *bh; + int bus_id; int max_units; IDEDMA *dma; @@ -463,6 +464,9 @@ struct IDEBus { qemu_irq irq; int error_status; + uint8_t retry_unit; + int64_t retry_sector_num; + uint32_t retry_nsector; }; #define TYPE_IDE_DEVICE "ide-device" @@ -522,6 +526,9 @@ extern const VMStateDescription vmstate_ide_drive; #define VMSTATE_IDE_DRIVES(_field, _state) \ VMSTATE_STRUCT_ARRAY(_field, _state, 2, 3, vmstate_ide_drive, IDEState) +#define VMSTATE_IDE_DRIVE(_field, _state) \ + VMSTATE_STRUCT(_field, _state, 1, vmstate_ide_drive, IDEState) + void ide_bus_reset(IDEBus *bus); int64_t ide_get_sector(IDEState *s); void ide_set_sector(IDEState *s, int64_t sector_num); @@ -550,12 +557,9 @@ int ide_init_drive(IDEState *s, BlockBackend *blk, IDEDriveKind kind, int chs_trans); void ide_init2(IDEBus *bus, qemu_irq irq); void ide_init_ioport(IDEBus *bus, ISADevice *isa, int iobase, int iobase2); +void ide_register_restart_cb(IDEBus *bus); void ide_exec_cmd(IDEBus *bus, uint32_t val); -void ide_dma_cb(void *opaque, int ret); -void ide_sector_write(IDEState *s); -void ide_sector_read(IDEState *s); -void ide_flush_cache(IDEState *s); void ide_transfer_start(IDEState *s, uint8_t *buf, int size, EndTransferFunc *end_transfer_func); diff --git a/hw/ide/isa.c b/hw/ide/isa.c index c0c4e1b098..9f80503faa 100644 --- a/hw/ide/isa.c +++ b/hw/ide/isa.c @@ -74,7 +74,8 @@ static void isa_ide_realizefn(DeviceState *dev, Error **errp) isa_init_irq(isadev, &s->irq, s->isairq); ide_init2(&s->bus, s->irq); vmstate_register(dev, 0, &vmstate_ide_isa, s); -}; + ide_register_restart_cb(&s->bus); +} ISADevice *isa_ide_init(ISABus *bus, int iobase, int iobase2, int isairq, DriveInfo *hd0, DriveInfo *hd1) diff --git a/hw/ide/macio.c b/hw/ide/macio.c index f6074f2024..a009674f48 100644 --- a/hw/ide/macio.c +++ b/hw/ide/macio.c @@ -558,10 +558,6 @@ static int32_t ide_nop_int32(IDEDMA *dma, int x) return 0; } -static void ide_nop_restart(void *opaque, int x, RunState y) -{ -} - static void ide_dbdma_start(IDEDMA *dma, IDEState *s, BlockCompletionFunc *cb) { @@ -576,8 +572,6 @@ static const IDEDMAOps dbdma_ops = { .start_dma = ide_dbdma_start, .prepare_buf = ide_nop_int32, .rw_buf = ide_nop_int, - .set_unit = ide_nop_int, - .restart_cb = ide_nop_restart, }; static void macio_ide_realizefn(DeviceState *dev, Error **errp) diff --git a/hw/ide/pci.c b/hw/ide/pci.c index e3f2054a90..1b3d1c12ad 100644 --- a/hw/ide/pci.c +++ b/hw/ide/pci.c @@ -42,13 +42,10 @@ static void bmdma_start_dma(IDEDMA *dma, IDEState *s, { BMDMAState *bm = DO_UPCAST(BMDMAState, dma, dma); - bm->unit = s->unit; bm->dma_cb = dma_cb; bm->cur_prd_last = 0; bm->cur_prd_addr = 0; bm->cur_prd_len = 0; - bm->sector_num = ide_get_sector(s); - bm->nsector = s->nsector; if (bm->status & BM_STATUS_DMAING) { bm->dma_cb(bmdma_active_if(bm), 0); @@ -99,7 +96,7 @@ static int32_t bmdma_prepare_buf(IDEDMA *dma, int is_write) * This should accommodate the largest ATA transaction * for LBA48 (65,536 sectors) and 32K sector sizes. */ if (s->sg.size > INT32_MAX) { - error_report("IDE: sglist describes more than 2GiB.\n"); + error_report("IDE: sglist describes more than 2GiB."); break; } bm->cur_prd_addr += l; @@ -163,20 +160,11 @@ static int bmdma_rw_buf(IDEDMA *dma, int is_write) return 1; } -static int bmdma_set_unit(IDEDMA *dma, int unit) -{ - BMDMAState *bm = DO_UPCAST(BMDMAState, dma, dma); - bm->unit = unit; - - return 0; -} - static void bmdma_set_inactive(IDEDMA *dma, bool more) { BMDMAState *bm = DO_UPCAST(BMDMAState, dma, dma); bm->dma_cb = NULL; - bm->unit = -1; if (more) { bm->status |= BM_STATUS_DMAING; } else { @@ -184,83 +172,11 @@ static void bmdma_set_inactive(IDEDMA *dma, bool more) } } -static void bmdma_restart_dma(BMDMAState *bm, enum ide_dma_cmd dma_cmd) -{ - IDEState *s = bmdma_active_if(bm); - - ide_set_sector(s, bm->sector_num); - s->io_buffer_index = 0; - s->io_buffer_size = 0; - s->nsector = bm->nsector; - s->dma_cmd = dma_cmd; - bm->cur_addr = bm->addr; - bm->dma_cb = ide_dma_cb; - bmdma_start_dma(&bm->dma, s, bm->dma_cb); -} - -/* TODO This should be common IDE code */ -static void bmdma_restart_bh(void *opaque) -{ - BMDMAState *bm = opaque; - IDEBus *bus = bm->bus; - bool is_read; - int error_status; - - qemu_bh_delete(bm->bh); - bm->bh = NULL; - - if (bm->unit == (uint8_t) -1) { - return; - } - - is_read = (bus->error_status & IDE_RETRY_READ) != 0; - - /* The error status must be cleared before resubmitting the request: The - * request may fail again, and this case can only be distinguished if the - * called function can set a new error status. */ - error_status = bus->error_status; - bus->error_status = 0; - - if (error_status & IDE_RETRY_DMA) { - if (error_status & IDE_RETRY_TRIM) { - bmdma_restart_dma(bm, IDE_DMA_TRIM); - } else { - bmdma_restart_dma(bm, is_read ? IDE_DMA_READ : IDE_DMA_WRITE); - } - } else if (error_status & IDE_RETRY_PIO) { - if (is_read) { - ide_sector_read(bmdma_active_if(bm)); - } else { - ide_sector_write(bmdma_active_if(bm)); - } - } else if (error_status & IDE_RETRY_FLUSH) { - ide_flush_cache(bmdma_active_if(bm)); - } else { - IDEState *s = bmdma_active_if(bm); - - /* - * We've not got any bits to tell us about ATAPI - but - * we do have the end_transfer_func that tells us what - * we're trying to do. - */ - if (s->end_transfer_func == ide_atapi_cmd) { - ide_atapi_dma_restart(s); - } - } -} - -static void bmdma_restart_cb(void *opaque, int running, RunState state) +static void bmdma_restart_dma(IDEDMA *dma) { - IDEDMA *dma = opaque; BMDMAState *bm = DO_UPCAST(BMDMAState, dma, dma); - if (!running) - return; - - if (!bm->bh) { - bm->bh = qemu_bh_new(bmdma_restart_bh, &bm->dma); - qemu_bh_schedule(bm->bh); - } + bm->cur_addr = bm->addr; } static void bmdma_cancel(BMDMAState *bm) @@ -286,8 +202,6 @@ static void bmdma_reset(IDEDMA *dma) bm->cur_prd_last = 0; bm->cur_prd_addr = 0; bm->cur_prd_len = 0; - bm->sector_num = 0; - bm->nsector = 0; } static void bmdma_irq(void *opaque, int n, int level) @@ -404,6 +318,9 @@ static void ide_bmdma_pre_save(void *opaque) BMDMAState *bm = opaque; uint8_t abused_bits = BM_MIGRATION_COMPAT_STATUS_BITS; + bm->migration_retry_unit = bm->bus->retry_unit; + bm->migration_retry_sector_num = bm->bus->retry_sector_num; + bm->migration_retry_nsector = bm->bus->retry_nsector; bm->migration_compat_status = (bm->status & ~abused_bits) | (bm->bus->error_status & abused_bits); } @@ -420,6 +337,11 @@ static int ide_bmdma_post_load(void *opaque, int version_id) bm->status = bm->migration_compat_status & ~abused_bits; bm->bus->error_status |= bm->migration_compat_status & abused_bits; } + if (bm->bus->error_status) { + bm->bus->retry_sector_num = bm->migration_retry_sector_num; + bm->bus->retry_nsector = bm->migration_retry_nsector; + bm->bus->retry_unit = bm->migration_retry_unit; + } return 0; } @@ -456,9 +378,9 @@ static const VMStateDescription vmstate_bmdma = { VMSTATE_UINT8(cmd, BMDMAState), VMSTATE_UINT8(migration_compat_status, BMDMAState), VMSTATE_UINT32(addr, BMDMAState), - VMSTATE_INT64(sector_num, BMDMAState), - VMSTATE_UINT32(nsector, BMDMAState), - VMSTATE_UINT8(unit, BMDMAState), + VMSTATE_INT64(migration_retry_sector_num, BMDMAState), + VMSTATE_UINT32(migration_retry_nsector, BMDMAState), + VMSTATE_UINT8(migration_retry_unit, BMDMAState), VMSTATE_END_OF_LIST() }, .subsections = (VMStateSubsection []) { @@ -482,7 +404,7 @@ static int ide_pci_post_load(void *opaque, int version_id) for(i = 0; i < 2; i++) { /* current versions always store 0/1, but older version stored bigger values. We only need last bit */ - d->bmdma[i].unit &= 1; + d->bmdma[i].migration_retry_unit &= 1; ide_bmdma_post_load(&d->bmdma[i], -1); } @@ -523,9 +445,8 @@ static const struct IDEDMAOps bmdma_ops = { .start_dma = bmdma_start_dma, .prepare_buf = bmdma_prepare_buf, .rw_buf = bmdma_rw_buf, - .set_unit = bmdma_set_unit, + .restart_dma = bmdma_restart_dma, .set_inactive = bmdma_set_inactive, - .restart_cb = bmdma_restart_cb, .reset = bmdma_reset, }; diff --git a/hw/ide/pci.h b/hw/ide/pci.h index 2e9314ad87..0f2d4b91a7 100644 --- a/hw/ide/pci.h +++ b/hw/ide/pci.h @@ -22,18 +22,18 @@ typedef struct BMDMAState { uint32_t cur_prd_last; uint32_t cur_prd_addr; uint32_t cur_prd_len; - uint8_t unit; BlockCompletionFunc *dma_cb; - int64_t sector_num; - uint32_t nsector; MemoryRegion addr_ioport; MemoryRegion extra_io; - QEMUBH *bh; qemu_irq irq; /* Bit 0-2 and 7: BM status register * Bit 3-6: bus->error_status */ uint8_t migration_compat_status; + uint8_t migration_retry_unit; + int64_t migration_retry_sector_num; + uint32_t migration_retry_nsector; + struct PCIIDEState *pci_dev; } BMDMAState; @@ -62,8 +62,8 @@ typedef struct PCIIDEState { static inline IDEState *bmdma_active_if(BMDMAState *bmdma) { - assert(bmdma->unit != (uint8_t)-1); - return bmdma->bus->ifs + bmdma->unit; + assert(bmdma->bus->retry_unit != (uint8_t)-1); + return bmdma->bus->ifs + bmdma->bus->retry_unit; } diff --git a/hw/ide/piix.c b/hw/ide/piix.c index ab930843e8..adb664957c 100644 --- a/hw/ide/piix.c +++ b/hw/ide/piix.c @@ -143,8 +143,7 @@ static void pci_piix_init_ports(PCIIDEState *d) { bmdma_init(&d->bus[i], &d->bmdma[i], d); d->bmdma[i].bus = &d->bus[i]; - qemu_add_vm_change_state_handler(d->bus[i].dma->ops->restart_cb, - &d->bmdma[i].dma); + ide_register_restart_cb(&d->bus[i]); } } diff --git a/hw/ide/qdev.c b/hw/ide/qdev.c index b4103fa009..788b36133c 100644 --- a/hw/ide/qdev.c +++ b/hw/ide/qdev.c @@ -163,6 +163,7 @@ static int ide_dev_initfn(IDEDevice *dev, IDEDriveKind kind) return -1; } + blkconf_blocksizes(&dev->conf); if (dev->conf.logical_block_size != 512) { error_report("logical_block_size must be 512 for IDE"); return -1; diff --git a/hw/ide/via.c b/hw/ide/via.c index 7a5151c5c1..e2da9ef71a 100644 --- a/hw/ide/via.c +++ b/hw/ide/via.c @@ -166,8 +166,7 @@ static void vt82c686b_init_ports(PCIIDEState *d) { bmdma_init(&d->bus[i], &d->bmdma[i], d); d->bmdma[i].bus = &d->bus[i]; - qemu_add_vm_change_state_handler(d->bus[i].dma->ops->restart_cb, - &d->bmdma[i].dma); + ide_register_restart_cb(&d->bus[i]); } } diff --git a/hw/lm32/milkymist.c b/hw/lm32/milkymist.c index 256c1029ce..7f622610d2 100644 --- a/hw/lm32/milkymist.c +++ b/hw/lm32/milkymist.c @@ -155,6 +155,7 @@ milkymist_init(MachineState *machine) bios_name); exit(1); } + g_free(bios_filename); milkymist_uart_create(0x60000000, irq[0]); milkymist_sysctl_create(0x60001000, irq[1], irq[2], irq[3], diff --git a/hw/m68k/dummy_m68k.c b/hw/m68k/dummy_m68k.c index facd561efa..278f4c03d3 100644 --- a/hw/m68k/dummy_m68k.c +++ b/hw/m68k/dummy_m68k.c @@ -21,6 +21,7 @@ static void dummy_m68k_init(MachineState *machine) ram_addr_t ram_size = machine->ram_size; const char *cpu_model = machine->cpu_model; const char *kernel_filename = machine->kernel_filename; + M68kCPU *cpu; CPUM68KState *env; MemoryRegion *address_space_mem = get_system_memory(); MemoryRegion *ram = g_new(MemoryRegion, 1); @@ -30,11 +31,12 @@ static void dummy_m68k_init(MachineState *machine) if (!cpu_model) cpu_model = "cfv4e"; - env = cpu_init(cpu_model); - if (!env) { + cpu = cpu_m68k_init(cpu_model); + if (!cpu) { fprintf(stderr, "Unable to find m68k CPU definition\n"); exit(1); } + env = &cpu->env; /* Initialize CPU registers. */ env->vbr = 0; diff --git a/hw/microblaze/boot.c b/hw/microblaze/boot.c index a2843cdf99..38c59dbe9d 100644 --- a/hw/microblaze/boot.c +++ b/hw/microblaze/boot.c @@ -185,7 +185,7 @@ void microblaze_load_kernel(MicroBlazeCPU *cpu, hwaddr ddr_base, ram_size - initrd_offset); } if (initrd_size < 0) { - error_report("qemu: could not load initrd '%s'\n", + error_report("qemu: could not load initrd '%s'", initrd_filename); exit(EXIT_FAILURE); } diff --git a/hw/misc/macio/macio.c b/hw/misc/macio/macio.c index 9bc3f2d908..063ad80412 100644 --- a/hw/misc/macio/macio.c +++ b/hw/misc/macio/macio.c @@ -273,7 +273,7 @@ static int macio_newworld_initfn(PCIDevice *d) MacIOState *s = MACIO(d); NewWorldMacIOState *ns = NEWWORLD_MACIO(d); SysBusDevice *sysbus_dev; - MemoryRegion *timer_memory = g_new(MemoryRegion, 1); + MemoryRegion *timer_memory = NULL; int i; int cur_irq = 0; int ret = macio_common_initfn(d); @@ -301,6 +301,7 @@ static int macio_newworld_initfn(PCIDevice *d) } /* Timer */ + timer_memory = g_new(MemoryRegion, 1); memory_region_init_io(timer_memory, OBJECT(s), &timer_ops, NULL, "timer", 0x1000); memory_region_add_subregion(&s->bar, 0x15000, timer_memory); diff --git a/hw/misc/milkymist-pfpu.c b/hw/misc/milkymist-pfpu.c index 609f33f9cd..08b604f13f 100644 --- a/hw/misc/milkymist-pfpu.c +++ b/hw/misc/milkymist-pfpu.c @@ -362,7 +362,7 @@ static void pfpu_start(MilkymistPFPUState *s) i = 0; while (pfpu_decode_insn(s)) { /* decode at most MICROCODE_WORDS instructions */ - if (i++ >= MICROCODE_WORDS) { + if (++i >= MICROCODE_WORDS) { error_report("milkymist_pfpu: too many instructions " "executed in microcode. No VECTOUT?"); break; diff --git a/hw/net/vhost_net.c b/hw/net/vhost_net.c index 2ea1ef1dd0..cf23335ba2 100644 --- a/hw/net/vhost_net.c +++ b/hw/net/vhost_net.c @@ -56,7 +56,7 @@ static const int kernel_feature_bits[] = { }; /* Features supported by others. */ -const int user_feature_bits[] = { +static const int user_feature_bits[] = { VIRTIO_F_NOTIFY_ON_EMPTY, VIRTIO_RING_F_INDIRECT_DESC, VIRTIO_RING_F_EVENT_IDX, diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c index 1187ab813b..27adcc5467 100644 --- a/hw/net/virtio-net.c +++ b/hw/net/virtio-net.c @@ -120,8 +120,8 @@ static void virtio_net_vhost_status(VirtIONet *n, uint8_t status) return; } - if (!!n->vhost_started == - (virtio_net_started(n, status) && !nc->peer->link_down)) { + if ((virtio_net_started(n, status) && !nc->peer->link_down) == + !!n->vhost_started) { return; } if (!n->vhost_started) { diff --git a/hw/net/xilinx_ethlite.c b/hw/net/xilinx_ethlite.c index 9536f64584..ad6b55306d 100644 --- a/hw/net/xilinx_ethlite.c +++ b/hw/net/xilinx_ethlite.c @@ -146,6 +146,7 @@ eth_write(void *opaque, hwaddr addr, if (!(value & CTRL_S)) { qemu_flush_queued_packets(qemu_get_queue(s->nic)); } + /* fall through */ case R_TX_LEN0: case R_TX_LEN1: case R_TX_GIE0: diff --git a/hw/ppc/e500.c b/hw/ppc/e500.c index fd0d138a1b..d51fb60f79 100644 --- a/hw/ppc/e500.c +++ b/hw/ppc/e500.c @@ -308,6 +308,7 @@ static int ppce500_load_device_tree(MachineState *machine, } fdt = load_device_tree(filename, &fdt_size); + g_free(filename); if (!fdt) { goto out; } diff --git a/hw/ppc/ppc.c b/hw/ppc/ppc.c index 5ce565d5ec..99db56c8d0 100644 --- a/hw/ppc/ppc.c +++ b/hw/ppc/ppc.c @@ -1318,167 +1318,6 @@ void PPC_debug_write (void *opaque, uint32_t addr, uint32_t val) } } -/*****************************************************************************/ -/* NVRAM helpers */ -static inline uint32_t nvram_read (nvram_t *nvram, uint32_t addr) -{ - return (*nvram->read_fn)(nvram->opaque, addr); -} - -static inline void nvram_write (nvram_t *nvram, uint32_t addr, uint32_t val) -{ - (*nvram->write_fn)(nvram->opaque, addr, val); -} - -static void NVRAM_set_byte(nvram_t *nvram, uint32_t addr, uint8_t value) -{ - nvram_write(nvram, addr, value); -} - -static uint8_t NVRAM_get_byte(nvram_t *nvram, uint32_t addr) -{ - return nvram_read(nvram, addr); -} - -static void NVRAM_set_word(nvram_t *nvram, uint32_t addr, uint16_t value) -{ - nvram_write(nvram, addr, value >> 8); - nvram_write(nvram, addr + 1, value & 0xFF); -} - -static uint16_t NVRAM_get_word(nvram_t *nvram, uint32_t addr) -{ - uint16_t tmp; - - tmp = nvram_read(nvram, addr) << 8; - tmp |= nvram_read(nvram, addr + 1); - - return tmp; -} - -static void NVRAM_set_lword(nvram_t *nvram, uint32_t addr, uint32_t value) -{ - nvram_write(nvram, addr, value >> 24); - nvram_write(nvram, addr + 1, (value >> 16) & 0xFF); - nvram_write(nvram, addr + 2, (value >> 8) & 0xFF); - nvram_write(nvram, addr + 3, value & 0xFF); -} - -uint32_t NVRAM_get_lword (nvram_t *nvram, uint32_t addr) -{ - uint32_t tmp; - - tmp = nvram_read(nvram, addr) << 24; - tmp |= nvram_read(nvram, addr + 1) << 16; - tmp |= nvram_read(nvram, addr + 2) << 8; - tmp |= nvram_read(nvram, addr + 3); - - return tmp; -} - -static void NVRAM_set_string(nvram_t *nvram, uint32_t addr, const char *str, - uint32_t max) -{ - int i; - - for (i = 0; i < max && str[i] != '\0'; i++) { - nvram_write(nvram, addr + i, str[i]); - } - nvram_write(nvram, addr + i, str[i]); - nvram_write(nvram, addr + max - 1, '\0'); -} - -int NVRAM_get_string (nvram_t *nvram, uint8_t *dst, uint16_t addr, int max) -{ - int i; - - memset(dst, 0, max); - for (i = 0; i < max; i++) { - dst[i] = NVRAM_get_byte(nvram, addr + i); - if (dst[i] == '\0') - break; - } - - return i; -} - -static uint16_t NVRAM_crc_update (uint16_t prev, uint16_t value) -{ - uint16_t tmp; - uint16_t pd, pd1, pd2; - - tmp = prev >> 8; - pd = prev ^ value; - pd1 = pd & 0x000F; - pd2 = ((pd >> 4) & 0x000F) ^ pd1; - tmp ^= (pd1 << 3) | (pd1 << 8); - tmp ^= pd2 | (pd2 << 7) | (pd2 << 12); - - return tmp; -} - -static uint16_t NVRAM_compute_crc (nvram_t *nvram, uint32_t start, uint32_t count) -{ - uint32_t i; - uint16_t crc = 0xFFFF; - int odd; - - odd = count & 1; - count &= ~1; - for (i = 0; i != count; i++) { - crc = NVRAM_crc_update(crc, NVRAM_get_word(nvram, start + i)); - } - if (odd) { - crc = NVRAM_crc_update(crc, NVRAM_get_byte(nvram, start + i) << 8); - } - - return crc; -} - -#define CMDLINE_ADDR 0x017ff000 - -int PPC_NVRAM_set_params (nvram_t *nvram, uint16_t NVRAM_size, - const char *arch, - uint32_t RAM_size, int boot_device, - uint32_t kernel_image, uint32_t kernel_size, - const char *cmdline, - uint32_t initrd_image, uint32_t initrd_size, - uint32_t NVRAM_image, - int width, int height, int depth) -{ - uint16_t crc; - - /* Set parameters for Open Hack'Ware BIOS */ - NVRAM_set_string(nvram, 0x00, "QEMU_BIOS", 16); - NVRAM_set_lword(nvram, 0x10, 0x00000002); /* structure v2 */ - NVRAM_set_word(nvram, 0x14, NVRAM_size); - NVRAM_set_string(nvram, 0x20, arch, 16); - NVRAM_set_lword(nvram, 0x30, RAM_size); - NVRAM_set_byte(nvram, 0x34, boot_device); - NVRAM_set_lword(nvram, 0x38, kernel_image); - NVRAM_set_lword(nvram, 0x3C, kernel_size); - if (cmdline) { - /* XXX: put the cmdline in NVRAM too ? */ - pstrcpy_targphys("cmdline", CMDLINE_ADDR, RAM_size - CMDLINE_ADDR, cmdline); - NVRAM_set_lword(nvram, 0x40, CMDLINE_ADDR); - NVRAM_set_lword(nvram, 0x44, strlen(cmdline)); - } else { - NVRAM_set_lword(nvram, 0x40, 0); - NVRAM_set_lword(nvram, 0x44, 0); - } - NVRAM_set_lword(nvram, 0x48, initrd_image); - NVRAM_set_lword(nvram, 0x4C, initrd_size); - NVRAM_set_lword(nvram, 0x50, NVRAM_image); - - NVRAM_set_word(nvram, 0x54, width); - NVRAM_set_word(nvram, 0x56, height); - NVRAM_set_word(nvram, 0x58, depth); - crc = NVRAM_compute_crc(nvram, 0x00, 0xF8); - NVRAM_set_word(nvram, 0xFC, crc); - - return 0; -} - /* CPU device-tree ID helpers */ int ppc_get_vcpu_dt_id(PowerPCCPU *cpu) { diff --git a/hw/ppc/ppc405_boards.c b/hw/ppc/ppc405_boards.c index 1dcea7730e..ec6c4cbaf1 100644 --- a/hw/ppc/ppc405_boards.c +++ b/hw/ppc/ppc405_boards.c @@ -283,7 +283,7 @@ static void ref405ep_init(MachineState *machine) #ifdef DEBUG_BOARD_INIT printf("%s: register NVRAM\n", __func__); #endif - m48t59_init(NULL, 0xF0000000, 0, 8192, 8); + m48t59_init(NULL, 0xF0000000, 0, 8192, 1968, 8); /* Load kernel */ linux_boot = (kernel_filename != NULL); if (linux_boot) { diff --git a/hw/ppc/prep.c b/hw/ppc/prep.c index 15df7f3dae..7f52662d76 100644 --- a/hw/ppc/prep.c +++ b/hw/ppc/prep.c @@ -181,7 +181,7 @@ static const MemoryRegionOps PPC_XCSR_ops = { /* Fake super-io ports for PREP platform (Intel 82378ZB) */ typedef struct sysctrl_t { qemu_irq reset_irq; - M48t59State *nvram; + Nvram *nvram; uint8_t state; uint8_t syscontrol; int contiguous_map; @@ -235,13 +235,17 @@ static void PREP_io_800_writeb (void *opaque, uint32_t addr, uint32_t val) break; case 0x0810: /* Password protect 1 register */ - if (sysctrl->nvram != NULL) - m48t59_toggle_lock(sysctrl->nvram, 1); + if (sysctrl->nvram != NULL) { + NvramClass *k = NVRAM_GET_CLASS(sysctrl->nvram); + (k->toggle_lock)(sysctrl->nvram, 1); + } break; case 0x0812: /* Password protect 2 register */ - if (sysctrl->nvram != NULL) - m48t59_toggle_lock(sysctrl->nvram, 2); + if (sysctrl->nvram != NULL) { + NvramClass *k = NVRAM_GET_CLASS(sysctrl->nvram); + (k->toggle_lock)(sysctrl->nvram, 2); + } break; case 0x0814: /* L2 invalidate register */ @@ -360,6 +364,144 @@ static const MemoryRegionPortio prep_portio_list[] = { static PortioList prep_port_list; +/*****************************************************************************/ +/* NVRAM helpers */ +static inline uint32_t nvram_read(Nvram *nvram, uint32_t addr) +{ + NvramClass *k = NVRAM_GET_CLASS(sysctrl->nvram); + return (k->read)(nvram, addr); +} + +static inline void nvram_write(Nvram *nvram, uint32_t addr, uint32_t val) +{ + NvramClass *k = NVRAM_GET_CLASS(sysctrl->nvram); + (k->write)(nvram, addr, val); +} + +static void NVRAM_set_byte(Nvram *nvram, uint32_t addr, uint8_t value) +{ + nvram_write(nvram, addr, value); +} + +static uint8_t NVRAM_get_byte(Nvram *nvram, uint32_t addr) +{ + return nvram_read(nvram, addr); +} + +static void NVRAM_set_word(Nvram *nvram, uint32_t addr, uint16_t value) +{ + nvram_write(nvram, addr, value >> 8); + nvram_write(nvram, addr + 1, value & 0xFF); +} + +static uint16_t NVRAM_get_word(Nvram *nvram, uint32_t addr) +{ + uint16_t tmp; + + tmp = nvram_read(nvram, addr) << 8; + tmp |= nvram_read(nvram, addr + 1); + + return tmp; +} + +static void NVRAM_set_lword(Nvram *nvram, uint32_t addr, uint32_t value) +{ + nvram_write(nvram, addr, value >> 24); + nvram_write(nvram, addr + 1, (value >> 16) & 0xFF); + nvram_write(nvram, addr + 2, (value >> 8) & 0xFF); + nvram_write(nvram, addr + 3, value & 0xFF); +} + +static void NVRAM_set_string(Nvram *nvram, uint32_t addr, const char *str, + uint32_t max) +{ + int i; + + for (i = 0; i < max && str[i] != '\0'; i++) { + nvram_write(nvram, addr + i, str[i]); + } + nvram_write(nvram, addr + i, str[i]); + nvram_write(nvram, addr + max - 1, '\0'); +} + +static uint16_t NVRAM_crc_update (uint16_t prev, uint16_t value) +{ + uint16_t tmp; + uint16_t pd, pd1, pd2; + + tmp = prev >> 8; + pd = prev ^ value; + pd1 = pd & 0x000F; + pd2 = ((pd >> 4) & 0x000F) ^ pd1; + tmp ^= (pd1 << 3) | (pd1 << 8); + tmp ^= pd2 | (pd2 << 7) | (pd2 << 12); + + return tmp; +} + +static uint16_t NVRAM_compute_crc (Nvram *nvram, uint32_t start, uint32_t count) +{ + uint32_t i; + uint16_t crc = 0xFFFF; + int odd; + + odd = count & 1; + count &= ~1; + for (i = 0; i != count; i++) { + crc = NVRAM_crc_update(crc, NVRAM_get_word(nvram, start + i)); + } + if (odd) { + crc = NVRAM_crc_update(crc, NVRAM_get_byte(nvram, start + i) << 8); + } + + return crc; +} + +#define CMDLINE_ADDR 0x017ff000 + +static int PPC_NVRAM_set_params (Nvram *nvram, uint16_t NVRAM_size, + const char *arch, + uint32_t RAM_size, int boot_device, + uint32_t kernel_image, uint32_t kernel_size, + const char *cmdline, + uint32_t initrd_image, uint32_t initrd_size, + uint32_t NVRAM_image, + int width, int height, int depth) +{ + uint16_t crc; + + /* Set parameters for Open Hack'Ware BIOS */ + NVRAM_set_string(nvram, 0x00, "QEMU_BIOS", 16); + NVRAM_set_lword(nvram, 0x10, 0x00000002); /* structure v2 */ + NVRAM_set_word(nvram, 0x14, NVRAM_size); + NVRAM_set_string(nvram, 0x20, arch, 16); + NVRAM_set_lword(nvram, 0x30, RAM_size); + NVRAM_set_byte(nvram, 0x34, boot_device); + NVRAM_set_lword(nvram, 0x38, kernel_image); + NVRAM_set_lword(nvram, 0x3C, kernel_size); + if (cmdline) { + /* XXX: put the cmdline in NVRAM too ? */ + pstrcpy_targphys("cmdline", CMDLINE_ADDR, RAM_size - CMDLINE_ADDR, + cmdline); + NVRAM_set_lword(nvram, 0x40, CMDLINE_ADDR); + NVRAM_set_lword(nvram, 0x44, strlen(cmdline)); + } else { + NVRAM_set_lword(nvram, 0x40, 0); + NVRAM_set_lword(nvram, 0x44, 0); + } + NVRAM_set_lword(nvram, 0x48, initrd_image); + NVRAM_set_lword(nvram, 0x4C, initrd_size); + NVRAM_set_lword(nvram, 0x50, NVRAM_image); + + NVRAM_set_word(nvram, 0x54, width); + NVRAM_set_word(nvram, 0x56, height); + NVRAM_set_word(nvram, 0x58, depth); + crc = NVRAM_compute_crc(nvram, 0x00, 0xF8); + NVRAM_set_word(nvram, 0xFC, crc); + + return 0; +} + /* PowerPC PREP hardware initialisation */ static void ppc_prep_init(MachineState *machine) { @@ -372,8 +514,7 @@ static void ppc_prep_init(MachineState *machine) MemoryRegion *sysmem = get_system_memory(); PowerPCCPU *cpu = NULL; CPUPPCState *env = NULL; - nvram_t nvram; - M48t59State *m48t59; + Nvram *m48t59; #if 0 MemoryRegion *xcsr = g_new(MemoryRegion, 1); #endif @@ -543,16 +684,14 @@ static void ppc_prep_init(MachineState *machine) pci_create_simple(pci_bus, -1, "pci-ohci"); } - m48t59 = m48t59_init_isa(isa_bus, 0x0074, NVRAM_SIZE, 59); + m48t59 = m48t59_init_isa(isa_bus, 0x0074, NVRAM_SIZE, 2000, 59); if (m48t59 == NULL) return; sysctrl->nvram = m48t59; /* Initialise NVRAM */ - nvram.opaque = m48t59; - nvram.read_fn = &m48t59_read; - nvram.write_fn = &m48t59_write; - PPC_NVRAM_set_params(&nvram, NVRAM_SIZE, "PREP", ram_size, ppc_boot_device, + PPC_NVRAM_set_params(m48t59, NVRAM_SIZE, "PREP", ram_size, + ppc_boot_device, kernel_base, kernel_size, kernel_cmdline, initrd_base, initrd_size, diff --git a/hw/scsi/esp-pci.c b/hw/scsi/esp-pci.c index 00b7297354..8d2242d0a4 100644 --- a/hw/scsi/esp-pci.c +++ b/hw/scsi/esp-pci.c @@ -342,13 +342,12 @@ static const struct SCSIBusInfo esp_pci_scsi_info = { .cancel = esp_request_cancelled, }; -static int esp_pci_scsi_init(PCIDevice *dev) +static void esp_pci_scsi_realize(PCIDevice *dev, Error **errp) { PCIESPState *pci = PCI_ESP(dev); DeviceState *d = DEVICE(dev); ESPState *s = &pci->esp; uint8_t *pci_conf; - Error *err = NULL; pci_conf = dev->config; @@ -367,13 +366,8 @@ static int esp_pci_scsi_init(PCIDevice *dev) scsi_bus_new(&s->bus, sizeof(s->bus), d, &esp_pci_scsi_info, NULL); if (!d->hotplugged) { - scsi_bus_legacy_handle_cmdline(&s->bus, &err); - if (err != NULL) { - error_free(err); - return -1; - } + scsi_bus_legacy_handle_cmdline(&s->bus, errp); } - return 0; } static void esp_pci_scsi_uninit(PCIDevice *d) @@ -388,7 +382,7 @@ static void esp_pci_class_init(ObjectClass *klass, void *data) DeviceClass *dc = DEVICE_CLASS(klass); PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); - k->init = esp_pci_scsi_init; + k->realize = esp_pci_scsi_realize; k->exit = esp_pci_scsi_uninit; k->vendor_id = PCI_VENDOR_ID_AMD; k->device_id = PCI_DEVICE_ID_AMD_SCSI; @@ -466,17 +460,19 @@ static void dc390_write_config(PCIDevice *dev, } } -static int dc390_scsi_init(PCIDevice *dev) +static void dc390_scsi_realize(PCIDevice *dev, Error **errp) { DC390State *pci = DC390(dev); + Error *err = NULL; uint8_t *contents; uint16_t chksum = 0; - int i, ret; + int i; /* init base class */ - ret = esp_pci_scsi_init(dev); - if (ret < 0) { - return ret; + esp_pci_scsi_realize(dev, &err); + if (err) { + error_propagate(errp, err); + return; } /* EEPROM */ @@ -503,8 +499,6 @@ static int dc390_scsi_init(PCIDevice *dev) chksum = 0x1234 - chksum; contents[EE_CHKSUM1] = chksum & 0xff; contents[EE_CHKSUM2] = chksum >> 8; - - return 0; } static void dc390_class_init(ObjectClass *klass, void *data) @@ -512,7 +506,7 @@ static void dc390_class_init(ObjectClass *klass, void *data) DeviceClass *dc = DEVICE_CLASS(klass); PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); - k->init = dc390_scsi_init; + k->realize = dc390_scsi_realize; k->config_read = dc390_read_config; k->config_write = dc390_write_config; set_bit(DEVICE_CATEGORY_STORAGE, dc->categories); diff --git a/hw/scsi/lsi53c895a.c b/hw/scsi/lsi53c895a.c index db7d4b8c9c..c5b0cc5caf 100644 --- a/hw/scsi/lsi53c895a.c +++ b/hw/scsi/lsi53c895a.c @@ -19,7 +19,6 @@ #include "hw/pci/pci.h" #include "hw/scsi/scsi.h" #include "sysemu/dma.h" -#include "qemu/error-report.h" //#define DEBUG_LSI //#define DEBUG_LSI_REG @@ -2089,12 +2088,11 @@ static const struct SCSIBusInfo lsi_scsi_info = { .cancel = lsi_request_cancelled }; -static int lsi_scsi_init(PCIDevice *dev) +static void lsi_scsi_realize(PCIDevice *dev, Error **errp) { LSIState *s = LSI53C895A(dev); DeviceState *d = DEVICE(dev); uint8_t *pci_conf; - Error *err = NULL; pci_conf = dev->config; @@ -2117,13 +2115,8 @@ static int lsi_scsi_init(PCIDevice *dev) scsi_bus_new(&s->bus, sizeof(s->bus), d, &lsi_scsi_info, NULL); if (!d->hotplugged) { - scsi_bus_legacy_handle_cmdline(&s->bus, &err); - if (err != NULL) { - error_free(err); - return -1; - } + scsi_bus_legacy_handle_cmdline(&s->bus, errp); } - return 0; } static void lsi_class_init(ObjectClass *klass, void *data) @@ -2131,7 +2124,7 @@ static void lsi_class_init(ObjectClass *klass, void *data) DeviceClass *dc = DEVICE_CLASS(klass); PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); - k->init = lsi_scsi_init; + k->realize = lsi_scsi_realize; k->vendor_id = PCI_VENDOR_ID_LSI_LOGIC; k->device_id = PCI_DEVICE_ID_LSI_53C895A; k->class_id = PCI_CLASS_STORAGE_SCSI; diff --git a/hw/scsi/megasas.c b/hw/scsi/megasas.c index 4852237a79..bf83b65383 100644 --- a/hw/scsi/megasas.c +++ b/hw/scsi/megasas.c @@ -2320,14 +2320,13 @@ static const struct SCSIBusInfo megasas_scsi_info = { .cancel = megasas_command_cancel, }; -static int megasas_scsi_init(PCIDevice *dev) +static void megasas_scsi_realize(PCIDevice *dev, Error **errp) { DeviceState *d = DEVICE(dev); MegasasState *s = MEGASAS(dev); MegasasBaseClass *b = MEGASAS_DEVICE_GET_CLASS(s); uint8_t *pci_conf; int i, bar_type; - Error *err = NULL; pci_conf = dev->config; @@ -2407,13 +2406,8 @@ static int megasas_scsi_init(PCIDevice *dev) scsi_bus_new(&s->bus, sizeof(s->bus), DEVICE(dev), &megasas_scsi_info, NULL); if (!d->hotplugged) { - scsi_bus_legacy_handle_cmdline(&s->bus, &err); - if (err != NULL) { - error_free(err); - return -1; - } + scsi_bus_legacy_handle_cmdline(&s->bus, errp); } - return 0; } static void @@ -2507,7 +2501,7 @@ static void megasas_class_init(ObjectClass *oc, void *data) MegasasBaseClass *e = MEGASAS_DEVICE_CLASS(oc); const MegasasInfo *info = data; - pc->init = megasas_scsi_init; + pc->realize = megasas_scsi_realize; pc->exit = megasas_scsi_uninit; pc->vendor_id = PCI_VENDOR_ID_LSI_LOGIC; pc->device_id = info->device_id; diff --git a/hw/scsi/scsi-bus.c b/hw/scsi/scsi-bus.c index dca9576828..bd2c0e4caa 100644 --- a/hw/scsi/scsi-bus.c +++ b/hw/scsi/scsi-bus.c @@ -242,8 +242,9 @@ SCSIDevice *scsi_bus_legacy_add_drive(SCSIBus *bus, BlockBackend *blk, if (serial && object_property_find(OBJECT(dev), "serial", NULL)) { qdev_prop_set_string(dev, "serial", serial); } - if (qdev_prop_set_drive(dev, "drive", blk) < 0) { - error_setg(errp, "Setting drive property failed"); + qdev_prop_set_drive(dev, "drive", blk, &err); + if (err) { + error_propagate(errp, err); object_unparent(OBJECT(dev)); return NULL; } @@ -273,7 +274,6 @@ void scsi_bus_legacy_handle_cmdline(SCSIBus *bus, Error **errp) scsi_bus_legacy_add_drive(bus, blk_by_legacy_dinfo(dinfo), unit, false, -1, NULL, &err); if (err != NULL) { - error_report("%s", error_get_pretty(err)); error_propagate(errp, err); break; } diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c index f65618d802..54d71f4c03 100644 --- a/hw/scsi/scsi-disk.c +++ b/hw/scsi/scsi-disk.c @@ -2251,6 +2251,7 @@ static void scsi_realize(SCSIDevice *dev, Error **errp) } blkconf_serial(&s->qdev.conf, &s->serial); + blkconf_blocksizes(&s->qdev.conf); if (dev->type == TYPE_DISK) { blkconf_geometry(&dev->conf, NULL, 65535, 255, 255, &err); if (err) { @@ -2290,6 +2291,12 @@ static void scsi_realize(SCSIDevice *dev, Error **errp) static void scsi_hd_realize(SCSIDevice *dev, Error **errp) { SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, dev); + /* can happen for devices without drive. The error message for missing + * backend will be issued in scsi_realize + */ + if (s->qdev.conf.blk) { + blkconf_blocksizes(&s->qdev.conf); + } s->qdev.blocksize = s->qdev.conf.logical_block_size; s->qdev.type = TYPE_DISK; if (!s->product) { diff --git a/hw/scsi/vhost-scsi.c b/hw/scsi/vhost-scsi.c index 618b0af186..335f4429a9 100644 --- a/hw/scsi/vhost-scsi.c +++ b/hw/scsi/vhost-scsi.c @@ -83,7 +83,7 @@ static int vhost_scsi_start(VHostSCSI *s) if (abi_version > VHOST_SCSI_ABI_VERSION) { error_report("vhost-scsi: The running tcm_vhost kernel abi_version:" " %d is greater than vhost_scsi userspace supports: %d, please" - " upgrade your version of QEMU\n", abi_version, + " upgrade your version of QEMU", abi_version, VHOST_SCSI_ABI_VERSION); return -ENOSYS; } @@ -141,7 +141,7 @@ static void vhost_scsi_stop(VHostSCSI *s) if (k->set_guest_notifiers) { ret = k->set_guest_notifiers(qbus->parent, s->dev.nvqs, false); if (ret < 0) { - error_report("vhost guest notifier cleanup failed: %d\n", ret); + error_report("vhost guest notifier cleanup failed: %d", ret); } } assert(ret >= 0); @@ -186,7 +186,7 @@ static void vhost_scsi_set_status(VirtIODevice *vdev, uint8_t val) ret = vhost_scsi_start(s); if (ret < 0) { - error_report("virtio-scsi: unable to start vhost: %s\n", + error_report("virtio-scsi: unable to start vhost: %s", strerror(-ret)); /* There is no userspace virtio-scsi fallback so exit */ diff --git a/hw/sparc/leon3.c b/hw/sparc/leon3.c index 751392e137..e41ec0bf3a 100644 --- a/hw/sparc/leon3.c +++ b/hw/sparc/leon3.c @@ -186,6 +186,7 @@ static void leon3_generic_hw_init(MachineState *machine) fprintf(stderr, "Can't read bios image %s\n", filename); exit(1); } + g_free(filename); /* Can directly load an application. */ if (kernel_filename != NULL) { diff --git a/hw/sparc/sun4m.c b/hw/sparc/sun4m.c index 09afccf860..b879aa91eb 100644 --- a/hw/sparc/sun4m.c +++ b/hw/sparc/sun4m.c @@ -127,7 +127,7 @@ static void fw_cfg_boot_set(void *opaque, const char *boot_device, fw_cfg_add_i16(opaque, FW_CFG_BOOT_DEVICE, boot_device[0]); } -static void nvram_init(M48t59State *nvram, uint8_t *macaddr, +static void nvram_init(Nvram *nvram, uint8_t *macaddr, const char *cmdline, const char *boot_devices, ram_addr_t RAM_size, uint32_t kernel_size, int width, int height, int depth, @@ -137,6 +137,7 @@ static void nvram_init(M48t59State *nvram, uint8_t *macaddr, uint32_t start, end; uint8_t image[0x1ff0]; struct OpenBIOS_nvpart_v1 *part_header; + NvramClass *k = NVRAM_GET_CLASS(nvram); memset(image, '\0', sizeof(image)); @@ -170,8 +171,9 @@ static void nvram_init(M48t59State *nvram, uint8_t *macaddr, Sun_init_header((struct Sun_nvram *)&image[0x1fd8], macaddr, nvram_machine_id); - for (i = 0; i < sizeof(image); i++) - m48t59_write(nvram, i, image[i]); + for (i = 0; i < sizeof(image); i++) { + (k->write)(nvram, i, image[i]); + } } static DeviceState *slavio_intctl; @@ -1012,7 +1014,7 @@ static void sun4m_hw_init(const struct sun4m_hwdef *hwdef, lance_init(&nd_table[0], hwdef->le_base, ledma, ledma_irq); - nvram = m48t59_init(slavio_irq[0], hwdef->nvram_base, 0, 0x2000, 8); + nvram = m48t59_init(slavio_irq[0], hwdef->nvram_base, 0, 0x2000, 1968, 8); slavio_timer_init_all(hwdef->counter_base, slavio_irq[19], slavio_cpu_irq, smp_cpus); diff --git a/hw/sparc64/sun4u.c b/hw/sparc64/sun4u.c index b310588ff7..f027caf909 100644 --- a/hw/sparc64/sun4u.c +++ b/hw/sparc64/sun4u.c @@ -130,7 +130,7 @@ static void fw_cfg_boot_set(void *opaque, const char *boot_device, fw_cfg_add_i16(opaque, FW_CFG_BOOT_DEVICE, boot_device[0]); } -static int sun4u_NVRAM_set_params(M48t59State *nvram, uint16_t NVRAM_size, +static int sun4u_NVRAM_set_params(Nvram *nvram, uint16_t NVRAM_size, const char *arch, ram_addr_t RAM_size, const char *boot_devices, uint32_t kernel_image, uint32_t kernel_size, @@ -144,6 +144,7 @@ static int sun4u_NVRAM_set_params(M48t59State *nvram, uint16_t NVRAM_size, uint32_t start, end; uint8_t image[0x1ff0]; struct OpenBIOS_nvpart_v1 *part_header; + NvramClass *k = NVRAM_GET_CLASS(nvram); memset(image, '\0', sizeof(image)); @@ -176,8 +177,9 @@ static int sun4u_NVRAM_set_params(M48t59State *nvram, uint16_t NVRAM_size, Sun_init_header((struct Sun_nvram *)&image[0x1fd8], macaddr, 0x80); - for (i = 0; i < sizeof(image); i++) - m48t59_write(nvram, i, image[i]); + for (i = 0; i < sizeof(image); i++) { + (k->write)(nvram, i, image[i]); + } return 0; } @@ -610,7 +612,7 @@ pci_ebus_init1(PCIDevice *pci_dev) 0, 0x1000000); pci_register_bar(pci_dev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->bar0); memory_region_init_alias(&s->bar1, OBJECT(s), "bar1", get_system_io(), - 0, 0x1000); + 0, 0x4000); pci_register_bar(pci_dev, 1, PCI_BASE_ADDRESS_SPACE_IO, &s->bar1); return 0; } @@ -818,11 +820,12 @@ static void sun4uv_init(MemoryRegion *address_space_mem, const struct hwdef *hwdef) { SPARCCPU *cpu; - M48t59State *nvram; + Nvram *nvram; unsigned int i; uint64_t initrd_addr, initrd_size, kernel_addr, kernel_size, kernel_entry; PCIBus *pci_bus, *pci_bus2, *pci_bus3; ISABus *isa_bus; + SysBusDevice *s; qemu_irq *ivec_irqs, *pbm_irqs; DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS]; DriveInfo *fd[MAX_FD]; @@ -866,8 +869,13 @@ static void sun4uv_init(MemoryRegion *address_space_mem, fd[i] = drive_get(IF_FLOPPY, 0, i); } fdctrl_init_isa(isa_bus, fd); - nvram = m48t59_init_isa(isa_bus, 0x0074, NVRAM_SIZE, 59); + /* Map NVRAM into I/O (ebus) space */ + nvram = m48t59_init(NULL, 0, 0, NVRAM_SIZE, 1968, 59); + s = SYS_BUS_DEVICE(nvram); + memory_region_add_subregion(get_system_io(), 0x2000, + sysbus_mmio_get_region(s, 0)); + initrd_size = 0; initrd_addr = 0; kernel_size = sun4u_load_kernel(machine->kernel_filename, diff --git a/hw/timer/a9gtimer.c b/hw/timer/a9gtimer.c index 435142a3c9..b087bbddb8 100644 --- a/hw/timer/a9gtimer.c +++ b/hw/timer/a9gtimer.c @@ -289,7 +289,7 @@ static void a9_gtimer_realize(DeviceState *dev, Error **errp) int i; if (s->num_cpu < 1 || s->num_cpu > A9_GTIMER_MAX_CPUS) { - error_setg(errp, "%s: num-cpu must be between 1 and %d\n", + error_setg(errp, "%s: num-cpu must be between 1 and %d", __func__, A9_GTIMER_MAX_CPUS); return; } diff --git a/hw/timer/m48t59.c b/hw/timer/m48t59.c index 31509d5c28..8ab683ddac 100644 --- a/hw/timer/m48t59.c +++ b/hw/timer/m48t59.c @@ -2,6 +2,7 @@ * QEMU M48T59 and M48T08 NVRAM emulation for PPC PREP and Sparc platforms * * Copyright (c) 2003-2005, 2007 Jocelyn Mayer + * Copyright (c) 2013 Hervé Poussineau * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -37,12 +38,35 @@ #define NVRAM_PRINTF(fmt, ...) do { } while (0) #endif +#define TYPE_M48TXX_SYS_BUS "sysbus-m48txx" +#define M48TXX_SYS_BUS_GET_CLASS(obj) \ + OBJECT_GET_CLASS(M48txxSysBusDeviceClass, (obj), TYPE_M48TXX_SYS_BUS) +#define M48TXX_SYS_BUS_CLASS(klass) \ + OBJECT_CLASS_CHECK(M48txxSysBusDeviceClass, (klass), TYPE_M48TXX_SYS_BUS) +#define M48TXX_SYS_BUS(obj) \ + OBJECT_CHECK(M48txxSysBusState, (obj), TYPE_M48TXX_SYS_BUS) + +#define TYPE_M48TXX_ISA "isa-m48txx" +#define M48TXX_ISA_GET_CLASS(obj) \ + OBJECT_GET_CLASS(M48txxISADeviceClass, (obj), TYPE_M48TXX_ISA) +#define M48TXX_ISA_CLASS(klass) \ + OBJECT_CLASS_CHECK(M48txxISADeviceClass, (klass), TYPE_M48TXX_ISA) +#define M48TXX_ISA(obj) \ + OBJECT_CHECK(M48txxISAState, (obj), TYPE_M48TXX_ISA) + /* * The M48T02, M48T08 and M48T59 chips are very similar. The newer '59 has * alarm and a watchdog timer and related control registers. In the * PPC platform there is also a nvram lock function. */ +typedef struct M48txxInfo { + const char *isa_name; + const char *sysbus_name; + uint32_t model; /* 2 = m48t02, 8 = m48t08, 59 = m48t59 */ + uint32_t size; +} M48txxInfo; + /* * Chipset docs: * http://www.st.com/stonline/products/literature/ds/2410/m48t02.pdf @@ -50,12 +74,12 @@ * http://www.st.com/stonline/products/literature/od/7001/m48t59y.pdf */ -struct M48t59State { +typedef struct M48t59State { /* Hardware parameters */ qemu_irq IRQ; MemoryRegion iomem; - uint32_t io_base; uint32_t size; + int32_t base_year; /* RTC management */ time_t time_offset; time_t stop_time; @@ -70,28 +94,51 @@ struct M48t59State { /* NVRAM storage */ uint16_t addr; uint8_t lock; -}; - -#define TYPE_ISA_M48T59 "m48t59_isa" -#define ISA_M48T59(obj) \ - OBJECT_CHECK(M48t59ISAState, (obj), TYPE_ISA_M48T59) +} M48t59State; -typedef struct M48t59ISAState { +typedef struct M48txxISAState { ISADevice parent_obj; - M48t59State state; + uint32_t io_base; MemoryRegion io; -} M48t59ISAState; +} M48txxISAState; -#define SYSBUS_M48T59(obj) \ - OBJECT_CHECK(M48t59SysBusState, (obj), TYPE_SYSBUS_M48T59) +typedef struct M48txxISADeviceClass { + ISADeviceClass parent_class; + M48txxInfo info; +} M48txxISADeviceClass; -typedef struct M48t59SysBusState { +typedef struct M48txxSysBusState { SysBusDevice parent_obj; - M48t59State state; MemoryRegion io; -} M48t59SysBusState; +} M48txxSysBusState; + +typedef struct M48txxSysBusDeviceClass { + SysBusDeviceClass parent_class; + M48txxInfo info; +} M48txxSysBusDeviceClass; + +static M48txxInfo m48txx_info[] = { + { + .sysbus_name = "sysbus-m48t02", + .model = 2, + .size = 0x800, + },{ + .sysbus_name = "sysbus-m48t08", + .model = 8, + .size = 0x2000, + },{ + .sysbus_name = "sysbus-m48t59", + .model = 59, + .size = 0x2000, + },{ + .isa_name = "isa-m48t59", + .model = 59, + .size = 0x2000, + } +}; + /* Fake timer functions */ @@ -198,9 +245,8 @@ static void set_up_watchdog(M48t59State *NVRAM, uint8_t value) } /* Direct access to NVRAM */ -void m48t59_write (void *opaque, uint32_t addr, uint32_t val) +static void m48t59_write(M48t59State *NVRAM, uint32_t addr, uint32_t val) { - M48t59State *NVRAM = opaque; struct tm tm; int tmp; @@ -346,11 +392,7 @@ void m48t59_write (void *opaque, uint32_t addr, uint32_t val) tmp = from_bcd(val); if (tmp >= 0 && tmp <= 99) { get_time(NVRAM, &tm); - if (NVRAM->model == 8) { - tm.tm_year = from_bcd(val) + 68; // Base year is 1968 - } else { - tm.tm_year = from_bcd(val); - } + tm.tm_year = from_bcd(val) + NVRAM->base_year - 1900; set_time(NVRAM, &tm); } break; @@ -368,9 +410,8 @@ void m48t59_write (void *opaque, uint32_t addr, uint32_t val) } } -uint32_t m48t59_read (void *opaque, uint32_t addr) +static uint32_t m48t59_read(M48t59State *NVRAM, uint32_t addr) { - M48t59State *NVRAM = opaque; struct tm tm; uint32_t retval = 0xFF; @@ -453,11 +494,7 @@ uint32_t m48t59_read (void *opaque, uint32_t addr) case 0x07FF: /* year */ get_time(NVRAM, &tm); - if (NVRAM->model == 8) { - retval = to_bcd(tm.tm_year - 68); // Base year is 1968 - } else { - retval = to_bcd(tm.tm_year); - } + retval = to_bcd((tm.tm_year + 1900 - NVRAM->base_year) % 100); break; default: /* Check lock registers state */ @@ -477,10 +514,8 @@ uint32_t m48t59_read (void *opaque, uint32_t addr) return retval; } -void m48t59_toggle_lock (void *opaque, int lock) +static void m48t59_toggle_lock(M48t59State *NVRAM, int lock) { - M48t59State *NVRAM = opaque; - NVRAM->lock ^= 1 << lock; } @@ -616,7 +651,7 @@ static void m48t59_reset_common(M48t59State *NVRAM) static void m48t59_reset_isa(DeviceState *d) { - M48t59ISAState *isa = ISA_M48T59(d); + M48txxISAState *isa = M48TXX_ISA(d); M48t59State *NVRAM = &isa->state; m48t59_reset_common(NVRAM); @@ -624,7 +659,7 @@ static void m48t59_reset_isa(DeviceState *d) static void m48t59_reset_sysbus(DeviceState *d) { - M48t59SysBusState *sys = SYSBUS_M48T59(d); + M48txxSysBusState *sys = M48TXX_SYS_BUS(d); M48t59State *NVRAM = &sys->state; m48t59_reset_common(NVRAM); @@ -641,58 +676,63 @@ static const MemoryRegionOps m48t59_io_ops = { }; /* Initialisation routine */ -M48t59State *m48t59_init(qemu_irq IRQ, hwaddr mem_base, - uint32_t io_base, uint16_t size, int model) +Nvram *m48t59_init(qemu_irq IRQ, hwaddr mem_base, + uint32_t io_base, uint16_t size, int base_year, + int model) { DeviceState *dev; SysBusDevice *s; - M48t59SysBusState *d; - M48t59State *state; - - dev = qdev_create(NULL, TYPE_SYSBUS_M48T59); - qdev_prop_set_uint32(dev, "model", model); - qdev_prop_set_uint32(dev, "size", size); - qdev_prop_set_uint32(dev, "io_base", io_base); - qdev_init_nofail(dev); - s = SYS_BUS_DEVICE(dev); - d = SYSBUS_M48T59(dev); - state = &d->state; - sysbus_connect_irq(s, 0, IRQ); - memory_region_init_io(&d->io, OBJECT(d), &m48t59_io_ops, state, - "m48t59", 4); - if (io_base != 0) { - memory_region_add_subregion(get_system_io(), io_base, &d->io); - } - if (mem_base != 0) { - sysbus_mmio_map(s, 0, mem_base); + int i; + + for (i = 0; i < ARRAY_SIZE(m48txx_info); i++) { + if (!m48txx_info[i].sysbus_name || + m48txx_info[i].size != size || + m48txx_info[i].model != model) { + continue; + } + + dev = qdev_create(NULL, m48txx_info[i].sysbus_name); + qdev_prop_set_int32(dev, "base-year", base_year); + qdev_init_nofail(dev); + s = SYS_BUS_DEVICE(dev); + sysbus_connect_irq(s, 0, IRQ); + if (io_base != 0) { + memory_region_add_subregion(get_system_io(), io_base, + sysbus_mmio_get_region(s, 1)); + } + if (mem_base != 0) { + sysbus_mmio_map(s, 0, mem_base); + } + + return NVRAM(s); } - return state; + assert(false); + return NULL; } -M48t59State *m48t59_init_isa(ISABus *bus, uint32_t io_base, uint16_t size, - int model) +Nvram *m48t59_init_isa(ISABus *bus, uint32_t io_base, uint16_t size, + int base_year, int model) { - M48t59ISAState *d; - ISADevice *isadev; DeviceState *dev; - M48t59State *s; - - isadev = isa_create(bus, TYPE_ISA_M48T59); - dev = DEVICE(isadev); - qdev_prop_set_uint32(dev, "model", model); - qdev_prop_set_uint32(dev, "size", size); - qdev_prop_set_uint32(dev, "io_base", io_base); - qdev_init_nofail(dev); - d = ISA_M48T59(isadev); - s = &d->state; - - memory_region_init_io(&d->io, OBJECT(d), &m48t59_io_ops, s, "m48t59", 4); - if (io_base != 0) { - isa_register_ioport(isadev, &d->io, io_base); + int i; + + for (i = 0; i < ARRAY_SIZE(m48txx_info); i++) { + if (!m48txx_info[i].isa_name || + m48txx_info[i].size != size || + m48txx_info[i].model != model) { + continue; + } + + dev = DEVICE(isa_create(bus, m48txx_info[i].isa_name)); + qdev_prop_set_uint32(dev, "iobase", io_base); + qdev_prop_set_int32(dev, "base-year", base_year); + qdev_init_nofail(dev); + return NVRAM(dev); } - return s; + assert(false); + return NULL; } static void m48t59_realize_common(M48t59State *s, Error **errp) @@ -709,25 +749,38 @@ static void m48t59_realize_common(M48t59State *s, Error **errp) static void m48t59_isa_realize(DeviceState *dev, Error **errp) { + M48txxISADeviceClass *u = M48TXX_ISA_GET_CLASS(dev); ISADevice *isadev = ISA_DEVICE(dev); - M48t59ISAState *d = ISA_M48T59(dev); + M48txxISAState *d = M48TXX_ISA(dev); M48t59State *s = &d->state; + s->model = u->info.model; + s->size = u->info.size; isa_init_irq(isadev, &s->IRQ, 8); m48t59_realize_common(s, errp); + memory_region_init_io(&d->io, OBJECT(dev), &m48t59_io_ops, s, "m48t59", 4); + if (d->io_base != 0) { + isa_register_ioport(isadev, &d->io, d->io_base); + } } static int m48t59_init1(SysBusDevice *dev) { - M48t59SysBusState *d = SYSBUS_M48T59(dev); + M48txxSysBusDeviceClass *u = M48TXX_SYS_BUS_GET_CLASS(dev); + M48txxSysBusState *d = M48TXX_SYS_BUS(dev); + Object *o = OBJECT(dev); M48t59State *s = &d->state; Error *err = NULL; + s->model = u->info.model; + s->size = u->info.size; sysbus_init_irq(dev, &s->IRQ); - memory_region_init_io(&s->iomem, OBJECT(d), &nvram_ops, s, - "m48t59.nvram", s->size); + memory_region_init_io(&s->iomem, o, &nvram_ops, s, "m48t59.nvram", + s->size); + memory_region_init_io(&d->io, o, &m48t59_io_ops, s, "m48t59", 4); sysbus_init_mmio(dev, &s->iomem); + sysbus_init_mmio(dev, &d->io); m48t59_realize_common(s, &err); if (err != NULL) { error_free(err); @@ -737,59 +790,157 @@ static int m48t59_init1(SysBusDevice *dev) return 0; } +static uint32_t m48txx_isa_read(Nvram *obj, uint32_t addr) +{ + M48txxISAState *d = M48TXX_ISA(obj); + return m48t59_read(&d->state, addr); +} + +static void m48txx_isa_write(Nvram *obj, uint32_t addr, uint32_t val) +{ + M48txxISAState *d = M48TXX_ISA(obj); + m48t59_write(&d->state, addr, val); +} + +static void m48txx_isa_toggle_lock(Nvram *obj, int lock) +{ + M48txxISAState *d = M48TXX_ISA(obj); + m48t59_toggle_lock(&d->state, lock); +} + static Property m48t59_isa_properties[] = { - DEFINE_PROP_UINT32("size", M48t59ISAState, state.size, -1), - DEFINE_PROP_UINT32("model", M48t59ISAState, state.model, -1), - DEFINE_PROP_UINT32("io_base", M48t59ISAState, state.io_base, 0), + DEFINE_PROP_INT32("base-year", M48txxISAState, state.base_year, 0), + DEFINE_PROP_UINT32("iobase", M48txxISAState, io_base, 0x74), DEFINE_PROP_END_OF_LIST(), }; -static void m48t59_isa_class_init(ObjectClass *klass, void *data) +static void m48txx_isa_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); + NvramClass *nc = NVRAM_CLASS(klass); dc->realize = m48t59_isa_realize; dc->reset = m48t59_reset_isa; dc->props = m48t59_isa_properties; - /* Reason: needs to be wired up by m48t59_init_isa() */ - dc->cannot_instantiate_with_device_add_yet = true; + nc->read = m48txx_isa_read; + nc->write = m48txx_isa_write; + nc->toggle_lock = m48txx_isa_toggle_lock; } -static const TypeInfo m48t59_isa_info = { - .name = TYPE_ISA_M48T59, - .parent = TYPE_ISA_DEVICE, - .instance_size = sizeof(M48t59ISAState), - .class_init = m48t59_isa_class_init, -}; +static void m48txx_isa_concrete_class_init(ObjectClass *klass, void *data) +{ + M48txxISADeviceClass *u = M48TXX_ISA_CLASS(klass); + M48txxInfo *info = data; + + u->info = *info; +} + +static uint32_t m48txx_sysbus_read(Nvram *obj, uint32_t addr) +{ + M48txxSysBusState *d = M48TXX_SYS_BUS(obj); + return m48t59_read(&d->state, addr); +} + +static void m48txx_sysbus_write(Nvram *obj, uint32_t addr, uint32_t val) +{ + M48txxSysBusState *d = M48TXX_SYS_BUS(obj); + m48t59_write(&d->state, addr, val); +} + +static void m48txx_sysbus_toggle_lock(Nvram *obj, int lock) +{ + M48txxSysBusState *d = M48TXX_SYS_BUS(obj); + m48t59_toggle_lock(&d->state, lock); +} -static Property m48t59_properties[] = { - DEFINE_PROP_UINT32("size", M48t59SysBusState, state.size, -1), - DEFINE_PROP_UINT32("model", M48t59SysBusState, state.model, -1), - DEFINE_PROP_UINT32("io_base", M48t59SysBusState, state.io_base, 0), +static Property m48t59_sysbus_properties[] = { + DEFINE_PROP_INT32("base-year", M48txxSysBusState, state.base_year, 0), DEFINE_PROP_END_OF_LIST(), }; -static void m48t59_class_init(ObjectClass *klass, void *data) +static void m48txx_sysbus_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); + NvramClass *nc = NVRAM_CLASS(klass); k->init = m48t59_init1; dc->reset = m48t59_reset_sysbus; - dc->props = m48t59_properties; + dc->props = m48t59_sysbus_properties; + nc->read = m48txx_sysbus_read; + nc->write = m48txx_sysbus_write; + nc->toggle_lock = m48txx_sysbus_toggle_lock; +} + +static void m48txx_sysbus_concrete_class_init(ObjectClass *klass, void *data) +{ + M48txxSysBusDeviceClass *u = M48TXX_SYS_BUS_CLASS(klass); + M48txxInfo *info = data; + + u->info = *info; } -static const TypeInfo m48t59_info = { - .name = TYPE_SYSBUS_M48T59, - .parent = TYPE_SYS_BUS_DEVICE, - .instance_size = sizeof(M48t59SysBusState), - .class_init = m48t59_class_init, +static const TypeInfo nvram_info = { + .name = TYPE_NVRAM, + .parent = TYPE_INTERFACE, + .class_size = sizeof(NvramClass), +}; + +static const TypeInfo m48txx_sysbus_type_info = { + .name = TYPE_M48TXX_SYS_BUS, + .parent = TYPE_SYS_BUS_DEVICE, + .instance_size = sizeof(M48txxSysBusState), + .abstract = true, + .class_init = m48txx_sysbus_class_init, + .interfaces = (InterfaceInfo[]) { + { TYPE_NVRAM }, + { } + } +}; + +static const TypeInfo m48txx_isa_type_info = { + .name = TYPE_M48TXX_ISA, + .parent = TYPE_ISA_DEVICE, + .instance_size = sizeof(M48txxISAState), + .abstract = true, + .class_init = m48txx_isa_class_init, + .interfaces = (InterfaceInfo[]) { + { TYPE_NVRAM }, + { } + } }; static void m48t59_register_types(void) { - type_register_static(&m48t59_info); - type_register_static(&m48t59_isa_info); + TypeInfo sysbus_type_info = { + .parent = TYPE_M48TXX_SYS_BUS, + .class_size = sizeof(M48txxSysBusDeviceClass), + .class_init = m48txx_sysbus_concrete_class_init, + }; + TypeInfo isa_type_info = { + .parent = TYPE_M48TXX_ISA, + .class_size = sizeof(M48txxISADeviceClass), + .class_init = m48txx_isa_concrete_class_init, + }; + int i; + + type_register_static(&nvram_info); + type_register_static(&m48txx_sysbus_type_info); + type_register_static(&m48txx_isa_type_info); + + for (i = 0; i < ARRAY_SIZE(m48txx_info); i++) { + if (m48txx_info[i].sysbus_name) { + sysbus_type_info.name = m48txx_info[i].sysbus_name; + sysbus_type_info.class_data = &m48txx_info[i]; + type_register(&sysbus_type_info); + } + + if (m48txx_info[i].isa_name) { + isa_type_info.name = m48txx_info[i].isa_name; + isa_type_info.class_data = &m48txx_info[i]; + type_register(&isa_type_info); + } + } } type_init(m48t59_register_types) diff --git a/hw/tpm/tpm_passthrough.c b/hw/tpm/tpm_passthrough.c index a94c7c5a24..2a45071e36 100644 --- a/hw/tpm/tpm_passthrough.c +++ b/hw/tpm/tpm_passthrough.c @@ -143,7 +143,7 @@ static int tpm_passthrough_unix_tx_bufs(TPMPassthruState *tpm_pt, if (!tpm_pt->tpm_op_canceled || (tpm_pt->tpm_op_canceled && errno != ECANCELED)) { error_report("tpm_passthrough: error while transmitting data " - "to TPM: %s (%i)\n", + "to TPM: %s (%i)", strerror(errno), errno); } goto err_exit; @@ -156,14 +156,14 @@ static int tpm_passthrough_unix_tx_bufs(TPMPassthruState *tpm_pt, if (!tpm_pt->tpm_op_canceled || (tpm_pt->tpm_op_canceled && errno != ECANCELED)) { error_report("tpm_passthrough: error while reading data from " - "TPM: %s (%i)\n", + "TPM: %s (%i)", strerror(errno), errno); } } else if (ret < sizeof(struct tpm_resp_hdr) || tpm_passthrough_get_size_from_buffer(out) != ret) { ret = -1; error_report("tpm_passthrough: received invalid response " - "packet from TPM\n"); + "packet from TPM"); } if (is_selftest && (ret >= sizeof(struct tpm_resp_hdr))) { @@ -309,7 +309,7 @@ static void tpm_passthrough_cancel_cmd(TPMBackend *tb) if (tpm_pt->cancel_fd >= 0) { n = write(tpm_pt->cancel_fd, "-", 1); if (n != 1) { - error_report("Canceling TPM command failed: %s\n", + error_report("Canceling TPM command failed: %s", strerror(errno)); } else { tpm_pt->tpm_op_canceled = true; @@ -440,13 +440,13 @@ static int tpm_passthrough_handle_device_opts(QemuOpts *opts, TPMBackend *tb) tpm_pt->tpm_fd = qemu_open(tpm_pt->tpm_dev, O_RDWR); if (tpm_pt->tpm_fd < 0) { - error_report("Cannot access TPM device using '%s': %s\n", + error_report("Cannot access TPM device using '%s': %s", tpm_pt->tpm_dev, strerror(errno)); goto err_free_parameters; } if (tpm_passthrough_test_tpmdev(tpm_pt->tpm_fd)) { - error_report("'%s' is not a TPM device.\n", + error_report("'%s' is not a TPM device.", tpm_pt->tpm_dev); goto err_close_tpmdev; } diff --git a/hw/unicore32/puv3.c b/hw/unicore32/puv3.c index c41499e38e..cc9a21a712 100644 --- a/hw/unicore32/puv3.c +++ b/hw/unicore32/puv3.c @@ -109,6 +109,7 @@ static void puv3_init(MachineState *machine) const char *kernel_filename = machine->kernel_filename; const char *initrd_filename = machine->initrd_filename; CPUUniCore32State *env; + UniCore32CPU *cpu; if (initrd_filename) { hw_error("Please use kernel built-in initramdisk.\n"); @@ -118,10 +119,11 @@ static void puv3_init(MachineState *machine) cpu_model = "UniCore-II"; } - env = cpu_init(cpu_model); - if (!env) { + cpu = uc32_cpu_init(cpu_model); + if (!cpu) { hw_error("Unable to find CPU definition\n"); } + env = &cpu->env; puv3_soc_init(env); puv3_board_init(env, ram_size); diff --git a/hw/usb/dev-storage.c b/hw/usb/dev-storage.c index 65d9aa6147..dacefd71a5 100644 --- a/hw/usb/dev-storage.c +++ b/hw/usb/dev-storage.c @@ -611,6 +611,7 @@ static void usb_msd_realize_storage(USBDevice *dev, Error **errp) } blkconf_serial(&s->conf, &dev->serial); + blkconf_blocksizes(&s->conf); /* * Hack alert: this pretends to be a block device, but it's really @@ -663,6 +664,7 @@ static void usb_msd_realize_bot(USBDevice *dev, Error **errp) static USBDevice *usb_msd_init(USBBus *bus, const char *filename) { static int nr=0; + Error *err = NULL; char id[8]; QemuOpts *opts; DriveInfo *dinfo; @@ -706,8 +708,10 @@ static USBDevice *usb_msd_init(USBBus *bus, const char *filename) /* create guest device */ dev = usb_create(bus, "usb-storage"); - if (qdev_prop_set_drive(&dev->qdev, "drive", - blk_by_legacy_dinfo(dinfo)) < 0) { + qdev_prop_set_drive(&dev->qdev, "drive", blk_by_legacy_dinfo(dinfo), + &err); + if (err) { + error_report_err(err); object_unparent(OBJECT(dev)); return NULL; } diff --git a/hw/vfio/common.c b/hw/vfio/common.c index 148eb53fc6..b01262063d 100644 --- a/hw/vfio/common.c +++ b/hw/vfio/common.c @@ -201,7 +201,7 @@ static int vfio_dma_unmap(VFIOContainer *container, }; if (ioctl(container->fd, VFIO_IOMMU_UNMAP_DMA, &unmap)) { - error_report("VFIO_UNMAP_DMA: %d\n", -errno); + error_report("VFIO_UNMAP_DMA: %d", -errno); return -errno; } @@ -234,7 +234,7 @@ static int vfio_dma_map(VFIOContainer *container, hwaddr iova, return 0; } - error_report("VFIO_MAP_DMA: %d\n", -errno); + error_report("VFIO_MAP_DMA: %d", -errno); return -errno; } @@ -274,7 +274,7 @@ static void vfio_iommu_map_notify(Notifier *n, void *data) iotlb->translated_addr, &xlat, &len, iotlb->perm & IOMMU_WO); if (!memory_region_is_ram(mr)) { - error_report("iommu map to non memory area %"HWADDR_PRIx"\n", + error_report("iommu map to non memory area %"HWADDR_PRIx"", xlat); return; } @@ -283,7 +283,7 @@ static void vfio_iommu_map_notify(Notifier *n, void *data) * check that it did not truncate too much. */ if (len & iotlb->addr_mask) { - error_report("iommu has granularity incompatible with target AS\n"); + error_report("iommu has granularity incompatible with target AS"); return; } @@ -566,7 +566,7 @@ static void vfio_kvm_device_add_group(VFIOGroup *group) }; if (kvm_vm_ioctl(kvm_state, KVM_CREATE_DEVICE, &cd)) { - error_report("Failed to create KVM VFIO device: %m\n"); + error_report("Failed to create KVM VFIO device: %m"); return; } diff --git a/hw/virtio/vhost-backend.c b/hw/virtio/vhost-backend.c index ff4f2001bb..4d68a27658 100644 --- a/hw/virtio/vhost-backend.c +++ b/hw/virtio/vhost-backend.c @@ -61,7 +61,7 @@ int vhost_set_backend_type(struct vhost_dev *dev, VhostBackendType backend_type) dev->vhost_ops = &user_ops; break; default: - error_report("Unknown vhost backend type\n"); + error_report("Unknown vhost backend type"); r = -1; } diff --git a/hw/xen/xen_pt_config_init.c b/hw/xen/xen_pt_config_init.c index de9a20f437..d99c22ef2f 100644 --- a/hw/xen/xen_pt_config_init.c +++ b/hw/xen/xen_pt_config_init.c @@ -360,15 +360,13 @@ static uint64_t xen_pt_get_bar_size(PCIIORegion *r) } static XenPTBarFlag xen_pt_bar_reg_parse(XenPCIPassthroughState *s, - XenPTRegInfo *reg) + int index) { PCIDevice *d = &s->dev; XenPTRegion *region = NULL; PCIIORegion *r; - int index = 0; /* check 64bit BAR */ - index = xen_pt_bar_offset_to_index(reg->offset); if ((0 < index) && (index < PCI_ROM_SLOT)) { int type = s->real_device.io_regions[index - 1].type; @@ -422,7 +420,7 @@ static int xen_pt_bar_reg_init(XenPCIPassthroughState *s, XenPTRegInfo *reg, } /* set BAR flag */ - s->bases[index].bar_flag = xen_pt_bar_reg_parse(s, reg); + s->bases[index].bar_flag = xen_pt_bar_reg_parse(s, index); if (s->bases[index].bar_flag == XEN_PT_BAR_FLAG_UNUSED) { reg_field = XEN_PT_INVALID_REG; } @@ -440,7 +438,7 @@ static int xen_pt_bar_reg_read(XenPCIPassthroughState *s, XenPTReg *cfg_entry, /* get BAR index */ index = xen_pt_bar_offset_to_index(reg->offset); - if (index < 0 || index >= PCI_NUM_REGIONS) { + if (index < 0 || index >= PCI_NUM_REGIONS - 1) { XEN_PT_ERR(&s->dev, "Internal error: Invalid BAR index [%d].\n", index); return -1; } diff --git a/hw/xtensa/sim.c b/hw/xtensa/sim.c index 37ea9ae9c2..328d20975d 100644 --- a/hw/xtensa/sim.c +++ b/hw/xtensa/sim.c @@ -64,7 +64,7 @@ static void xtensa_sim_init(MachineState *machine) for (n = 0; n < smp_cpus; n++) { cpu = cpu_xtensa_init(cpu_model); if (cpu == NULL) { - error_report("unable to find CPU definition '%s'\n", + error_report("unable to find CPU definition '%s'", cpu_model); exit(EXIT_FAILURE); } diff --git a/hw/xtensa/xtfpga.c b/hw/xtensa/xtfpga.c index d441c024c2..ab4d0e4127 100644 --- a/hw/xtensa/xtfpga.c +++ b/hw/xtensa/xtfpga.c @@ -207,7 +207,7 @@ static void lx_init(const LxBoardDesc *board, MachineState *machine) for (n = 0; n < smp_cpus; n++) { cpu = cpu_xtensa_init(cpu_model); if (cpu == NULL) { - error_report("unable to find CPU definition '%s'\n", + error_report("unable to find CPU definition '%s'", cpu_model); exit(EXIT_FAILURE); } @@ -253,7 +253,7 @@ static void lx_init(const LxBoardDesc *board, MachineState *machine) board->flash_size / board->flash_sector_size, 4, 0x0000, 0x0000, 0x0000, 0x0000, be); if (flash == NULL) { - error_report("unable to mount pflash\n"); + error_report("unable to mount pflash"); exit(EXIT_FAILURE); } } @@ -305,7 +305,7 @@ static void lx_init(const LxBoardDesc *board, MachineState *machine) uint32_t dtb_addr = tswap32(cur_lowmem); if (!fdt) { - error_report("could not load DTB '%s'\n", dtb_filename); + error_report("could not load DTB '%s'", dtb_filename); exit(EXIT_FAILURE); } @@ -325,7 +325,7 @@ static void lx_init(const LxBoardDesc *board, MachineState *machine) lowmem_end - cur_lowmem); } if (initrd_size < 0) { - error_report("could not load initrd '%s'\n", initrd_filename); + error_report("could not load initrd '%s'", initrd_filename); exit(EXIT_FAILURE); } initrd_location.start = tswap32(cur_lowmem); @@ -351,7 +351,7 @@ static void lx_init(const LxBoardDesc *board, MachineState *machine) if (success > 0 && is_linux) { entry_point = ep; } else { - error_report("could not load kernel '%s'\n", + error_report("could not load kernel '%s'", kernel_filename); exit(EXIT_FAILURE); } |