diff options
Diffstat (limited to 'hw')
-rw-r--r-- | hw/display/sm501.c | 1 | ||||
-rw-r--r-- | hw/ide/ahci_internal.h | 4 | ||||
-rw-r--r-- | hw/ide/core.c | 53 | ||||
-rw-r--r-- | hw/ide/sii3112.c | 10 | ||||
-rw-r--r-- | hw/ppc/Makefile.objs | 4 | ||||
-rw-r--r-- | hw/ppc/spapr.c | 22 | ||||
-rw-r--r-- | hw/ppc/spapr_caps.c | 78 | ||||
-rw-r--r-- | hw/ppc/spapr_cpu_core.c | 7 | ||||
-rw-r--r-- | hw/ppc/spapr_rtas.c | 9 |
9 files changed, 82 insertions, 106 deletions
diff --git a/hw/display/sm501.c b/hw/display/sm501.c index 4f7dc59b25..134cbed607 100644 --- a/hw/display/sm501.c +++ b/hw/display/sm501.c @@ -797,6 +797,7 @@ static uint64_t sm501_system_config_read(void *opaque, hwaddr addr, break; case SM501_COMMAND_LIST_STATUS: ret = 0x00180002; /* FIFOs are empty, everything idle */ + break; case SM501_IRQ_MASK: ret = s->irq_mask; break; diff --git a/hw/ide/ahci_internal.h b/hw/ide/ahci_internal.h index ce2e818c8c..8c755d4ca1 100644 --- a/hw/ide/ahci_internal.h +++ b/hw/ide/ahci_internal.h @@ -311,8 +311,6 @@ struct AHCIPCIState { AHCIState ahci; }; -#define TYPE_ICH9_AHCI "ich9-ahci" - #define ICH_AHCI(obj) \ OBJECT_CHECK(AHCIPCIState, (obj), TYPE_ICH9_AHCI) @@ -375,10 +373,8 @@ void ahci_uninit(AHCIState *s); void ahci_reset(AHCIState *s); -#define TYPE_SYSBUS_AHCI "sysbus-ahci" #define SYSBUS_AHCI(obj) OBJECT_CHECK(SysbusAHCIState, (obj), TYPE_SYSBUS_AHCI) -#define TYPE_ALLWINNER_AHCI "allwinner-ahci" #define ALLWINNER_AHCI(obj) OBJECT_CHECK(AllwinnerAHCIState, (obj), \ TYPE_ALLWINNER_AHCI) diff --git a/hw/ide/core.c b/hw/ide/core.c index 1ea5812b7e..5be72d41dc 100644 --- a/hw/ide/core.c +++ b/hw/ide/core.c @@ -380,14 +380,27 @@ static void ide_set_signature(IDEState *s) } } +static bool ide_sect_range_ok(IDEState *s, + uint64_t sector, uint64_t nb_sectors) +{ + uint64_t total_sectors; + + blk_get_geometry(s->blk, &total_sectors); + if (sector > total_sectors || nb_sectors > total_sectors - sector) { + return false; + } + return true; +} + typedef struct TrimAIOCB { BlockAIOCB common; - BlockBackend *blk; + IDEState *s; QEMUBH *bh; int ret; QEMUIOVector *qiov; BlockAIOCB *aiocb; int i, j; + bool is_invalid; } TrimAIOCB; static void trim_aio_cancel(BlockAIOCB *acb) @@ -415,8 +428,11 @@ static void ide_trim_bh_cb(void *opaque) { TrimAIOCB *iocb = opaque; - iocb->common.cb(iocb->common.opaque, iocb->ret); - + if (iocb->is_invalid) { + ide_dma_error(iocb->s); + } else { + iocb->common.cb(iocb->common.opaque, iocb->ret); + } qemu_bh_delete(iocb->bh); iocb->bh = NULL; qemu_aio_unref(iocb); @@ -425,6 +441,8 @@ static void ide_trim_bh_cb(void *opaque) static void ide_issue_trim_cb(void *opaque, int ret) { TrimAIOCB *iocb = opaque; + IDEState *s = iocb->s; + if (ret >= 0) { while (iocb->j < iocb->qiov->niov) { int j = iocb->j; @@ -441,8 +459,13 @@ static void ide_issue_trim_cb(void *opaque, int ret) continue; } + if (!ide_sect_range_ok(s, sector, count)) { + iocb->is_invalid = true; + goto done; + } + /* Got an entry! Submit and exit. */ - iocb->aiocb = blk_aio_pdiscard(iocb->blk, + iocb->aiocb = blk_aio_pdiscard(s->blk, sector << BDRV_SECTOR_BITS, count << BDRV_SECTOR_BITS, ide_issue_trim_cb, opaque); @@ -456,6 +479,7 @@ static void ide_issue_trim_cb(void *opaque, int ret) iocb->ret = ret; } +done: iocb->aiocb = NULL; if (iocb->bh) { qemu_bh_schedule(iocb->bh); @@ -466,16 +490,17 @@ BlockAIOCB *ide_issue_trim( int64_t offset, QEMUIOVector *qiov, BlockCompletionFunc *cb, void *cb_opaque, void *opaque) { - BlockBackend *blk = opaque; + IDEState *s = opaque; TrimAIOCB *iocb; - iocb = blk_aio_get(&trim_aiocb_info, blk, cb, cb_opaque); - iocb->blk = blk; + iocb = blk_aio_get(&trim_aiocb_info, s->blk, cb, cb_opaque); + iocb->s = s; iocb->bh = qemu_bh_new(ide_trim_bh_cb, iocb); iocb->ret = 0; iocb->qiov = qiov; iocb->i = -1; iocb->j = 0; + iocb->is_invalid = false; ide_issue_trim_cb(iocb, 0); return &iocb->common; } @@ -601,18 +626,6 @@ static void ide_rw_error(IDEState *s) { ide_set_irq(s->bus); } -static bool ide_sect_range_ok(IDEState *s, - uint64_t sector, uint64_t nb_sectors) -{ - uint64_t total_sectors; - - blk_get_geometry(s->blk, &total_sectors); - if (sector > total_sectors || nb_sectors > total_sectors - sector) { - return false; - } - return true; -} - static void ide_buffered_readv_cb(void *opaque, int ret) { IDEBufferedRequest *req = opaque; @@ -900,7 +913,7 @@ static void ide_dma_cb(void *opaque, int ret) case IDE_DMA_TRIM: s->bus->dma->aiocb = dma_blk_io(blk_get_aio_context(s->blk), &s->sg, offset, BDRV_SECTOR_SIZE, - ide_issue_trim, s->blk, ide_dma_cb, s, + ide_issue_trim, s, ide_dma_cb, s, DMA_DIRECTION_TO_DEVICE); break; default: diff --git a/hw/ide/sii3112.c b/hw/ide/sii3112.c index e2f5562bb7..17aa930e39 100644 --- a/hw/ide/sii3112.c +++ b/hw/ide/sii3112.c @@ -79,13 +79,13 @@ static uint64_t sii3112_reg_read(void *opaque, hwaddr addr, val |= (d->regs[0].confstat & (1UL << 11) ? (1 << 4) : 0); /*SATAINT0*/ val |= (d->regs[1].confstat & (1UL << 11) ? (1 << 6) : 0); /*SATAINT1*/ val |= (d->i.bmdma[1].status & BM_STATUS_INT ? (1 << 14) : 0); - val |= d->i.bmdma[0].status << 16; - val |= d->i.bmdma[1].status << 24; + val |= (uint32_t)d->i.bmdma[0].status << 16; + val |= (uint32_t)d->i.bmdma[1].status << 24; break; case 0x18: val = d->i.bmdma[1].cmd; val |= (d->regs[1].confstat & (1UL << 11) ? (1 << 4) : 0); - val |= d->i.bmdma[1].status << 16; + val |= (uint32_t)d->i.bmdma[1].status << 16; break; case 0x80 ... 0x87: if (size == 1) { @@ -128,7 +128,7 @@ static uint64_t sii3112_reg_read(void *opaque, hwaddr addr, val = (d->i.bus[0].ifs[0].blk) ? 0x113 : 0; break; case 0x148: - val = d->regs[0].sien << 16; + val = (uint32_t)d->regs[0].sien << 16; break; case 0x180: val = d->regs[1].scontrol; @@ -137,7 +137,7 @@ static uint64_t sii3112_reg_read(void *opaque, hwaddr addr, val = (d->i.bus[1].ifs[0].blk) ? 0x113 : 0; break; case 0x1c8: - val = d->regs[1].sien << 16; + val = (uint32_t)d->regs[1].sien << 16; break; default: val = 0; diff --git a/hw/ppc/Makefile.objs b/hw/ppc/Makefile.objs index 1faff853b7..ad1928c5d8 100644 --- a/hw/ppc/Makefile.objs +++ b/hw/ppc/Makefile.objs @@ -12,8 +12,8 @@ obj-y += spapr_pci_vfio.o endif obj-$(CONFIG_PSERIES) += spapr_rtas_ddw.o # PowerPC 4xx boards -obj-y += ppc405_boards.o ppc4xx_devs.o ppc405_uc.o ppc440_bamboo.o -obj-y += ppc4xx_pci.o +obj-y += ppc4xx_devs.o ppc405_uc.o +obj-$(CONFIG_PPC4XX) += ppc4xx_pci.o ppc405_boards.o ppc440_bamboo.o # PReP obj-$(CONFIG_PREP) += prep.o obj-$(CONFIG_PREP) += prep_systemio.o diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index a781dd22e7..88a78d31eb 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -1484,6 +1484,15 @@ static void spapr_machine_reset(void) spapr_setup_hpt_and_vrma(spapr); } + /* if this reset wasn't generated by CAS, we should reset our + * negotiated options and start from scratch */ + if (!spapr->cas_reboot) { + spapr_ovec_cleanup(spapr->ov5_cas); + spapr->ov5_cas = spapr_ovec_new(); + + ppc_set_compat(first_ppc_cpu, spapr->max_compat_pvr, &error_fatal); + } + qemu_devices_reset(); /* DRC reset may cause a device to be unplugged. This will cause troubles @@ -1504,15 +1513,6 @@ static void spapr_machine_reset(void) rtas_addr = rtas_limit - RTAS_MAX_SIZE; fdt_addr = rtas_addr - FDT_MAX_SIZE; - /* if this reset wasn't generated by CAS, we should reset our - * negotiated options and start from scratch */ - if (!spapr->cas_reboot) { - spapr_ovec_cleanup(spapr->ov5_cas); - spapr->ov5_cas = spapr_ovec_new(); - - ppc_set_compat(first_ppc_cpu, spapr->max_compat_pvr, &error_fatal); - } - fdt = spapr_build_fdt(spapr, rtas_addr, spapr->rtas_size); spapr_load_rtas(spapr, fdt, rtas_addr); @@ -3357,9 +3357,7 @@ static void spapr_core_plug(HotplugHandler *hotplug_dev, DeviceState *dev, int i; for (i = 0; i < cc->nr_threads; i++) { - sPAPRCPUCore *sc = SPAPR_CPU_CORE(dev); - - cs = CPU(sc->threads[i]); + cs = CPU(core->threads[i]); pre_2_10_vmstate_unregister_dummy_icp(cs->cpu_index); } } diff --git a/hw/ppc/spapr_caps.c b/hw/ppc/spapr_caps.c index d5c9ce774a..5d52969bd5 100644 --- a/hw/ppc/spapr_caps.c +++ b/hw/ppc/spapr_caps.c @@ -228,62 +228,32 @@ int spapr_caps_post_migration(sPAPRMachineState *spapr) return ok ? 0 : -EINVAL; } -static bool spapr_cap_htm_needed(void *opaque) -{ - sPAPRMachineState *spapr = opaque; - - return spapr->cmd_line_caps[SPAPR_CAP_HTM] && - (spapr->eff.caps[SPAPR_CAP_HTM] != spapr->def.caps[SPAPR_CAP_HTM]); -} - -const VMStateDescription vmstate_spapr_cap_htm = { - .name = "spapr/cap/htm", - .version_id = 1, - .minimum_version_id = 1, - .needed = spapr_cap_htm_needed, - .fields = (VMStateField[]) { - VMSTATE_UINT8(mig.caps[SPAPR_CAP_HTM], sPAPRMachineState), - VMSTATE_END_OF_LIST() - }, -}; - -static bool spapr_cap_vsx_needed(void *opaque) -{ - sPAPRMachineState *spapr = opaque; - - return spapr->cmd_line_caps[SPAPR_CAP_VSX] && - (spapr->eff.caps[SPAPR_CAP_VSX] != spapr->def.caps[SPAPR_CAP_VSX]); +/* Used to generate the migration field and needed function for a spapr cap */ +#define SPAPR_CAP_MIG_STATE(cap, ccap) \ +static bool spapr_cap_##cap##_needed(void *opaque) \ +{ \ + sPAPRMachineState *spapr = opaque; \ + \ + return spapr->cmd_line_caps[SPAPR_CAP_##ccap] && \ + (spapr->eff.caps[SPAPR_CAP_##ccap] != \ + spapr->def.caps[SPAPR_CAP_##ccap]); \ +} \ + \ +const VMStateDescription vmstate_spapr_cap_##cap = { \ + .name = "spapr/cap/" #cap, \ + .version_id = 1, \ + .minimum_version_id = 1, \ + .needed = spapr_cap_##cap##_needed, \ + .fields = (VMStateField[]) { \ + VMSTATE_UINT8(mig.caps[SPAPR_CAP_##ccap], \ + sPAPRMachineState), \ + VMSTATE_END_OF_LIST() \ + }, \ } -const VMStateDescription vmstate_spapr_cap_vsx = { - .name = "spapr/cap/vsx", - .version_id = 1, - .minimum_version_id = 1, - .needed = spapr_cap_vsx_needed, - .fields = (VMStateField[]) { - VMSTATE_UINT8(mig.caps[SPAPR_CAP_VSX], sPAPRMachineState), - VMSTATE_END_OF_LIST() - }, -}; - -static bool spapr_cap_dfp_needed(void *opaque) -{ - sPAPRMachineState *spapr = opaque; - - return spapr->cmd_line_caps[SPAPR_CAP_DFP] && - (spapr->eff.caps[SPAPR_CAP_DFP] != spapr->def.caps[SPAPR_CAP_DFP]); -} - -const VMStateDescription vmstate_spapr_cap_dfp = { - .name = "spapr/cap/dfp", - .version_id = 1, - .minimum_version_id = 1, - .needed = spapr_cap_dfp_needed, - .fields = (VMStateField[]) { - VMSTATE_UINT8(mig.caps[SPAPR_CAP_DFP], sPAPRMachineState), - VMSTATE_END_OF_LIST() - }, -}; +SPAPR_CAP_MIG_STATE(htm, HTM); +SPAPR_CAP_MIG_STATE(vsx, VSX); +SPAPR_CAP_MIG_STATE(dfp, DFP); void spapr_caps_reset(sPAPRMachineState *spapr) { diff --git a/hw/ppc/spapr_cpu_core.c b/hw/ppc/spapr_cpu_core.c index ac19b2e0b7..590d167b04 100644 --- a/hw/ppc/spapr_cpu_core.c +++ b/hw/ppc/spapr_cpu_core.c @@ -44,6 +44,13 @@ static void spapr_cpu_reset(void *opaque) if (cs != first_cpu) { env->spr[SPR_LPCR] &= ~pcc->lpcr_pm; } + + /* Set compatibility mode to match the boot CPU, which was either set + * by the machine reset code or by CAS. This should never fail. + */ + if (cs != first_cpu) { + ppc_set_compat(cpu, POWERPC_CPU(first_cpu)->compat_pvr, &error_abort); + } } static void spapr_cpu_destroy(PowerPCCPU *cpu) diff --git a/hw/ppc/spapr_rtas.c b/hw/ppc/spapr_rtas.c index 2b89e1d448..4bb939d3d1 100644 --- a/hw/ppc/spapr_rtas.c +++ b/hw/ppc/spapr_rtas.c @@ -163,7 +163,6 @@ static void rtas_start_cpu(PowerPCCPU *cpu_, sPAPRMachineState *spapr, CPUState *cs = CPU(cpu); CPUPPCState *env = &cpu->env; PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu); - Error *local_err = NULL; if (!cs->halted) { rtas_st(rets, 0, RTAS_OUT_HW_ERROR); @@ -175,14 +174,6 @@ static void rtas_start_cpu(PowerPCCPU *cpu_, sPAPRMachineState *spapr, * new cpu enters */ kvm_cpu_synchronize_state(cs); - /* Set compatibility mode to match existing cpus */ - ppc_set_compat(cpu, POWERPC_CPU(first_cpu)->compat_pvr, &local_err); - if (local_err) { - error_report_err(local_err); - rtas_st(rets, 0, RTAS_OUT_HW_ERROR); - return; - } - env->msr = (1ULL << MSR_SF) | (1ULL << MSR_ME); /* Enable Power-saving mode Exit Cause exceptions for the new CPU */ |