diff options
Diffstat (limited to 'include')
34 files changed, 932 insertions, 74 deletions
diff --git a/include/block/block-copy.h b/include/block/block-copy.h index e2e135ff1b..0a161724d7 100644 --- a/include/block/block-copy.h +++ b/include/block/block-copy.h @@ -16,6 +16,7 @@ #define BLOCK_COPY_H #include "block/block.h" +#include "qemu/co-shared-resource.h" typedef struct BlockCopyInFlightReq { int64_t start_byte; @@ -37,7 +38,7 @@ typedef struct BlockCopyState { BdrvDirtyBitmap *copy_bitmap; int64_t cluster_size; bool use_copy_range; - int64_t copy_range_size; + int64_t copy_size; uint64_t len; QLIST_HEAD(, BlockCopyInFlightReq) inflight_reqs; @@ -69,6 +70,8 @@ typedef struct BlockCopyState { */ ProgressResetCallbackFunc progress_reset_callback; void *progress_opaque; + + SharedResource *mem; } BlockCopyState; BlockCopyState *block_copy_state_new(BdrvChild *source, BdrvChild *target, diff --git a/include/block/block.h b/include/block/block.h index 89606bd9f8..1df9848e74 100644 --- a/include/block/block.h +++ b/include/block/block.h @@ -346,10 +346,10 @@ BlockDriverState *bdrv_find_backing_image(BlockDriverState *bs, const char *backing_file); void bdrv_refresh_filename(BlockDriverState *bs); -int coroutine_fn bdrv_co_truncate(BdrvChild *child, int64_t offset, +int coroutine_fn bdrv_co_truncate(BdrvChild *child, int64_t offset, bool exact, PreallocMode prealloc, Error **errp); -int bdrv_truncate(BdrvChild *child, int64_t offset, PreallocMode prealloc, - Error **errp); +int bdrv_truncate(BdrvChild *child, int64_t offset, bool exact, + PreallocMode prealloc, Error **errp); int64_t bdrv_nb_sectors(BlockDriverState *bs); int64_t bdrv_getlength(BlockDriverState *bs); diff --git a/include/block/block_int.h b/include/block/block_int.h index ca4ccac4c1..02dc0034a2 100644 --- a/include/block/block_int.h +++ b/include/block/block_int.h @@ -334,8 +334,23 @@ struct BlockDriver { * bdrv_parse_filename. */ const char *protocol_name; + + /* + * Truncate @bs to @offset bytes using the given @prealloc mode + * when growing. Modes other than PREALLOC_MODE_OFF should be + * rejected when shrinking @bs. + * + * If @exact is true, @bs must be resized to exactly @offset. + * Otherwise, it is sufficient for @bs (if it is a host block + * device and thus there is no way to resize it) to be at least + * @offset bytes in length. + * + * If @exact is true and this function fails but would succeed + * with @exact = false, it should return -ENOTSUP. + */ int coroutine_fn (*bdrv_co_truncate)(BlockDriverState *bs, int64_t offset, - PreallocMode prealloc, Error **errp); + bool exact, PreallocMode prealloc, + Error **errp); int64_t (*bdrv_getlength)(BlockDriverState *bs); bool has_variable_length; diff --git a/include/block/nvme.h b/include/block/nvme.h index 3ec8efcc43..ab5943b90a 100644 --- a/include/block/nvme.h +++ b/include/block/nvme.h @@ -653,12 +653,29 @@ typedef struct NvmeIdNs { uint8_t mc; uint8_t dpc; uint8_t dps; - uint8_t res30[98]; + + uint8_t nmic; + uint8_t rescap; + uint8_t fpi; + uint8_t dlfeat; + + uint8_t res34[94]; NvmeLBAF lbaf[16]; uint8_t res192[192]; uint8_t vs[3712]; } NvmeIdNs; + +/*Deallocate Logical Block Features*/ +#define NVME_ID_NS_DLFEAT_GUARD_CRC(dlfeat) ((dlfeat) & 0x10) +#define NVME_ID_NS_DLFEAT_WRITE_ZEROES(dlfeat) ((dlfeat) & 0x08) + +#define NVME_ID_NS_DLFEAT_READ_BEHAVIOR(dlfeat) ((dlfeat) & 0x7) +#define NVME_ID_NS_DLFEAT_READ_BEHAVIOR_UNDEFINED 0 +#define NVME_ID_NS_DLFEAT_READ_BEHAVIOR_ZEROES 1 +#define NVME_ID_NS_DLFEAT_READ_BEHAVIOR_ONES 2 + + #define NVME_ID_NS_NSFEAT_THIN(nsfeat) ((nsfeat & 0x1)) #define NVME_ID_NS_FLBAS_EXTENDED(flbas) ((flbas >> 4) & 0x1) #define NVME_ID_NS_FLBAS_INDEX(flbas) ((flbas & 0xf)) diff --git a/include/exec/cpu-all.h b/include/exec/cpu-all.h index ad9ab85eb3..e96781a455 100644 --- a/include/exec/cpu-all.h +++ b/include/exec/cpu-all.h @@ -210,17 +210,31 @@ static inline void stl_phys_notdirty(AddressSpace *as, hwaddr addr, uint32_t val /* page related stuff */ #ifdef TARGET_PAGE_BITS_VARY -extern bool target_page_bits_decided; -extern int target_page_bits; -#define TARGET_PAGE_BITS ({ assert(target_page_bits_decided); \ - target_page_bits; }) +typedef struct { + bool decided; + int bits; + target_long mask; +} TargetPageBits; +#if defined(CONFIG_ATTRIBUTE_ALIAS) || !defined(IN_EXEC_VARY) +extern const TargetPageBits target_page; +#else +extern TargetPageBits target_page; +#endif +#ifdef CONFIG_DEBUG_TCG +#define TARGET_PAGE_BITS ({ assert(target_page.decided); target_page.bits; }) +#define TARGET_PAGE_MASK ({ assert(target_page.decided); target_page.mask; }) +#else +#define TARGET_PAGE_BITS target_page.bits +#define TARGET_PAGE_MASK target_page.mask +#endif +#define TARGET_PAGE_SIZE (-(int)TARGET_PAGE_MASK) #else #define TARGET_PAGE_BITS_MIN TARGET_PAGE_BITS +#define TARGET_PAGE_SIZE (1 << TARGET_PAGE_BITS) +#define TARGET_PAGE_MASK ((target_long)-1 << TARGET_PAGE_BITS) #endif -#define TARGET_PAGE_SIZE (1 << TARGET_PAGE_BITS) -#define TARGET_PAGE_MASK ~(TARGET_PAGE_SIZE - 1) -#define TARGET_PAGE_ALIGN(addr) (((addr) + TARGET_PAGE_SIZE - 1) & TARGET_PAGE_MASK) +#define TARGET_PAGE_ALIGN(addr) ROUND_UP((addr), TARGET_PAGE_SIZE) /* Using intptr_t ensures that qemu_*_page_mask is sign-extended even * when intptr_t is 32-bit and we are aligning a long long. @@ -228,9 +242,8 @@ extern int target_page_bits; extern uintptr_t qemu_host_page_size; extern intptr_t qemu_host_page_mask; -#define HOST_PAGE_ALIGN(addr) (((addr) + qemu_host_page_size - 1) & qemu_host_page_mask) -#define REAL_HOST_PAGE_ALIGN(addr) (((addr) + qemu_real_host_page_size - 1) & \ - qemu_real_host_page_mask) +#define HOST_PAGE_ALIGN(addr) ROUND_UP((addr), qemu_host_page_size) +#define REAL_HOST_PAGE_ALIGN(addr) ROUND_UP((addr), qemu_real_host_page_size) /* same as PROT_xxx */ #define PAGE_READ 0x0001 diff --git a/include/exec/cpu_ldst_template.h b/include/exec/cpu_ldst_template.h index af7e0b49f2..3d24ed9bd0 100644 --- a/include/exec/cpu_ldst_template.h +++ b/include/exec/cpu_ldst_template.h @@ -65,8 +65,8 @@ #ifdef SOFTMMU_CODE_ACCESS #define ADDR_READ addr_code #define MMUSUFFIX _cmmu -#define URETSUFFIX SUFFIX -#define SRETSUFFIX SUFFIX +#define URETSUFFIX USUFFIX +#define SRETSUFFIX glue(s, SUFFIX) #else #define ADDR_READ addr_read #define MMUSUFFIX _mmu diff --git a/include/exec/ram_addr.h b/include/exec/ram_addr.h index ad158bb247..bed0554f4d 100644 --- a/include/exec/ram_addr.h +++ b/include/exec/ram_addr.h @@ -373,7 +373,7 @@ static inline void cpu_physical_memory_set_dirty_lebitmap(unsigned long *bitmap, hwaddr addr; ram_addr_t ram_addr; unsigned long len = (pages + HOST_LONG_BITS - 1) / HOST_LONG_BITS; - unsigned long hpratio = getpagesize() / TARGET_PAGE_SIZE; + unsigned long hpratio = qemu_real_host_page_size / TARGET_PAGE_SIZE; unsigned long page = BIT_WORD(start >> TARGET_PAGE_BITS); /* start address is aligned at the start of a word? */ diff --git a/include/hw/block/swim.h b/include/hw/block/swim.h new file mode 100644 index 0000000000..6add3499d0 --- /dev/null +++ b/include/hw/block/swim.h @@ -0,0 +1,76 @@ +/* + * QEMU Macintosh floppy disk controller emulator (SWIM) + * + * Copyright (c) 2014-2018 Laurent Vivier <laurent@vivier.eu> + * + * This work is licensed under the terms of the GNU GPL, version 2. See + * the COPYING file in the top-level directory. + * + */ + +#ifndef SWIM_H +#define SWIM_H + +#include "qemu/osdep.h" +#include "hw/sysbus.h" + +#define SWIM_MAX_FD 2 + +typedef struct SWIMDrive SWIMDrive; +typedef struct SWIMBus SWIMBus; +typedef struct SWIMCtrl SWIMCtrl; + +#define TYPE_SWIM_DRIVE "swim-drive" +#define SWIM_DRIVE(obj) OBJECT_CHECK(SWIMDrive, (obj), TYPE_SWIM_DRIVE) + +struct SWIMDrive { + DeviceState qdev; + int32_t unit; + BlockConf conf; +}; + +#define TYPE_SWIM_BUS "swim-bus" +#define SWIM_BUS(obj) OBJECT_CHECK(SWIMBus, (obj), TYPE_SWIM_BUS) + +struct SWIMBus { + BusState bus; + struct SWIMCtrl *ctrl; +}; + +typedef struct FDrive { + SWIMCtrl *swimctrl; + BlockBackend *blk; + BlockConf *conf; +} FDrive; + +struct SWIMCtrl { + MemoryRegion iomem; + FDrive drives[SWIM_MAX_FD]; + int mode; + /* IWM mode */ + int iwm_switch; + uint16_t regs[8]; +#define IWM_PH0 0 +#define IWM_PH1 1 +#define IWM_PH2 2 +#define IWM_PH3 3 +#define IWM_MTR 4 +#define IWM_DRIVE 5 +#define IWM_Q6 6 +#define IWM_Q7 7 + uint8_t iwm_data; + uint8_t iwm_mode; + /* SWIM mode */ + uint8_t swim_phase; + uint8_t swim_mode; + SWIMBus bus; +}; + +#define TYPE_SWIM "swim" +#define SWIM(obj) OBJECT_CHECK(SWIM, (obj), TYPE_SWIM) + +typedef struct SWIM { + SysBusDevice parent_obj; + SWIMCtrl ctrl; +} SWIM; +#endif diff --git a/include/hw/display/macfb.h b/include/hw/display/macfb.h new file mode 100644 index 0000000000..26367ae2c4 --- /dev/null +++ b/include/hw/display/macfb.h @@ -0,0 +1,64 @@ +/* + * QEMU Motorola 680x0 Macintosh Video Card Emulation + * Copyright (c) 2012-2018 Laurent Vivier + * + * some parts from QEMU G364 framebuffer Emulator. + * Copyright (c) 2007-2011 Herve Poussineau + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + * + */ + +#ifndef MACFB_H +#define MACFB_H + +#include "qemu/osdep.h" +#include "exec/memory.h" +#include "ui/console.h" + +typedef struct MacfbState { + MemoryRegion mem_vram; + MemoryRegion mem_ctrl; + QemuConsole *con; + + uint8_t *vram; + uint32_t vram_bit_mask; + uint32_t palette_current; + uint8_t color_palette[256 * 3]; + uint32_t width, height; /* in pixels */ + uint8_t depth; +} MacfbState; + +#define TYPE_MACFB "sysbus-macfb" +#define MACFB(obj) \ + OBJECT_CHECK(MacfbSysBusState, (obj), TYPE_MACFB) + +typedef struct { + SysBusDevice busdev; + + MacfbState macfb; +} MacfbSysBusState; + +#define MACFB_NUBUS_DEVICE_CLASS(class) \ + OBJECT_CLASS_CHECK(MacfbNubusDeviceClass, (class), TYPE_NUBUS_MACFB) +#define MACFB_NUBUS_GET_CLASS(obj) \ + OBJECT_GET_CLASS(MacfbNubusDeviceClass, (obj), TYPE_NUBUS_MACFB) + +typedef struct MacfbNubusDeviceClass { + DeviceClass parent_class; + + DeviceRealize parent_realize; +} MacfbNubusDeviceClass; + +#define TYPE_NUBUS_MACFB "nubus-macfb" +#define NUBUS_MACFB(obj) \ + OBJECT_CHECK(MacfbNubusState, (obj), TYPE_NUBUS_MACFB) + +typedef struct { + NubusDevice busdev; + + MacfbState macfb; +} MacfbNubusState; + +#endif diff --git a/include/hw/i386/microvm.h b/include/hw/i386/microvm.h new file mode 100644 index 0000000000..ba68d1f22b --- /dev/null +++ b/include/hw/i386/microvm.h @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2018 Intel Corporation + * Copyright (c) 2019 Red Hat, Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2 or later, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef HW_I386_MICROVM_H +#define HW_I386_MICROVM_H + +#include "qemu-common.h" +#include "exec/hwaddr.h" +#include "qemu/notify.h" + +#include "hw/boards.h" +#include "hw/i386/x86.h" + +/* Platform virtio definitions */ +#define VIRTIO_MMIO_BASE 0xc0000000 +#define VIRTIO_IRQ_BASE 5 +#define VIRTIO_NUM_TRANSPORTS 8 +#define VIRTIO_CMDLINE_MAXLEN 64 + +/* Machine type options */ +#define MICROVM_MACHINE_PIT "pit" +#define MICROVM_MACHINE_PIC "pic" +#define MICROVM_MACHINE_RTC "rtc" +#define MICROVM_MACHINE_ISA_SERIAL "isa-serial" +#define MICROVM_MACHINE_OPTION_ROMS "x-option-roms" +#define MICROVM_MACHINE_AUTO_KERNEL_CMDLINE "auto-kernel-cmdline" + +typedef struct { + X86MachineClass parent; + HotplugHandler *(*orig_hotplug_handler)(MachineState *machine, + DeviceState *dev); +} MicrovmMachineClass; + +typedef struct { + X86MachineState parent; + + /* Machine type options */ + OnOffAuto pic; + OnOffAuto pit; + OnOffAuto rtc; + bool isa_serial; + bool option_roms; + bool auto_kernel_cmdline; + + /* Machine state */ + bool kernel_cmdline_fixed; +} MicrovmMachineState; + +#define TYPE_MICROVM_MACHINE MACHINE_TYPE_NAME("microvm") +#define MICROVM_MACHINE(obj) \ + OBJECT_CHECK(MicrovmMachineState, (obj), TYPE_MICROVM_MACHINE) +#define MICROVM_MACHINE_GET_CLASS(obj) \ + OBJECT_GET_CLASS(MicrovmMachineClass, obj, TYPE_MICROVM_MACHINE) +#define MICROVM_MACHINE_CLASS(class) \ + OBJECT_CLASS_CHECK(MicrovmMachineClass, class, TYPE_MICROVM_MACHINE) + +#endif diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h index 37bfd95113..f040a72095 100644 --- a/include/hw/i386/pc.h +++ b/include/hw/i386/pc.h @@ -8,6 +8,7 @@ #include "hw/block/flash.h" #include "net/net.h" #include "hw/i386/ioapic.h" +#include "hw/i386/x86.h" #include "qemu/range.h" #include "qemu/bitmap.h" @@ -27,7 +28,7 @@ */ struct PCMachineState { /*< private >*/ - MachineState parent_obj; + X86MachineState parent_obj; /* <public> */ @@ -36,16 +37,11 @@ struct PCMachineState { /* Pointers to devices and objects: */ HotplugHandler *acpi_dev; - ISADevice *rtc; PCIBus *bus; I2CBus *smbus; - FWCfgState *fw_cfg; - qemu_irq *gsi; PFlashCFI01 *flash[2]; - GMappedFile *initrd_mapped_file; /* Configuration options: */ - uint64_t max_ram_below_4g; OnOffAuto vmport; OnOffAuto smm; @@ -54,30 +50,16 @@ struct PCMachineState { bool sata_enabled; bool pit_enabled; - /* RAM information (sizes, addresses, configuration): */ - ram_addr_t below_4g_mem_size, above_4g_mem_size; - - /* CPU and apic information: */ - bool apic_xrupt_override; - unsigned apic_id_limit; - uint16_t boot_cpus; - unsigned smp_dies; - /* NUMA information: */ uint64_t numa_nodes; uint64_t *node_mem; - /* Address space used by IOAPIC device. All IOAPIC interrupts - * will be translated to MSI messages in the address space. */ - AddressSpace *ioapic_as; - /* ACPI Memory hotplug IO base address */ hwaddr memhp_io_base; }; #define PC_MACHINE_ACPI_DEVICE_PROP "acpi-device" #define PC_MACHINE_DEVMEM_REGION_SIZE "device-memory-region-size" -#define PC_MACHINE_MAX_RAM_BELOW_4G "max-ram-below-4g" #define PC_MACHINE_VMPORT "vmport" #define PC_MACHINE_SMM "smm" #define PC_MACHINE_SMBUS "smbus" @@ -102,7 +84,7 @@ struct PCMachineState { */ typedef struct PCMachineClass { /*< private >*/ - MachineClass parent_class; + X86MachineClass parent_class; /*< public >*/ @@ -144,9 +126,6 @@ typedef struct PCMachineClass { /* use PVH to load kernels that support this feature */ bool pvh_enabled; - - /* Enables contiguous-apic-ID mode */ - bool compat_apic_id_mode; } PCMachineClass; #define TYPE_PC_MACHINE "generic-pc-machine" @@ -178,6 +157,8 @@ typedef struct GSIState { void gsi_handler(void *opaque, int n, int level); +GSIState *pc_gsi_create(qemu_irq **irqs, bool pci_enabled); + /* vmport.c */ #define TYPE_VMPORT "vmport" typedef uint32_t (VMPortReadFunc)(void *opaque, uint32_t address); @@ -195,10 +176,8 @@ void vmmouse_set_data(const uint32_t *data); extern int fd_bootchk; bool pc_machine_is_smm_enabled(PCMachineState *pcms); -void pc_register_ferr_irq(qemu_irq irq); void pc_acpi_smi_interrupt(void *opaque, int irq, int level); -void pc_cpus_init(PCMachineState *pcms); void pc_hot_add_cpu(MachineState *ms, const int64_t id, Error **errp); void pc_smp_parse(MachineState *ms, QemuOpts *opts); @@ -239,6 +218,7 @@ void pc_pci_device_init(PCIBus *pci_bus); typedef void (*cpu_set_smm_t)(int smm, void *arg); +void pc_i8259_create(ISABus *isa_bus, qemu_irq *i8259_irqs); void ioapic_init_gsi(GSIState *gsi_state, const char *parent_name); ISADevice *pc_find_fdc0(void); diff --git a/include/hw/i386/x86.h b/include/hw/i386/x86.h new file mode 100644 index 0000000000..82d09fd7d0 --- /dev/null +++ b/include/hw/i386/x86.h @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2019 Red Hat, Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2 or later, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef HW_I386_X86_H +#define HW_I386_X86_H + +#include "qemu-common.h" +#include "exec/hwaddr.h" +#include "qemu/notify.h" + +#include "hw/boards.h" +#include "hw/nmi.h" + +typedef struct { + /*< private >*/ + MachineClass parent; + + /*< public >*/ + + /* Enables contiguous-apic-ID mode */ + bool compat_apic_id_mode; +} X86MachineClass; + +typedef struct { + /*< private >*/ + MachineState parent; + + /*< public >*/ + + /* Pointers to devices and objects: */ + ISADevice *rtc; + FWCfgState *fw_cfg; + qemu_irq *gsi; + GMappedFile *initrd_mapped_file; + + /* Configuration options: */ + uint64_t max_ram_below_4g; + + /* RAM information (sizes, addresses, configuration): */ + ram_addr_t below_4g_mem_size, above_4g_mem_size; + + /* CPU and apic information: */ + bool apic_xrupt_override; + unsigned apic_id_limit; + uint16_t boot_cpus; + unsigned smp_dies; + + /* + * Address space used by IOAPIC device. All IOAPIC interrupts + * will be translated to MSI messages in the address space. + */ + AddressSpace *ioapic_as; +} X86MachineState; + +#define X86_MACHINE_MAX_RAM_BELOW_4G "max-ram-below-4g" + +#define TYPE_X86_MACHINE MACHINE_TYPE_NAME("x86") +#define X86_MACHINE(obj) \ + OBJECT_CHECK(X86MachineState, (obj), TYPE_X86_MACHINE) +#define X86_MACHINE_GET_CLASS(obj) \ + OBJECT_GET_CLASS(X86MachineClass, obj, TYPE_X86_MACHINE) +#define X86_MACHINE_CLASS(class) \ + OBJECT_CLASS_CHECK(X86MachineClass, class, TYPE_X86_MACHINE) + +uint32_t x86_cpu_apic_id_from_index(X86MachineState *pcms, + unsigned int cpu_index); + +void x86_cpu_new(X86MachineState *pcms, int64_t apic_id, Error **errp); +void x86_cpus_init(X86MachineState *pcms, int default_cpu_version); +CpuInstanceProperties x86_cpu_index_to_props(MachineState *ms, + unsigned cpu_index); +int64_t x86_get_default_cpu_node_id(const MachineState *ms, int idx); +const CPUArchIdList *x86_possible_cpu_arch_ids(MachineState *ms); + +void x86_bios_rom_init(MemoryRegion *rom_memory, bool isapc_ram_fw); + +void x86_load_linux(X86MachineState *x86ms, + FWCfgState *fw_cfg, + int acpi_data_size, + bool pvh_enabled, + bool linuxboot_dma_enabled); + +#endif diff --git a/include/hw/misc/mac_via.h b/include/hw/misc/mac_via.h new file mode 100644 index 0000000000..3f86fcb7e1 --- /dev/null +++ b/include/hw/misc/mac_via.h @@ -0,0 +1,115 @@ +/* + * + * Copyright (c) 2011-2018 Laurent Vivier + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + */ + +#ifndef HW_MISC_MAC_VIA_H +#define HW_MISC_MAC_VIA_H + +#include "exec/memory.h" +#include "hw/sysbus.h" +#include "hw/misc/mos6522.h" + + +/* VIA 1 */ +#define VIA1_IRQ_ONE_SECOND_BIT 0 +#define VIA1_IRQ_VBLANK_BIT 1 +#define VIA1_IRQ_ADB_READY_BIT 2 +#define VIA1_IRQ_ADB_DATA_BIT 3 +#define VIA1_IRQ_ADB_CLOCK_BIT 4 + +#define VIA1_IRQ_NB 8 + +#define VIA1_IRQ_ONE_SECOND (1 << VIA1_IRQ_ONE_SECOND_BIT) +#define VIA1_IRQ_VBLANK (1 << VIA1_IRQ_VBLANK_BIT) +#define VIA1_IRQ_ADB_READY (1 << VIA1_IRQ_ADB_READY_BIT) +#define VIA1_IRQ_ADB_DATA (1 << VIA1_IRQ_ADB_DATA_BIT) +#define VIA1_IRQ_ADB_CLOCK (1 << VIA1_IRQ_ADB_CLOCK_BIT) + + +#define TYPE_MOS6522_Q800_VIA1 "mos6522-q800-via1" +#define MOS6522_Q800_VIA1(obj) OBJECT_CHECK(MOS6522Q800VIA1State, (obj), \ + TYPE_MOS6522_Q800_VIA1) + +typedef struct MOS6522Q800VIA1State { + /*< private >*/ + MOS6522State parent_obj; + + qemu_irq irqs[VIA1_IRQ_NB]; + uint8_t last_b; + uint8_t PRAM[256]; + + /* external timers */ + QEMUTimer *one_second_timer; + int64_t next_second; + QEMUTimer *VBL_timer; + int64_t next_VBL; +} MOS6522Q800VIA1State; + + +/* VIA 2 */ +#define VIA2_IRQ_SCSI_DATA_BIT 0 +#define VIA2_IRQ_SLOT_BIT 1 +#define VIA2_IRQ_UNUSED_BIT 2 +#define VIA2_IRQ_SCSI_BIT 3 +#define VIA2_IRQ_ASC_BIT 4 + +#define VIA2_IRQ_NB 8 + +#define VIA2_IRQ_SCSI_DATA (1 << VIA2_IRQ_SCSI_DATA_BIT) +#define VIA2_IRQ_SLOT (1 << VIA2_IRQ_SLOT_BIT) +#define VIA2_IRQ_UNUSED (1 << VIA2_IRQ_SCSI_BIT) +#define VIA2_IRQ_SCSI (1 << VIA2_IRQ_UNUSED_BIT) +#define VIA2_IRQ_ASC (1 << VIA2_IRQ_ASC_BIT) + +#define TYPE_MOS6522_Q800_VIA2 "mos6522-q800-via2" +#define MOS6522_Q800_VIA2(obj) OBJECT_CHECK(MOS6522Q800VIA2State, (obj), \ + TYPE_MOS6522_Q800_VIA2) + +typedef struct MOS6522Q800VIA2State { + /*< private >*/ + MOS6522State parent_obj; +} MOS6522Q800VIA2State; + + +#define TYPE_MAC_VIA "mac_via" +#define MAC_VIA(obj) OBJECT_CHECK(MacVIAState, (obj), TYPE_MAC_VIA) + +typedef struct MacVIAState { + SysBusDevice busdev; + + /* MMIO */ + MemoryRegion mmio; + MemoryRegion via1mem; + MemoryRegion via2mem; + + /* VIAs */ + MOS6522Q800VIA1State mos6522_via1; + MOS6522Q800VIA2State mos6522_via2; + + /* RTC */ + uint32_t tick_offset; + + uint8_t data_out; + int data_out_cnt; + uint8_t data_in; + uint8_t data_in_cnt; + uint8_t cmd; + int wprotect; + int alt; + + /* ADB */ + ADBBusState adb_bus; + QEMUTimer *adb_poll_timer; + qemu_irq adb_data_ready; + int adb_data_in_size; + int adb_data_in_index; + int adb_data_out_index; + uint8_t adb_data_in[128]; + uint8_t adb_data_out[16]; +} MacVIAState; + +#endif diff --git a/include/hw/nubus/mac-nubus-bridge.h b/include/hw/nubus/mac-nubus-bridge.h new file mode 100644 index 0000000000..ce9c789d99 --- /dev/null +++ b/include/hw/nubus/mac-nubus-bridge.h @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2013-2018 Laurent Vivier <laurent@vivier.eu> + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + * + */ + +#ifndef HW_NUBUS_MAC_H +#define HW_NUBUS_MAC_H + +#include "hw/nubus/nubus.h" + +#define TYPE_MAC_NUBUS_BRIDGE "mac-nubus-bridge" +#define MAC_NUBUS_BRIDGE(obj) OBJECT_CHECK(MacNubusState, (obj), \ + TYPE_MAC_NUBUS_BRIDGE) + +typedef struct MacNubusState { + SysBusDevice sysbus_dev; + + NubusBus *bus; +} MacNubusState; + +#endif diff --git a/include/hw/nubus/nubus.h b/include/hw/nubus/nubus.h new file mode 100644 index 0000000000..a8634e54c5 --- /dev/null +++ b/include/hw/nubus/nubus.h @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2013-2018 Laurent Vivier <laurent@vivier.eu> + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + * + */ + +#ifndef HW_NUBUS_NUBUS_H +#define HW_NUBUS_NUBUS_H + +#include "hw/qdev-properties.h" +#include "exec/address-spaces.h" + +#define NUBUS_SUPER_SLOT_SIZE 0x10000000U +#define NUBUS_SUPER_SLOT_NB 0x9 + +#define NUBUS_SLOT_SIZE 0x01000000 +#define NUBUS_SLOT_NB 0xF + +#define NUBUS_FIRST_SLOT 0x9 +#define NUBUS_LAST_SLOT 0xF + +#define TYPE_NUBUS_DEVICE "nubus-device" +#define NUBUS_DEVICE(obj) \ + OBJECT_CHECK(NubusDevice, (obj), TYPE_NUBUS_DEVICE) + +#define TYPE_NUBUS_BUS "nubus-bus" +#define NUBUS_BUS(obj) OBJECT_CHECK(NubusBus, (obj), TYPE_NUBUS_BUS) + +#define TYPE_NUBUS_BRIDGE "nubus-bridge" +#define NUBUS_BRIDGE(obj) OBJECT_CHECK(NubusBridge, (obj), TYPE_NUBUS_BRIDGE) + +typedef struct NubusBus { + BusState qbus; + + MemoryRegion super_slot_io; + MemoryRegion slot_io; + + int current_slot; +} NubusBus; + +typedef struct NubusDevice { + DeviceState qdev; + + int slot_nb; + MemoryRegion slot_mem; + + /* Format Block */ + + MemoryRegion fblock_io; + + uint32_t rom_length; + uint32_t rom_crc; + uint8_t rom_rev; + uint8_t rom_format; + uint8_t byte_lanes; + int32_t directory_offset; + + /* ROM */ + + MemoryRegion rom_io; + const uint8_t *rom; +} NubusDevice; + +void nubus_register_rom(NubusDevice *dev, const uint8_t *rom, uint32_t size, + int revision, int format, uint8_t byte_lanes); + +#endif diff --git a/include/hw/nvram/fw_cfg.h b/include/hw/nvram/fw_cfg.h index 80e435d303..b5291eefad 100644 --- a/include/hw/nvram/fw_cfg.h +++ b/include/hw/nvram/fw_cfg.h @@ -99,6 +99,20 @@ void fw_cfg_add_bytes(FWCfgState *s, uint16_t key, void *data, size_t len); void fw_cfg_add_string(FWCfgState *s, uint16_t key, const char *value); /** + * fw_cfg_modify_string: + * @s: fw_cfg device being modified + * @key: selector key value for new fw_cfg item + * @value: NUL-terminated ascii string + * + * Replace the fw_cfg item available by selecting the given key. The new + * data will consist of a dynamically allocated copy of the provided string, + * including its NUL terminator. The data being replaced, assumed to have + * been dynamically allocated during an earlier call to either + * fw_cfg_add_string() or fw_cfg_modify_string(), is freed before returning. + */ +void fw_cfg_modify_string(FWCfgState *s, uint16_t key, const char *value); + +/** * fw_cfg_add_i16: * @s: fw_cfg device being modified * @key: selector key value for new fw_cfg item @@ -137,6 +151,20 @@ void fw_cfg_modify_i16(FWCfgState *s, uint16_t key, uint16_t value); void fw_cfg_add_i32(FWCfgState *s, uint16_t key, uint32_t value); /** + * fw_cfg_modify_i32: + * @s: fw_cfg device being modified + * @key: selector key value for new fw_cfg item + * @value: 32-bit integer + * + * Replace the fw_cfg item available by selecting the given key. The new + * data will consist of a dynamically allocated copy of the given 32-bit + * value, converted to little-endian representation. The data being replaced, + * assumed to have been dynamically allocated during an earlier call to + * either fw_cfg_add_i32() or fw_cfg_modify_i32(), is freed before returning. + */ +void fw_cfg_modify_i32(FWCfgState *s, uint16_t key, uint32_t value); + +/** * fw_cfg_add_i64: * @s: fw_cfg device being modified * @key: selector key value for new fw_cfg item @@ -149,6 +177,20 @@ void fw_cfg_add_i32(FWCfgState *s, uint16_t key, uint32_t value); void fw_cfg_add_i64(FWCfgState *s, uint16_t key, uint64_t value); /** + * fw_cfg_modify_i64: + * @s: fw_cfg device being modified + * @key: selector key value for new fw_cfg item + * @value: 64-bit integer + * + * Replace the fw_cfg item available by selecting the given key. The new + * data will consist of a dynamically allocated copy of the given 64-bit + * value, converted to little-endian representation. The data being replaced, + * assumed to have been dynamically allocated during an earlier call to + * either fw_cfg_add_i64() or fw_cfg_modify_i64(), is freed before returning. + */ +void fw_cfg_modify_i64(FWCfgState *s, uint16_t key, uint64_t value); + +/** * fw_cfg_add_file: * @s: fw_cfg device being modified * @filename: name of new fw_cfg file item diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h index f3f0ffd5fb..db75c6dfd0 100644 --- a/include/hw/pci/pci.h +++ b/include/hw/pci/pci.h @@ -265,6 +265,7 @@ typedef struct PCIReqIDCache PCIReqIDCache; struct PCIDevice { DeviceState qdev; + bool partially_hotplugged; /* PCI config space */ uint8_t *config; @@ -352,6 +353,9 @@ struct PCIDevice { MSIVectorUseNotifier msix_vector_use_notifier; MSIVectorReleaseNotifier msix_vector_release_notifier; MSIVectorPollNotifier msix_vector_poll_notifier; + + /* ID of standby device in net_failover pair */ + char *failover_pair_id; }; void pci_register_bar(PCIDevice *pci_dev, int region_num, diff --git a/include/hw/pci/pci_ids.h b/include/hw/pci/pci_ids.h index 0abe27a53a..11f8ab7149 100644 --- a/include/hw/pci/pci_ids.h +++ b/include/hw/pci/pci_ids.h @@ -164,6 +164,7 @@ #define PCI_DEVICE_ID_LSI_SAS0079 0x0079 #define PCI_VENDOR_ID_DEC 0x1011 +#define PCI_DEVICE_ID_DEC_21143 0x0019 #define PCI_DEVICE_ID_DEC_21154 0x0026 #define PCI_VENDOR_ID_CIRRUS 0x1013 diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h index aa123f88cb..1518495b1e 100644 --- a/include/hw/qdev-core.h +++ b/include/hw/qdev-core.h @@ -78,6 +78,19 @@ typedef void (*BusUnrealize)(BusState *bus, Error **errp); * respective parent types. * </para> * </note> + * + * # Hiding a device # + * To hide a device, a DeviceListener function should_be_hidden() needs to + * be registered. + * It can be used to defer adding a device and therefore hide it from the + * guest. The handler registering to this DeviceListener can save the QOpts + * passed to it for re-using it later and must return that it wants the device + * to be/remain hidden or not. When the handler function decides the device + * shall not be hidden it will be added in qdev_device_add() and + * realized as any other device. Otherwise qdev_device_add() will return early + * without adding the device. The guest will not see a "hidden" device + * until it was marked don't hide and qdev_device_add called again. + * */ typedef struct DeviceClass { /*< private >*/ @@ -143,6 +156,7 @@ struct DeviceState { bool pending_deleted_event; QemuOpts *opts; int hotplugged; + bool allow_unplug_during_migration; BusState *parent_bus; QLIST_HEAD(, NamedGPIOList) gpios; QLIST_HEAD(, BusState) child_bus; @@ -154,6 +168,12 @@ struct DeviceState { struct DeviceListener { void (*realize)(DeviceListener *listener, DeviceState *dev); void (*unrealize)(DeviceListener *listener, DeviceState *dev); + /* + * This callback is called upon init of the DeviceState and allows to + * inform qdev that a device should be hidden, depending on the device + * opts, for example, to hide a standby device. + */ + int (*should_be_hidden)(DeviceListener *listener, QemuOpts *device_opts); QTAILQ_ENTRY(DeviceListener) link; }; @@ -451,4 +471,14 @@ static inline bool qbus_is_hotpluggable(BusState *bus) void device_listener_register(DeviceListener *listener); void device_listener_unregister(DeviceListener *listener); +/** + * @qdev_should_hide_device: + * @opts: QemuOpts as passed on cmdline. + * + * Check if a device should be added. + * When a device is added via qdev_device_add() this will be called, + * and return if the device should be added now or not. + */ +bool qdev_should_hide_device(QemuOpts *opts); + #endif diff --git a/include/hw/riscv/sifive_u.h b/include/hw/riscv/sifive_u.h index e4df298c23..82667b5746 100644 --- a/include/hw/riscv/sifive_u.h +++ b/include/hw/riscv/sifive_u.h @@ -44,25 +44,34 @@ typedef struct SiFiveUSoCState { CadenceGEMState gem; } SiFiveUSoCState; +#define TYPE_RISCV_U_MACHINE MACHINE_TYPE_NAME("sifive_u") +#define RISCV_U_MACHINE(obj) \ + OBJECT_CHECK(SiFiveUState, (obj), TYPE_RISCV_U_MACHINE) + typedef struct SiFiveUState { /*< private >*/ - SysBusDevice parent_obj; + MachineState parent_obj; /*< public >*/ SiFiveUSoCState soc; + void *fdt; int fdt_size; + + bool start_in_flash; } SiFiveUState; enum { SIFIVE_U_DEBUG, SIFIVE_U_MROM, SIFIVE_U_CLINT, + SIFIVE_U_L2LIM, SIFIVE_U_PLIC, SIFIVE_U_PRCI, SIFIVE_U_UART0, SIFIVE_U_UART1, SIFIVE_U_OTP, + SIFIVE_U_FLASH0, SIFIVE_U_DRAM, SIFIVE_U_GEM, SIFIVE_U_GEM_MGMT @@ -75,7 +84,6 @@ enum { }; enum { - SIFIVE_U_CLOCK_FREQ = 1000000000, SIFIVE_U_HFCLK_FREQ = 33333333, SIFIVE_U_RTCCLK_FREQ = 1000000 }; diff --git a/include/hw/riscv/spike.h b/include/hw/riscv/spike.h index 03d870363c..dc770421bc 100644 --- a/include/hw/riscv/spike.h +++ b/include/hw/riscv/spike.h @@ -38,10 +38,6 @@ enum { SPIKE_DRAM }; -enum { - SPIKE_CLOCK_FREQ = 1000000000 -}; - #if defined(TARGET_RISCV32) #define SPIKE_V1_09_1_CPU TYPE_RISCV_CPU_RV32GCSU_V1_09_1 #define SPIKE_V1_10_0_CPU TYPE_RISCV_CPU_RV32GCSU_V1_10_0 diff --git a/include/hw/riscv/virt.h b/include/hw/riscv/virt.h index 6e5fbe5d3b..b17048a93a 100644 --- a/include/hw/riscv/virt.h +++ b/include/hw/riscv/virt.h @@ -21,14 +21,21 @@ #include "hw/riscv/riscv_hart.h" #include "hw/sysbus.h" +#include "hw/block/flash.h" + +#define TYPE_RISCV_VIRT_MACHINE MACHINE_TYPE_NAME("virt") +#define RISCV_VIRT_MACHINE(obj) \ + OBJECT_CHECK(RISCVVirtState, (obj), TYPE_RISCV_VIRT_MACHINE) typedef struct { /*< private >*/ - SysBusDevice parent_obj; + MachineState parent; /*< public >*/ RISCVHartArrayState soc; DeviceState *plic; + PFlashCFI01 *flash[2]; + void *fdt; int fdt_size; } RISCVVirtState; @@ -41,6 +48,7 @@ enum { VIRT_PLIC, VIRT_UART0, VIRT_VIRTIO, + VIRT_FLASH, VIRT_DRAM, VIRT_PCIE_MMIO, VIRT_PCIE_PIO, @@ -55,10 +63,6 @@ enum { VIRTIO_NDEV = 0x35 /* Arbitrary maximum number of interrupts */ }; -enum { - VIRT_CLOCK_FREQ = 1000000000 -}; - #define VIRT_PLIC_HART_CONFIG "MS" #define VIRT_PLIC_NUM_SOURCES 127 #define VIRT_PLIC_NUM_PRIORITIES 7 diff --git a/include/hw/rtc/mc146818rtc.h b/include/hw/rtc/mc146818rtc.h index 7fa59d4279..10c93a096a 100644 --- a/include/hw/rtc/mc146818rtc.h +++ b/include/hw/rtc/mc146818rtc.h @@ -9,9 +9,44 @@ #ifndef HW_RTC_MC146818RTC_H #define HW_RTC_MC146818RTC_H +#include "qapi/qapi-types-misc.h" +#include "qemu/queue.h" +#include "qemu/timer.h" #include "hw/isa/isa.h" #define TYPE_MC146818_RTC "mc146818rtc" +#define MC146818_RTC(obj) OBJECT_CHECK(RTCState, (obj), TYPE_MC146818_RTC) + +typedef struct RTCState { + ISADevice parent_obj; + + MemoryRegion io; + MemoryRegion coalesced_io; + uint8_t cmos_data[128]; + uint8_t cmos_index; + int32_t base_year; + uint64_t base_rtc; + uint64_t last_update; + int64_t offset; + qemu_irq irq; + int it_shift; + /* periodic timer */ + QEMUTimer *periodic_timer; + int64_t next_periodic_time; + /* update-ended timer */ + QEMUTimer *update_timer; + uint64_t next_alarm_time; + uint16_t irq_reinject_on_ack_count; + uint32_t irq_coalesced; + uint32_t period; + QEMUTimer *coalesced_timer; + Notifier clock_reset_notifier; + LostTickPolicy lost_tick_policy; + Notifier suspend_notifier; + QLIST_ENTRY(RTCState) link; +} RTCState; + +#define RTC_ISA_IRQ 8 ISADevice *mc146818_rtc_init(ISABus *bus, int base_year, qemu_irq intercept_irq); diff --git a/include/hw/rtc/mc146818rtc_regs.h b/include/hw/rtc/mc146818rtc_regs.h index dd6c09e2fc..12197e0553 100644 --- a/include/hw/rtc/mc146818rtc_regs.h +++ b/include/hw/rtc/mc146818rtc_regs.h @@ -28,8 +28,6 @@ #include "qemu/timer.h" #include "qemu/host-utils.h" -#define RTC_ISA_IRQ 8 - #define RTC_SECONDS 0 #define RTC_SECONDS_ALARM 1 #define RTC_MINUTES 2 diff --git a/include/hw/scsi/esp.h b/include/hw/scsi/esp.h index adab63d1c9..6ba47dac41 100644 --- a/include/hw/scsi/esp.h +++ b/include/hw/scsi/esp.h @@ -14,10 +14,18 @@ typedef void (*ESPDMAMemoryReadWriteFunc)(void *opaque, uint8_t *buf, int len); typedef struct ESPState ESPState; +enum pdma_origin_id { + PDMA, + TI, + CMD, + ASYNC, +}; + struct ESPState { uint8_t rregs[ESP_REGS]; uint8_t wregs[ESP_REGS]; qemu_irq irq; + qemu_irq irq_data; uint8_t chip_id; bool tchi_written; int32_t ti_size; @@ -48,6 +56,12 @@ struct ESPState { ESPDMAMemoryReadWriteFunc dma_memory_write; void *dma_opaque; void (*dma_cb)(ESPState *s); + uint8_t pdma_buf[32]; + int pdma_origin; + uint32_t pdma_len; + uint32_t pdma_start; + uint32_t pdma_cur; + void (*pdma_cb)(ESPState *s); }; #define TYPE_ESP "esp" @@ -59,6 +73,7 @@ typedef struct { /*< public >*/ MemoryRegion iomem; + MemoryRegion pdma; uint32_t it_shift; ESPState esp; } SysBusESPState; diff --git a/include/hw/virtio/virtio-mmio.h b/include/hw/virtio/virtio-mmio.h new file mode 100644 index 0000000000..7dbfd03dcf --- /dev/null +++ b/include/hw/virtio/virtio-mmio.h @@ -0,0 +1,73 @@ +/* + * Virtio MMIO bindings + * + * Copyright (c) 2011 Linaro Limited + * + * Author: + * Peter Maydell <peter.maydell@linaro.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef HW_VIRTIO_MMIO_H +#define HW_VIRTIO_MMIO_H + +#include "hw/virtio/virtio-bus.h" + +/* QOM macros */ +/* virtio-mmio-bus */ +#define TYPE_VIRTIO_MMIO_BUS "virtio-mmio-bus" +#define VIRTIO_MMIO_BUS(obj) \ + OBJECT_CHECK(VirtioBusState, (obj), TYPE_VIRTIO_MMIO_BUS) +#define VIRTIO_MMIO_BUS_GET_CLASS(obj) \ + OBJECT_GET_CLASS(VirtioBusClass, (obj), TYPE_VIRTIO_MMIO_BUS) +#define VIRTIO_MMIO_BUS_CLASS(klass) \ + OBJECT_CLASS_CHECK(VirtioBusClass, (klass), TYPE_VIRTIO_MMIO_BUS) + +/* virtio-mmio */ +#define TYPE_VIRTIO_MMIO "virtio-mmio" +#define VIRTIO_MMIO(obj) \ + OBJECT_CHECK(VirtIOMMIOProxy, (obj), TYPE_VIRTIO_MMIO) + +#define VIRT_MAGIC 0x74726976 /* 'virt' */ +#define VIRT_VERSION 2 +#define VIRT_VERSION_LEGACY 1 +#define VIRT_VENDOR 0x554D4551 /* 'QEMU' */ + +typedef struct VirtIOMMIOQueue { + uint16_t num; + bool enabled; + uint32_t desc[2]; + uint32_t avail[2]; + uint32_t used[2]; +} VirtIOMMIOQueue; + +typedef struct { + /* Generic */ + SysBusDevice parent_obj; + MemoryRegion iomem; + qemu_irq irq; + bool legacy; + /* Guest accessible state needing migration and reset */ + uint32_t host_features_sel; + uint32_t guest_features_sel; + uint32_t guest_page_shift; + /* virtio-bus */ + VirtioBusState bus; + bool format_transport_address; + /* Fields only used for non-legacy (v2) devices */ + uint32_t guest_features[2]; + VirtIOMMIOQueue vqs[VIRTIO_QUEUE_MAX]; +} VirtIOMMIOProxy; + +#endif diff --git a/include/hw/virtio/virtio-net.h b/include/hw/virtio/virtio-net.h index b96f0c643f..96c68d4a92 100644 --- a/include/hw/virtio/virtio-net.h +++ b/include/hw/virtio/virtio-net.h @@ -18,6 +18,7 @@ #include "standard-headers/linux/virtio_net.h" #include "hw/virtio/virtio.h" #include "net/announce.h" +#include "qemu/option_int.h" #define TYPE_VIRTIO_NET "virtio-net-device" #define VIRTIO_NET(obj) \ @@ -43,6 +44,7 @@ typedef struct virtio_net_conf int32_t speed; char *duplex_str; uint8_t duplex; + char *primary_id_str; } virtio_net_conf; /* Coalesced packets type & status */ @@ -182,9 +184,21 @@ struct VirtIONet { char *netclient_name; char *netclient_type; uint64_t curr_guest_offloads; + /* used on saved state restore phase to preserve the curr_guest_offloads */ + uint64_t saved_guest_offloads; AnnounceTimer announce_timer; bool needs_vnet_hdr_swap; bool mtu_bypass_backend; + QemuOpts *primary_device_opts; + QDict *primary_device_dict; + DeviceState *primary_dev; + BusState *primary_bus; + char *primary_device_id; + char *standby_id; + bool primary_should_be_hidden; + bool failover; + DeviceListener primary_listener; + Notifier migration_state; }; void virtio_net_set_netclient_name(VirtIONet *n, const char *name, diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h index 48e8d04ff6..3448d67d2a 100644 --- a/include/hw/virtio/virtio.h +++ b/include/hw/virtio/virtio.h @@ -37,13 +37,6 @@ static inline hwaddr vring_align(hwaddr addr, return QEMU_ALIGN_UP(addr, align); } -/* - * Calculate the number of bytes up to and including the given 'field' of - * 'container'. - */ -#define virtio_endof(container, field) \ - (offsetof(container, field) + sizeof_field(container, field)) - typedef struct VirtIOFeature { uint64_t flags; size_t end; @@ -59,6 +52,8 @@ typedef struct VirtQueue VirtQueue; typedef struct VirtQueueElement { unsigned int index; + unsigned int len; + unsigned int ndescs; unsigned int out_num; unsigned int in_num; hwaddr *in_addr; @@ -158,7 +153,14 @@ typedef struct VirtioDeviceClass { */ void (*save)(VirtIODevice *vdev, QEMUFile *f); int (*load)(VirtIODevice *vdev, QEMUFile *f, int version_id); + /* Post load hook in vmsd is called early while device is processed, and + * when VirtIODevice isn't fully initialized. Devices should use this instead, + * unless they specifically want to verify the migration stream as it's + * processed, e.g. for bounds checking. + */ + int (*post_load)(VirtIODevice *vdev); const VMStateDescription *vmsd; + bool (*primary_unplug_pending)(void *opaque); } VirtioDeviceClass; void virtio_instance_init_common(Object *proxy_obj, void *data, @@ -196,7 +198,8 @@ void virtqueue_map(VirtIODevice *vdev, VirtQueueElement *elem); void *virtqueue_pop(VirtQueue *vq, size_t sz); unsigned int virtqueue_drop_all(VirtQueue *vq); void *qemu_get_virtqueue_element(VirtIODevice *vdev, QEMUFile *f, size_t sz); -void qemu_put_virtqueue_element(QEMUFile *f, VirtQueueElement *elem); +void qemu_put_virtqueue_element(VirtIODevice *vdev, QEMUFile *f, + VirtQueueElement *elem); int virtqueue_avail_bytes(VirtQueue *vq, unsigned int in_bytes, unsigned int out_bytes); void virtqueue_get_avail_bytes(VirtQueue *vq, unsigned int *in_bytes, @@ -282,7 +285,9 @@ typedef struct VirtIORNGConf VirtIORNGConf; DEFINE_PROP_BIT64("any_layout", _state, _field, \ VIRTIO_F_ANY_LAYOUT, true), \ DEFINE_PROP_BIT64("iommu_platform", _state, _field, \ - VIRTIO_F_IOMMU_PLATFORM, false) + VIRTIO_F_IOMMU_PLATFORM, false), \ + DEFINE_PROP_BIT64("packed", _state, _field, \ + VIRTIO_F_RING_PACKED, false) hwaddr virtio_queue_get_desc_addr(VirtIODevice *vdev, int n); bool virtio_queue_enabled(VirtIODevice *vdev, int n); @@ -291,8 +296,9 @@ hwaddr virtio_queue_get_used_addr(VirtIODevice *vdev, int n); hwaddr virtio_queue_get_desc_size(VirtIODevice *vdev, int n); hwaddr virtio_queue_get_avail_size(VirtIODevice *vdev, int n); hwaddr virtio_queue_get_used_size(VirtIODevice *vdev, int n); -uint16_t virtio_queue_get_last_avail_idx(VirtIODevice *vdev, int n); -void virtio_queue_set_last_avail_idx(VirtIODevice *vdev, int n, uint16_t idx); +unsigned int virtio_queue_get_last_avail_idx(VirtIODevice *vdev, int n); +void virtio_queue_set_last_avail_idx(VirtIODevice *vdev, int n, + unsigned int idx); void virtio_queue_restore_last_avail_idx(VirtIODevice *vdev, int n); void virtio_queue_invalidate_signalled_used(VirtIODevice *vdev, int n); void virtio_queue_update_used_idx(VirtIODevice *vdev, int n); @@ -302,7 +308,6 @@ EventNotifier *virtio_queue_get_guest_notifier(VirtQueue *vq); void virtio_queue_set_guest_notifier_fd_handler(VirtQueue *vq, bool assign, bool with_irqfd); int virtio_device_start_ioeventfd(VirtIODevice *vdev); -void virtio_device_stop_ioeventfd(VirtIODevice *vdev); int virtio_device_grab_ioeventfd(VirtIODevice *vdev); void virtio_device_release_ioeventfd(VirtIODevice *vdev); bool virtio_device_ioeventfd_enabled(VirtIODevice *vdev); diff --git a/include/migration/vmstate.h b/include/migration/vmstate.h index b9ee563aa4..ac4f46a67d 100644 --- a/include/migration/vmstate.h +++ b/include/migration/vmstate.h @@ -186,6 +186,8 @@ struct VMStateDescription { int (*pre_save)(void *opaque); int (*post_save)(void *opaque); bool (*needed)(void *opaque); + bool (*dev_unplug_pending)(void *opaque); + const VMStateField *fields; const VMStateDescription **subsections; }; diff --git a/include/qemu-common.h b/include/qemu-common.h index 8d84db90b0..082da59e85 100644 --- a/include/qemu-common.h +++ b/include/qemu-common.h @@ -75,6 +75,12 @@ void cpu_exec_step_atomic(CPUState *cpu); bool set_preferred_target_page_bits(int bits); /** + * finalize_target_page_bits: + * Commit the final value set by set_preferred_target_page_bits. + */ +void finalize_target_page_bits(void); + +/** * Sends a (part of) iovec down a socket, yielding when the socket is full, or * Receives data into a (part of) iovec from a socket, * yielding when there is no data in the socket. diff --git a/include/qemu/co-shared-resource.h b/include/qemu/co-shared-resource.h new file mode 100644 index 0000000000..4e4503004c --- /dev/null +++ b/include/qemu/co-shared-resource.h @@ -0,0 +1,71 @@ +/* + * Helper functionality for distributing a fixed total amount of + * an abstract resource among multiple coroutines. + * + * Copyright (c) 2019 Virtuozzo International GmbH + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef QEMU_CO_SHARED_RESOURCE_H +#define QEMU_CO_SHARED_RESOURCE_H + + +typedef struct SharedResource SharedResource; + +/* + * Create SharedResource structure + * + * @total: total amount of some resource to be shared between clients + * + * Note: this API is not thread-safe. + */ +SharedResource *shres_create(uint64_t total); + +/* + * Release SharedResource structure + * + * This function may only be called once everything allocated by all + * clients has been deallocated. + */ +void shres_destroy(SharedResource *s); + +/* + * Try to allocate an amount of @n. Return true on success, and false + * if there is too little left of the collective resource to fulfill + * the request. + */ +bool co_try_get_from_shres(SharedResource *s, uint64_t n); + +/* + * Allocate an amount of @n, and, if necessary, yield until + * that becomes possible. + */ +void coroutine_fn co_get_from_shres(SharedResource *s, uint64_t n); + +/* + * Deallocate an amount of @n. The total amount allocated by a caller + * does not need to be deallocated/released with a single call, but may + * be split over several calls. For example, get(4), get(3), and then + * put(5), put(2). + */ +void coroutine_fn co_put_to_shres(SharedResource *s, uint64_t n); + + +#endif /* QEMU_CO_SHARED_RESOURCE_H */ diff --git a/include/qemu/compiler.h b/include/qemu/compiler.h index 7b93c73340..85c02c16d3 100644 --- a/include/qemu/compiler.h +++ b/include/qemu/compiler.h @@ -60,6 +60,13 @@ #define sizeof_field(type, field) sizeof(((type *)0)->field) +/* + * Calculate the number of bytes up to and including the given 'field' of + * 'container'. + */ +#define endof(container, field) \ + (offsetof(container, field) + sizeof_field(container, field)) + /* Convert from a base type to a parent type, with compile time checking. */ #ifdef __GNUC__ #define DO_UPCAST(type, field, dev) ( __extension__ ( { \ diff --git a/include/qemu/osdep.h b/include/qemu/osdep.h index c7d242f476..0f97d68586 100644 --- a/include/qemu/osdep.h +++ b/include/qemu/osdep.h @@ -423,9 +423,9 @@ void qemu_anon_ram_free(void *ptr, size_t size); # define QEMU_VMALLOC_ALIGN (256 * 4096) #elif defined(__linux__) && defined(__sparc__) #include <sys/shm.h> -# define QEMU_VMALLOC_ALIGN MAX(getpagesize(), SHMLBA) +# define QEMU_VMALLOC_ALIGN MAX(qemu_real_host_page_size, SHMLBA) #else -# define QEMU_VMALLOC_ALIGN getpagesize() +# define QEMU_VMALLOC_ALIGN qemu_real_host_page_size #endif #ifdef CONFIG_POSIX diff --git a/include/sysemu/block-backend.h b/include/sysemu/block-backend.h index 368d53af77..b198deca0b 100644 --- a/include/sysemu/block-backend.h +++ b/include/sysemu/block-backend.h @@ -121,6 +121,10 @@ void blk_set_dev_ops(BlockBackend *blk, const BlockDevOps *ops, void *opaque); int coroutine_fn blk_co_preadv(BlockBackend *blk, int64_t offset, unsigned int bytes, QEMUIOVector *qiov, BdrvRequestFlags flags); +int coroutine_fn blk_co_pwritev_part(BlockBackend *blk, int64_t offset, + unsigned int bytes, + QEMUIOVector *qiov, size_t qiov_offset, + BdrvRequestFlags flags); int coroutine_fn blk_co_pwritev(BlockBackend *blk, int64_t offset, unsigned int bytes, QEMUIOVector *qiov, BdrvRequestFlags flags); @@ -233,8 +237,8 @@ int coroutine_fn blk_co_pwrite_zeroes(BlockBackend *blk, int64_t offset, int bytes, BdrvRequestFlags flags); int blk_pwrite_compressed(BlockBackend *blk, int64_t offset, const void *buf, int bytes); -int blk_truncate(BlockBackend *blk, int64_t offset, PreallocMode prealloc, - Error **errp); +int blk_truncate(BlockBackend *blk, int64_t offset, bool exact, + PreallocMode prealloc, Error **errp); int blk_pdiscard(BlockBackend *blk, int64_t offset, int bytes); int blk_save_vmstate(BlockBackend *blk, const uint8_t *buf, int64_t pos, int size); |