diff options
Diffstat (limited to 'hw')
-rw-r--r-- | hw/acpi/tco.c | 11 | ||||
-rw-r--r-- | hw/acpi/trace-events | 4 | ||||
-rw-r--r-- | hw/core/qdev.c | 32 | ||||
-rw-r--r-- | hw/display/cirrus_vga.c | 6 | ||||
-rw-r--r-- | hw/display/vga.c | 33 | ||||
-rw-r--r-- | hw/i386/pc.c | 7 | ||||
-rw-r--r-- | hw/ide/core.c | 1 | ||||
-rw-r--r-- | hw/ide/qdev.c | 1 | ||||
-rw-r--r-- | hw/scsi/scsi-disk.c | 28 |
9 files changed, 96 insertions, 27 deletions
diff --git a/hw/acpi/tco.c b/hw/acpi/tco.c index 05b9d7ba36..a9143963ab 100644 --- a/hw/acpi/tco.c +++ b/hw/acpi/tco.c @@ -12,6 +12,7 @@ #include "hw/i386/ich9.h" #include "hw/acpi/tco.h" +#include "trace.h" //#define DEBUG @@ -41,8 +42,11 @@ enum { static inline void tco_timer_reload(TCOIORegs *tr) { - tr->expire_time = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + - ((int64_t)(tr->tco.tmr & TCO_TMR_MASK) * TCO_TICK_NSEC); + int ticks = tr->tco.tmr & TCO_TMR_MASK; + int64_t nsec = (int64_t)ticks * TCO_TICK_NSEC; + + trace_tco_timer_reload(ticks, nsec / 1000000); + tr->expire_time = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + nsec; timer_mod(tr->tco_timer, tr->expire_time); } @@ -59,6 +63,9 @@ static void tco_timer_expired(void *opaque) ICH9LPCState *lpc = container_of(pm, ICH9LPCState, pm); uint32_t gcs = pci_get_long(lpc->chip_config + ICH9_CC_GCS); + trace_tco_timer_expired(tr->timeouts_no, + lpc->pin_strap.spkr_hi, + !!(gcs & ICH9_CC_GCS_NO_REBOOT)); tr->tco.rld = 0; tr->tco.sts1 |= TCO_TIMEOUT; if (++tr->timeouts_no == 2) { diff --git a/hw/acpi/trace-events b/hw/acpi/trace-events index e3b41e9df4..df0024f8b2 100644 --- a/hw/acpi/trace-events +++ b/hw/acpi/trace-events @@ -30,3 +30,7 @@ cpuhp_acpi_ejecting_invalid_cpu(uint32_t idx) "0x%"PRIx32 cpuhp_acpi_ejecting_cpu(uint32_t idx) "0x%"PRIx32 cpuhp_acpi_write_ost_ev(uint32_t slot, uint32_t ev) "idx[0x%"PRIx32"] OST EVENT: 0x%"PRIx32 cpuhp_acpi_write_ost_status(uint32_t slot, uint32_t st) "idx[0x%"PRIx32"] OST STATUS: 0x%"PRIx32 + +# hw/acpi/tco.c +tco_timer_reload(int ticks, int msec) "ticks=%d (%d ms)" +tco_timer_expired(int timeouts_no, bool strap, bool no_reboot) "timeouts_no=%d no_reboot=%d/%d" diff --git a/hw/core/qdev.c b/hw/core/qdev.c index 606ab53c42..11112951a5 100644 --- a/hw/core/qdev.c +++ b/hw/core/qdev.c @@ -928,6 +928,13 @@ static void device_set_realized(Object *obj, bool value, Error **errp) goto post_realize_fail; } + /* + * always free/re-initialize here since the value cannot be cleaned up + * in device_unrealize due to its usage later on in the unplug path + */ + g_free(dev->canonical_path); + dev->canonical_path = object_get_canonical_path(OBJECT(dev)); + if (qdev_get_vmsd(dev)) { if (vmstate_register_with_alias_id(dev, -1, qdev_get_vmsd(dev), dev, dev->instance_id_alias, @@ -984,6 +991,8 @@ child_realize_fail: } post_realize_fail: + g_free(dev->canonical_path); + dev->canonical_path = NULL; if (dc->unrealize) { dc->unrealize(dev, NULL); } @@ -1070,6 +1079,18 @@ static void device_finalize(Object *obj) * here */ } + + /* Only send event if the device had been completely realized */ + if (dev->pending_deleted_event) { + g_assert(dev->canonical_path); + + qapi_event_send_device_deleted(!!dev->id, dev->id, dev->canonical_path, + &error_abort); + g_free(dev->canonical_path); + dev->canonical_path = NULL; + } + + qemu_opts_del(dev->opts); } static void device_class_base_init(ObjectClass *class, void *data) @@ -1099,17 +1120,6 @@ static void device_unparent(Object *obj) object_unref(OBJECT(dev->parent_bus)); dev->parent_bus = NULL; } - - /* Only send event if the device had been completely realized */ - if (dev->pending_deleted_event) { - gchar *path = object_get_canonical_path(OBJECT(dev)); - - qapi_event_send_device_deleted(!!dev->id, dev->id, path, &error_abort); - g_free(path); - } - - qemu_opts_del(dev->opts); - dev->opts = NULL; } static void device_class_init(ObjectClass *class, void *data) diff --git a/hw/display/cirrus_vga.c b/hw/display/cirrus_vga.c index b4d579857a..bc32bf1e39 100644 --- a/hw/display/cirrus_vga.c +++ b/hw/display/cirrus_vga.c @@ -2038,15 +2038,14 @@ static void cirrus_mem_writeb_mode4and5_8bpp(CirrusVGAState * s, unsigned val = mem_value; uint8_t *dst; - dst = s->vga.vram_ptr + (offset &= s->cirrus_addr_mask); for (x = 0; x < 8; x++) { + dst = s->vga.vram_ptr + ((offset + x) & s->cirrus_addr_mask); if (val & 0x80) { *dst = s->cirrus_shadow_gr1; } else if (mode == 5) { *dst = s->cirrus_shadow_gr0; } val <<= 1; - dst++; } memory_region_set_dirty(&s->vga.vram, offset, 8); } @@ -2060,8 +2059,8 @@ static void cirrus_mem_writeb_mode4and5_16bpp(CirrusVGAState * s, unsigned val = mem_value; uint8_t *dst; - dst = s->vga.vram_ptr + (offset &= s->cirrus_addr_mask); for (x = 0; x < 8; x++) { + dst = s->vga.vram_ptr + ((offset + 2 * x) & s->cirrus_addr_mask & ~1); if (val & 0x80) { *dst = s->cirrus_shadow_gr1; *(dst + 1) = s->vga.gr[0x11]; @@ -2070,7 +2069,6 @@ static void cirrus_mem_writeb_mode4and5_16bpp(CirrusVGAState * s, *(dst + 1) = s->vga.gr[0x10]; } val <<= 1; - dst += 2; } memory_region_set_dirty(&s->vga.vram, offset, 16); } diff --git a/hw/display/vga.c b/hw/display/vga.c index ed24ef7076..1d19f6bc48 100644 --- a/hw/display/vga.c +++ b/hw/display/vga.c @@ -1464,14 +1464,14 @@ static void vga_draw_graphic(VGACommonState *s, int full_update) { DisplaySurface *surface = qemu_console_surface(s->con); int y1, y, update, linesize, y_start, double_scan, mask, depth; - int width, height, shift_control, line_offset, bwidth, bits; - ram_addr_t page0, page1; + int width, height, shift_control, bwidth, bits; + ram_addr_t page0, page1, region_start, region_end; DirtyBitmapSnapshot *snap = NULL; int disp_width, multi_scan, multi_run; uint8_t *d; uint32_t v, addr1, addr; vga_draw_line_func *vga_draw_line = NULL; - bool share_surface; + bool share_surface, force_shadow = false; pixman_format_code_t format; #ifdef HOST_WORDS_BIGENDIAN bool byteswap = !s->big_endian_fb; @@ -1484,6 +1484,15 @@ static void vga_draw_graphic(VGACommonState *s, int full_update) s->get_resolution(s, &width, &height); disp_width = width; + region_start = (s->start_addr * 4); + region_end = region_start + (ram_addr_t)s->line_offset * height; + if (region_end > s->vbe_size) { + /* wraps around (can happen with cirrus vbe modes) */ + region_start = 0; + region_end = s->vbe_size; + force_shadow = true; + } + shift_control = (s->gr[VGA_GFX_MODE] >> 5) & 3; double_scan = (s->cr[VGA_CRTC_MAX_SCAN] >> 7); if (shift_control != 1) { @@ -1523,7 +1532,7 @@ static void vga_draw_graphic(VGACommonState *s, int full_update) format = qemu_default_pixman_format(depth, !byteswap); if (format) { share_surface = dpy_gfx_check_format(s->con, format) - && !s->force_shadow; + && !s->force_shadow && !force_shadow; } else { share_surface = false; } @@ -1614,7 +1623,6 @@ static void vga_draw_graphic(VGACommonState *s, int full_update) s->cursor_invalidate(s); } - line_offset = s->line_offset; #if 0 printf("w=%d h=%d v=%d line_offset=%d cr[0x09]=0x%02x cr[0x17]=0x%02x linecmp=%d sr[0x01]=0x%02x\n", width, height, v, line_offset, s->cr[9], s->cr[VGA_CRTC_MODE], @@ -1628,8 +1636,6 @@ static void vga_draw_graphic(VGACommonState *s, int full_update) y1 = 0; if (!full_update) { - ram_addr_t region_start = addr1; - ram_addr_t region_end = addr1 + line_offset * height; vga_sync_dirty_bitmap(s); if (s->line_compare < height) { /* split screen mode */ @@ -1652,10 +1658,17 @@ static void vga_draw_graphic(VGACommonState *s, int full_update) addr = (addr & ~0x8000) | ((y1 & 2) << 14); } update = full_update; - page0 = addr; - page1 = addr + bwidth - 1; + page0 = addr & s->vbe_size_mask; + page1 = (addr + bwidth - 1) & s->vbe_size_mask; if (full_update) { update = 1; + } else if (page1 < page0) { + /* scanline wraps from end of video memory to the start */ + assert(force_shadow); + update = memory_region_snapshot_get_dirty(&s->vram, snap, + page0, 0); + update |= memory_region_snapshot_get_dirty(&s->vram, snap, + page1, 0); } else { update = memory_region_snapshot_get_dirty(&s->vram, snap, page0, page1 - page0); @@ -1681,7 +1694,7 @@ static void vga_draw_graphic(VGACommonState *s, int full_update) if (!multi_run) { mask = (s->cr[VGA_CRTC_MODE] & 3) ^ 3; if ((y1 & mask) == mask) - addr1 += line_offset; + addr1 += s->line_offset; y1++; multi_run = multi_scan; } else { diff --git a/hw/i386/pc.c b/hw/i386/pc.c index 05985d4927..8e307f7aff 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -1876,8 +1876,15 @@ static void pc_cpu_pre_plug(HotplugHandler *hotplug_dev, CPUArchId *cpu_slot; X86CPUTopoInfo topo; X86CPU *cpu = X86_CPU(dev); + MachineState *ms = MACHINE(hotplug_dev); PCMachineState *pcms = PC_MACHINE(hotplug_dev); + if(!object_dynamic_cast(OBJECT(cpu), ms->cpu_type)) { + error_setg(errp, "Invalid CPU type, expected cpu type: '%s'", + ms->cpu_type); + return; + } + /* if APIC ID is not set, set it based on socket/core/thread properties */ if (cpu->apic_id == UNASSIGNED_APIC_ID) { int max_socket = (max_cpus - 1) / smp_threads / smp_cores; diff --git a/hw/ide/core.c b/hw/ide/core.c index 5f1cd3b91f..a04766aee7 100644 --- a/hw/ide/core.c +++ b/hw/ide/core.c @@ -208,6 +208,7 @@ static void ide_identify(IDEState *s) if (dev && dev->conf.discard_granularity) { put_le16(p + 169, 1); /* TRIM support */ } + put_le16(p + 217, dev->rotation_rate); /* Nominal media rotation rate */ ide_identify_size(s); s->identify_set = 1; diff --git a/hw/ide/qdev.c b/hw/ide/qdev.c index d60ac25be0..a5181b4448 100644 --- a/hw/ide/qdev.c +++ b/hw/ide/qdev.c @@ -299,6 +299,7 @@ static Property ide_hd_properties[] = { DEFINE_BLOCK_CHS_PROPERTIES(IDEDrive, dev.conf), DEFINE_PROP_BIOS_CHS_TRANS("bios-chs-trans", IDEDrive, dev.chs_trans, BIOS_ATA_TRANSLATION_AUTO), + DEFINE_PROP_UINT16("rotation_rate", IDEDrive, dev.rotation_rate, 0), DEFINE_PROP_END_OF_LIST(), }; diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c index 6e841fb5ff..12431177a7 100644 --- a/hw/scsi/scsi-disk.c +++ b/hw/scsi/scsi-disk.c @@ -104,6 +104,14 @@ typedef struct SCSIDiskState char *product; bool tray_open; bool tray_locked; + /* + * 0x0000 - rotation rate not reported + * 0x0001 - non-rotating medium (SSD) + * 0x0002-0x0400 - reserved + * 0x0401-0xffe - rotations per minute + * 0xffff - reserved + */ + uint16_t rotation_rate; } SCSIDiskState; static bool scsi_handle_rw_error(SCSIDiskReq *r, int error, bool acct_failed); @@ -605,6 +613,7 @@ static int scsi_disk_emulate_inquiry(SCSIRequest *req, uint8_t *outbuf) outbuf[buflen++] = 0x83; // device identification if (s->qdev.type == TYPE_DISK) { outbuf[buflen++] = 0xb0; // block limits + outbuf[buflen++] = 0xb1; /* block device characteristics */ outbuf[buflen++] = 0xb2; // thin provisioning } break; @@ -747,6 +756,15 @@ static int scsi_disk_emulate_inquiry(SCSIRequest *req, uint8_t *outbuf) outbuf[43] = max_io_sectors & 0xff; break; } + case 0xb1: /* block device characteristics */ + { + buflen = 8; + outbuf[4] = (s->rotation_rate >> 8) & 0xff; + outbuf[5] = s->rotation_rate & 0xff; + outbuf[6] = 0; + outbuf[7] = 0; + break; + } case 0xb2: /* thin provisioning */ { buflen = 8; @@ -2329,6 +2347,14 @@ static void scsi_realize(SCSIDevice *dev, Error **errp) blkconf_serial(&s->qdev.conf, &s->serial); blkconf_blocksizes(&s->qdev.conf); + + if (s->qdev.conf.logical_block_size > + s->qdev.conf.physical_block_size) { + error_setg(errp, + "logical_block_size > physical_block_size not supported"); + return; + } + if (dev->type == TYPE_DISK) { blkconf_geometry(&dev->conf, NULL, 65535, 255, 255, &err); if (err) { @@ -2911,6 +2937,7 @@ static Property scsi_hd_properties[] = { DEFAULT_MAX_UNMAP_SIZE), DEFINE_PROP_UINT64("max_io_size", SCSIDiskState, max_io_size, DEFAULT_MAX_IO_SIZE), + DEFINE_PROP_UINT16("rotation_rate", SCSIDiskState, rotation_rate, 0), DEFINE_BLOCK_CHS_PROPERTIES(SCSIDiskState, qdev.conf), DEFINE_PROP_END_OF_LIST(), }; @@ -2982,6 +3009,7 @@ static const TypeInfo scsi_cd_info = { static Property scsi_block_properties[] = { DEFINE_BLOCK_ERROR_PROPERTIES(SCSIDiskState, qdev.conf), \ DEFINE_PROP_DRIVE("drive", SCSIDiskState, qdev.conf.blk), + DEFINE_PROP_UINT16("rotation_rate", SCSIDiskState, rotation_rate, 0), DEFINE_PROP_END_OF_LIST(), }; |