From c7319d0df67c098ec6594cd6d19f6853e121fbf1 Mon Sep 17 00:00:00 2001 From: gdwnldsKSC Date: Tue, 24 Sep 2024 18:17:42 -0400 Subject: [PATCH] upstream 57fa5ca - 0.12.1 - Jan 7, 2010 woohoo we're only in the previous decade now! :D --- outside_qemu_tree_custom/FAKE_KVM_FUNCTIONS.c | 4 + qemu/Changelog | 38 ++++++ qemu/Makefile | 2 +- qemu/Makefile.user | 7 +- qemu/QMP/README | 34 +++-- qemu/QMP/qmp-spec.txt | 60 +++++---- qemu/VERSION | 2 +- qemu/check-qdict.c | 2 + qemu/config-host.h | 2 +- qemu/configure | 3 + qemu/cpu-all.h | 3 +- qemu/cpu-defs.h | 2 +- qemu/host-utils.h | 2 +- qemu/hw/boards.h | 5 +- qemu/hw/cirrus_vga.c | 4 +- qemu/hw/e1000.c | 10 +- qemu/hw/fdc.c | 45 ++----- qemu/hw/fw_cfg.c | 69 ++++++++-- qemu/hw/fw_cfg.h | 35 +++-- qemu/hw/loader.c | 127 +++++++++--------- qemu/hw/loader.h | 11 +- qemu/hw/pc.c | 12 +- qemu/hw/pci-hotplug.c | 6 +- qemu/hw/pci.c | 82 +++++++---- qemu/hw/pci.h | 8 +- qemu/hw/qdev-properties.c | 9 +- qemu/hw/rtl8139.c | 9 +- qemu/hw/s390-virtio-bus.c | 2 +- qemu/hw/s390-virtio.c | 19 ++- qemu/hw/scsi-disk.c | 21 ++- qemu/hw/unin_pci.c | 24 ++-- qemu/hw/usb-net.c | 78 ++++++----- qemu/hw/usb.h | 3 - qemu/hw/vga-isa.c | 6 +- qemu/hw/vga-pci.c | 7 +- qemu/hw/vga.c | 46 +++++++ qemu/hw/vga_int.h | 7 +- qemu/hw/virtio-pci.c | 9 +- qemu/hw/vmware_vga.c | 79 +++++++---- qemu/migration-unix.c | 12 +- qemu/migration.c | 2 +- qemu/migration.h | 2 +- qemu/monitor.c | 57 +++++--- qemu/osdep.c | 18 ++- qemu/pc-bios/bios.bin | Bin 131072 -> 131072 bytes qemu/pc-bios/optionrom/linuxboot.S | 20 ++- qemu/qdict.c | 3 +- qemu/qemu-config.h | 1 + qemu/qemu-io.c | 10 +- qemu/qemu-monitor.h | 7 +- qemu/qemu-monitor.hx | 7 +- qemu/qemu-options.h | 2 +- qemu/qemu-options.hx | 2 +- qemu/target-alpha/op_helper.c | 4 +- qemu/target-i386/cpu.h | 5 +- qemu/target-i386/helper.c | 25 ++-- qemu/target-i386/kvm.c | 6 +- qemu/target-i386/machine.c | 2 +- qemu/target-i386/translate.c | 2 + qemu/target-mips/translate.c | 8 ++ qemu/target-mips/translate_init.c | 8 -- qemu/target-ppc/kvm.c | 2 + qemu/target-s390x/kvm.c | 2 +- qemu/usb-linux.c | 11 +- qemu/vl.c | 76 ++++++----- qemu/vnchextile.h | 2 +- 66 files changed, 742 insertions(+), 448 deletions(-) diff --git a/outside_qemu_tree_custom/FAKE_KVM_FUNCTIONS.c b/outside_qemu_tree_custom/FAKE_KVM_FUNCTIONS.c index 6c9e6987..67a84ad0 100644 --- a/outside_qemu_tree_custom/FAKE_KVM_FUNCTIONS.c +++ b/outside_qemu_tree_custom/FAKE_KVM_FUNCTIONS.c @@ -54,4 +54,8 @@ int kvm_log_start(target_phys_addr_t phys_addr, ram_addr_t size) { return 0; } +int kvm_log_stop(target_phys_addr_t phys_addr, ram_addr_t size) { + return 0; +} + #endif \ No newline at end of file diff --git a/qemu/Changelog b/qemu/Changelog index 79cd934a..ee2af730 100644 --- a/qemu/Changelog +++ b/qemu/Changelog @@ -1,3 +1,41 @@ +version 0.12.1: + - loader: fix rom loading at address 0 (fixes target-arm) (Aurelien Jarno) + - loader: fix rom_copy (fixes multiboot) (Kevin Wolf) + +version 0.12.0: + + - Update to SeaBIOS 0.5.0 + - e1000: fix device link status in Linux (Anthony Liguori) + - monitor: fix QMP for balloon command (Luiz Capitulino) + - QMP: Return an empty dict by default (Luiz Capitulino) + - QMP: Only handle converted commands (Luiz Capitulino) + - pci: support PCI based option rom loading (Gerd Hoffman/Anthony Liguori) + - Fix backcompat for hotplug of SCSI controllers (Daniel P. Berrange) + - fdc: fix migration from 0.11 (Juan Quintela) + - vmware-vga: fix segv on cursor resize. (Dave Airlie) + - vmware-vga: various fixes (Dave Airlie/Anthony Liguori) + - qdev: improve property error reporting. (Gerd Hoffmann) + - fix vga names in default_list (Gerd Hoffmann) + - usb-host: check mon before using it. (Gerd Hoffmann) + - usb-net: use qdev for -usbdevice (Gerd Hoffmann) + - monitor: Catch printing to non-existent monitor (Luiz Capitulino) + - Avoid permanently disabled QEMU monitor when UNIX migration fails (Daniel P. Berrange) + - Fix loading of ELF multiboot kernels (Kevin Wolf) + - qemu-io: Fix memory leak (Kevin Wolf) + - Fix thinko in linuxboot.S (Paolo Bonzini) + - target-i386: Fix evaluation of DR7 register (Jan Kiszka) + - vnc: hextile: do not generate ForegroundSpecified and SubrectsColoured tiles (Anthony Liguori) + - S390: Bail out without KVM (Alexander Graf) + - S390: Don't tell guest we're updating config space (Alexander Graf) + - target-s390: Fail on unknown instructions (Alexander Graf) + - osdep: Fix runtime failure on older Linux kernels (Andre Przywara) + - Fix a make -j race (Juergen Lock) + - target-alpha: Fix generic ctz64. (Richard Henderson) + - s390: Fix buggy assignment (Stefan Weil) + - target-mips: fix user-mode emulation startup (Nathan Froyd) + - target-i386: Update CPUID feature set for TCG (Andre Przywara) + - s390: fix build on 32 bit host (Michael S. Tsirkin) + version 0.12.0-rc2: - v2: properly save kvm system time msr registers (Glauber Costa) diff --git a/qemu/Makefile b/qemu/Makefile index a662d96a..c1fa08ce 100644 --- a/qemu/Makefile +++ b/qemu/Makefile @@ -70,7 +70,7 @@ $(filter %-softmmu,$(SUBDIR_RULES)): libqemu_common.a $(filter %-user,$(SUBDIR_RULES)): libuser.a -libuser.a: +libuser.a: $(GENERATED_HEADERS) $(call quiet-command,$(MAKE) $(SUBDIR_MAKEFLAGS) -C libuser V="$(V)" TARGET_DIR="libuser/" all,) ROMSUBDIR_RULES=$(patsubst %,romsubdir-%, $(ROMS)) diff --git a/qemu/Makefile.user b/qemu/Makefile.user index 907e74bd..7daedeff 100644 --- a/qemu/Makefile.user +++ b/qemu/Makefile.user @@ -2,10 +2,15 @@ include ../config-host.mak include $(SRC_PATH)/rules.mak +-include config.mak .PHONY: all -VPATH=$(SRC_PATH) +# Do not take %.o from $(SRC_PATH), only %.c and %.h +# All %.o for user targets should be built with -fpie, when +# configured with --enable-user-pie, so we don't want to +# take %.o from $(SRC_PATH), since they built without -fpie +vpath %.c %.h $(SRC_PATH) QEMU_CFLAGS+=-I.. diff --git a/qemu/QMP/README b/qemu/QMP/README index 50c31f20..09e70537 100644 --- a/qemu/QMP/README +++ b/qemu/QMP/README @@ -4,45 +4,57 @@ Introduction ------------- -The QEMU Monitor Protocol (QMP) is a JSON[1] based protocol for QEMU. +The QEMU Monitor Protocol (QMP) allows applications to communicate with +QEMU's Monitor. -By using it applications can control QEMU in reliable and "parseable" way, -QMP also provides asynchronous events support. +QMP is JSON[1] based and has the following features: + +- Lightweight, text-based, easy to parse data format +- Asynchronous events support +- Stability For more information, please, refer to the following files: -o qmp-spec.txt QEMU Monitor Protocol current draft specification +o qmp-spec.txt QEMU Monitor Protocol current specification o qmp-events.txt List of available asynchronous events There are also two simple Python scripts available: o qmp-shell A shell -o vm-info Show some informations about the Virtal Machine +o vm-info Show some information about the Virtual Machine [1] http://www.json.org Usage ----- -To enable QMP, QEMU has to be started in "control mode". This is done -by passing the flag "control" to the "-monitor" command-line option. +To enable QMP, QEMU has to be started in "control mode". There are +two ways of doing this, the simplest one is using the the '-qmp' +command-line option. For example: -$ qemu [...] -monitor control,tcp:localhost:4444,server +$ qemu [...] -qmp tcp:localhost:4444,server Will start QEMU in control mode, waiting for a client TCP connection on localhost port 4444. -To manually test it you can connect with telnet and issue commands: +It is also possible to use the '-mon' command-line option to have +more complex combinations. Please, refer to the QEMU's manpage for +more information. + +Simple Testing +-------------- + +To manually test QMP one can connect with telnet and issue commands: $ telnet localhost 4444 -Trying ::1... +Trying 127.0.0.1... Connected to localhost. Escape character is '^]'. {"QMP": {"capabilities": []}} { "execute": "query-version" } -{"return": "0.11.50"} +{"return": {"qemu": "0.11.50", "package": ""}} Contact ------- diff --git a/qemu/QMP/qmp-spec.txt b/qemu/QMP/qmp-spec.txt index 1cbd21cd..56f388c3 100644 --- a/qemu/QMP/qmp-spec.txt +++ b/qemu/QMP/qmp-spec.txt @@ -1,4 +1,4 @@ - QEMU Monitor Protocol Draft Specification - Version 0.1 + QEMU Monitor Protocol Specification - Version 0.1 1. Introduction =============== @@ -27,9 +27,9 @@ the JSON standard: http://www.ietf.org/rfc/rfc4627.txt -For convenience, json-objects mentioned in this document will have its members -in a certain order. However, in real protocol usage json-objects members can -be in ANY order, thus no particular order should be assumed. +For convenience, json-object members and json-array elements mentioned in +this document will be in a certain order. However, in real protocol usage +they can be in ANY order, thus no particular order should be assumed. 2.1 General Definitions ----------------------- @@ -85,12 +85,13 @@ without errors. The format is: -{ "return": json-value, "id": json-value } +{ "return": json-object, "id": json-value } Where, - The "return" member contains the command returned data, which is defined - in a per-command basis or "OK" if the command does not return data + in a per-command basis or an empty json-object if the command does not + return data - The "id" member contains the transaction identification associated with the command execution (if issued by the Client) @@ -102,7 +103,7 @@ completed because of an error condition. The format is: -{ "error": { "class": json-string, "data": json-value, "desc": json-string }, +{ "error": { "class": json-string, "data": json-object, "desc": json-string }, "id": json-value } Where, @@ -110,7 +111,7 @@ The format is: - The "class" member contains the error class name (eg. "ServiceUnavailable") - The "data" member contains specific error data and is defined in a per-command basis, it will be an empty json-object if the error has no data -- The "desc" member is a human-readable error message. Clients should +- The "desc" member is a human-readable error message. Clients should not attempt to parse this message. - The "id" member contains the transaction identification associated with the command execution (if issued by the Client) @@ -127,7 +128,7 @@ to the Client at any time. They are called 'asynchronous events'. The format is: -{ "event": json-string, "data": json-value, +{ "event": json-string, "data": json-object, "timestamp": { "seconds": json-number, "microseconds": json-number } } Where, @@ -135,7 +136,7 @@ The format is: - The "event" member contains the event's name - The "data" member contains event specific data, which is defined in a per-event basis, it is optional -- The "timestamp" member contains the exact time of when the event ocurred +- The "timestamp" member contains the exact time of when the event occurred in the Server. It is a fixed json-object with time in seconds and microseconds @@ -157,19 +158,20 @@ S: {"QMP": {"capabilities": []}} --------------------------- C: { "execute": "stop" } -S: {"return": "OK"} +S: {"return": {}} 3.3 KVM information ------------------- -C: {"execute": "query-kvm", "id": "example"} -S: {"return": "enabled", "id": "example"} +C: { "execute": "query-kvm", "id": "example" } +S: {"return": {"enabled": true, "present": true}, "id": "example"} 3.4 Parsing error ------------------ C: { "execute": } -S: {"error": {"class": "JSONParsing", "data": {}}} +S: {"error": {"class": "JSONParsing", "desc": "Invalid JSON syntax", "data": +{}}} 3.5 Powerdown event ------------------- @@ -177,19 +179,25 @@ S: {"error": {"class": "JSONParsing", "data": {}}} S: {"timestamp": {"seconds": 1258551470, "microseconds": 802384}, "event": "POWERDOWN"} -4. Notes to Client implementors -------------------------------- +4. Compatibility Considerations +-------------------------------- -4.1 It is recommended to always start the Server in pause mode, thus the - Client is able to perform any setup procedure without the risk of - race conditions and related problems +In order to achieve maximum compatibility between versions, Clients must not +assume any particular: -4.2 It is recommended to always check the capabilities json-array, issued - with the greeting message, at connection time +- Size of json-objects or length of json-arrays +- Order of json-object members or json-array elements +- Amount of errors generated by a command, that is, new errors can be added + to any existing command in newer versions of the Server -4.3 Json-objects or json-arrays mentioned in this document are not fixed - and no particular size or number of members/elements should be assumed. - New members/elements can be added at any time. +Additionally, Clients should always: -4.4 No particular order of json-objects members should be assumed, they - can change at any time +- Check the capabilities json-array at connection time +- Check the availability of commands with 'query-commands' before issuing them + +5. Recommendations to Client implementors +----------------------------------------- + +5.1 The Server should be always started in pause mode, thus the Client is + able to perform any setup procedure without the risk of race conditions + and related problems diff --git a/qemu/VERSION b/qemu/VERSION index c2527649..34a83616 100644 --- a/qemu/VERSION +++ b/qemu/VERSION @@ -1 +1 @@ -0.11.92 +0.12.1 diff --git a/qemu/check-qdict.c b/qemu/check-qdict.c index c37d4482..f2b48265 100644 --- a/qemu/check-qdict.c +++ b/qemu/check-qdict.c @@ -205,6 +205,8 @@ START_TEST(qdict_put_exists_test) value = qdict_get_int(tests_dict, key); fail_unless(value == 2); + + fail_unless(qdict_size(tests_dict) == 1); } END_TEST diff --git a/qemu/config-host.h b/qemu/config-host.h index d21e7407..8f4735c8 100644 --- a/qemu/config-host.h +++ b/qemu/config-host.h @@ -9,7 +9,7 @@ #define CONFIG_STATIC 1 #define CONFIG_SLIRP 1 #define CONFIG_ADLIB 1 -#define QEMU_VERSION "0.11.92" +#define QEMU_VERSION "0.12.1" #define QEMU_PKGVERSION "MS-VisualStudio-2022" #define CONFIG_UNAME_RELEASE "" #define CONFIG_AUDIO_DRIVERS &winwave_audio_driver, \ diff --git a/qemu/configure b/qemu/configure index 273b6b7c..5f463b05 100644 --- a/qemu/configure +++ b/qemu/configure @@ -2652,3 +2652,6 @@ d=libuser mkdir -p $d rm -f $d/Makefile ln -s $source_path/Makefile.user $d/Makefile +if test "$static" = "no" -a "$user_pie" = "yes" ; then + echo "QEMU_CFLAGS+=-fpie" > $d/config.mak +fi diff --git a/qemu/cpu-all.h b/qemu/cpu-all.h index e3f267cf..8ca18bcd 100644 --- a/qemu/cpu-all.h +++ b/qemu/cpu-all.h @@ -1039,7 +1039,8 @@ static inline int64_t cpu_get_real_ticks (void) #endif } -#elif (defined(__mips_isa_rev) && __mips_isa_rev >= 2) || defined(__linux__) +#elif defined(__mips)) && \ + ((defined(__mips_isa_rev) && __mips_isa_rev > = 2) || defined(__linux__)) /* * binutils wants to use rdhwr only on mips32r2 * but as linux kernel emulate it, it's fine diff --git a/qemu/cpu-defs.h b/qemu/cpu-defs.h index 2dcc6fa6..38056e6c 100644 --- a/qemu/cpu-defs.h +++ b/qemu/cpu-defs.h @@ -202,7 +202,7 @@ typedef int sig_atomic_t; \ /* Core interrupt code */ \ jmp_buf jmp_env; \ - int32_t exception_index; \ + int exception_index; \ \ CPUState *next_cpu; /* next CPU sharing TB cache */ \ int cpu_index; /* CPU index (informative) */ \ diff --git a/qemu/host-utils.h b/qemu/host-utils.h index e335c5cb..0ddc1765 100644 --- a/qemu/host-utils.h +++ b/qemu/host-utils.h @@ -164,7 +164,7 @@ static inline int ctz64(uint64_t val) { #if QEMU_GNUC_PREREQ(3, 4) if (val) - return __builtin_ctz(val); + return __builtin_ctzll(val); else return 64; #else diff --git a/qemu/hw/boards.h b/qemu/hw/boards.h index 8fe0fbc8..e1beda30 100644 --- a/qemu/hw/boards.h +++ b/qemu/hw/boards.h @@ -22,7 +22,10 @@ typedef struct QEMUMachine { int no_serial:1, no_parallel:1, use_virtcon:1, - no_vga:1; + no_vga:1, + no_floppy:1, + no_cdrom:1, + no_sdcard:1; int is_default; GlobalProperty *compat_props; struct QEMUMachine *next; diff --git a/qemu/hw/cirrus_vga.c b/qemu/hw/cirrus_vga.c index 67bf2504..3b0da7d3 100644 --- a/qemu/hw/cirrus_vga.c +++ b/qemu/hw/cirrus_vga.c @@ -3227,9 +3227,6 @@ static int pci_cirrus_vga_initfn(PCIDevice *dev) pci_register_bar((PCIDevice *)d, 1, CIRRUS_PNPMMIO_SIZE, PCI_BASE_ADDRESS_SPACE_MEMORY, cirrus_pci_mmio_map); } - - /* ROM BIOS */ - rom_add_vga(VGABIOS_CIRRUS_FILENAME); return 0; } @@ -3244,6 +3241,7 @@ static PCIDeviceInfo cirrus_vga_info = { .qdev.size = sizeof(PCICirrusVGAState), .qdev.vmsd = &vmstate_pci_cirrus_vga, .init = pci_cirrus_vga_initfn, + .romfile = VGABIOS_CIRRUS_FILENAME, .config_write = pci_cirrus_write_config, }; diff --git a/qemu/hw/e1000.c b/qemu/hw/e1000.c index 4fc207e8..5b180e65 100644 --- a/qemu/hw/e1000.c +++ b/qemu/hw/e1000.c @@ -1110,7 +1110,6 @@ static int pci_e1000_init(PCIDevice *pci_dev) pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_INTEL); pci_config_set_device_id(pci_conf, E1000_DEVID); - *(uint16_t *)(pci_conf+0x04) = cpu_to_le16(0x0407); *(uint16_t *)(pci_conf+0x06) = cpu_to_le16(0x0010); pci_conf[0x08] = 0x03; pci_config_set_class(pci_conf, PCI_CLASS_NETWORK_ETHERNET); @@ -1142,14 +1141,6 @@ static int pci_e1000_init(PCIDevice *pci_dev) d->dev.qdev.info->name, d->dev.qdev.id, d); qemu_format_nic_info_str(&d->nic->nc, macaddr); - - if (!pci_dev->qdev.hotplugged) { - static int loaded = 0; - if (!loaded) { - rom_add_option("pxe-e1000.bin"); - loaded = 1; - } - } return 0; } @@ -1167,6 +1158,7 @@ static PCIDeviceInfo e1000_info = { .qdev.vmsd = &vmstate_e1000, .init = pci_e1000_init, .exit = pci_e1000_uninit, + .romfile = "pxe-e1000.bin", .qdev.props = (Property[]) { DEFINE_NIC_PROPERTIES(E1000State, conf), DEFINE_PROP_END_OF_LIST(), diff --git a/qemu/hw/fdc.c b/qemu/hw/fdc.c index 0d38dd2e..bfdafd65 100644 --- a/qemu/hw/fdc.c +++ b/qemu/hw/fdc.c @@ -661,7 +661,7 @@ static int fdc_post_load(void *opaque, int version_id) } static const VMStateDescription vmstate_fdc = { - .name = "fdctrl", + .name = "fdc", .version_id = 2, .minimum_version_id = 2, .minimum_version_id_old = 2, @@ -699,31 +699,6 @@ static const VMStateDescription vmstate_fdc = { } }; -static const VMStateDescription vmstate_fdc_isa = { - .name = "fdc", - .version_id = 2, - .minimum_version_id = 2, - .minimum_version_id_old = 2, - .fields = (VMStateField []) { - /* Controller State */ - VMSTATE_STRUCT(state, fdctrl_isabus_t, 0, vmstate_fdc, fdctrl_t), - VMSTATE_END_OF_LIST() - } -}; - -static const VMStateDescription vmstate_fdc_sysbus = { - .name = "fdc", - .version_id = 2, - .minimum_version_id = 2, - .minimum_version_id_old = 2, - .fields = (VMStateField []) { - /* Controller State */ - VMSTATE_STRUCT(state, fdctrl_sysbus_t, 0, vmstate_fdc, fdctrl_t), - VMSTATE_END_OF_LIST() - } -}; - - static void fdctrl_external_reset_sysbus(DeviceState *d) { fdctrl_sysbus_t *sys = container_of(d, fdctrl_sysbus_t, busdev.qdev); @@ -960,6 +935,12 @@ static uint32_t fdctrl_read_main_status (fdctrl_t *fdctrl) fdctrl->dsr &= ~FD_DSR_PWRDOWN; fdctrl->dor |= FD_DOR_nRESET; + /* Sparc mutation */ + if (fdctrl->sun4m) { + retval |= FD_MSR_DIO; + fdctrl_reset_irq(fdctrl); + }; + FLOPPY_DPRINTF("main status register: 0x%02x\n", retval); return retval; @@ -1926,7 +1907,7 @@ fdctrl_t *sun4m_fdctrl_init (qemu_irq irq, target_phys_addr_t io_base, return fdctrl; } -static int fdctrl_init_common(fdctrl_t *fdctrl) +static int fdctrl_init_common(fdctrl_t *fdctrl, target_phys_addr_t io_base) { int i, j; static int command_tables_inited = 0; @@ -1957,6 +1938,7 @@ static int fdctrl_init_common(fdctrl_t *fdctrl) DMA_register_channel(fdctrl->dma_chann, &fdctrl_transfer_handler, fdctrl); fdctrl_connect_drives(fdctrl); + vmstate_register(io_base, &vmstate_fdc, fdctrl); return 0; } @@ -1980,7 +1962,7 @@ static int isabus_fdc_init1(ISADevice *dev) isa_init_irq(&isa->busdev, &fdctrl->irq, isairq); fdctrl->dma_chann = dma_chann; - ret = fdctrl_init_common(fdctrl); + ret = fdctrl_init_common(fdctrl, iobase); return ret; } @@ -1998,7 +1980,7 @@ static int sysbus_fdc_init1(SysBusDevice *dev) qdev_init_gpio_in(&dev->qdev, fdctrl_handle_tc, 1); fdctrl->dma_chann = -1; - ret = fdctrl_init_common(fdctrl); + ret = fdctrl_init_common(fdctrl, io); return ret; } @@ -2015,7 +1997,7 @@ static int sun4m_fdc_init1(SysBusDevice *dev) qdev_init_gpio_in(&dev->qdev, fdctrl_handle_tc, 1); fdctrl->sun4m = 1; - return fdctrl_init_common(fdctrl); + return fdctrl_init_common(fdctrl, io); } static ISADeviceInfo isa_fdc_info = { @@ -2023,7 +2005,6 @@ static ISADeviceInfo isa_fdc_info = { .qdev.name = "isa-fdc", .qdev.size = sizeof(fdctrl_isabus_t), .qdev.no_user = 1, - .qdev.vmsd = &vmstate_fdc_isa, .qdev.reset = fdctrl_external_reset_isa, .qdev.props = (Property[]) { DEFINE_PROP_DRIVE("driveA", fdctrl_isabus_t, state.drives[0].dinfo), @@ -2036,7 +2017,6 @@ static SysBusDeviceInfo sysbus_fdc_info = { .init = sysbus_fdc_init1, .qdev.name = "sysbus-fdc", .qdev.size = sizeof(fdctrl_sysbus_t), - .qdev.vmsd = &vmstate_fdc_sysbus, .qdev.reset = fdctrl_external_reset_sysbus, .qdev.props = (Property[]) { DEFINE_PROP_DRIVE("driveA", fdctrl_sysbus_t, state.drives[0].dinfo), @@ -2049,7 +2029,6 @@ static SysBusDeviceInfo sun4m_fdc_info = { .init = sun4m_fdc_init1, .qdev.name = "SUNW,fdtwo", .qdev.size = sizeof(fdctrl_sysbus_t), - .qdev.vmsd = &vmstate_fdc_sysbus, .qdev.reset = fdctrl_external_reset_sysbus, .qdev.props = (Property[]) { DEFINE_PROP_DRIVE("drive", fdctrl_sysbus_t, state.drives[0].dinfo), diff --git a/qemu/hw/fw_cfg.c b/qemu/hw/fw_cfg.c index b25affff..fe9c5275 100644 --- a/qemu/hw/fw_cfg.c +++ b/qemu/hw/fw_cfg.c @@ -45,11 +45,12 @@ typedef struct _FWCfgEntry { FWCfgCallback callback; } FWCfgEntry; -typedef struct _FWCfgState { +struct _FWCfgState { FWCfgEntry entries[2][FW_CFG_MAX_ENTRY]; + FWCfgFiles *files; uint16_t cur_entry; uint32_t cur_offset; -} FWCfgState; +}; static void fw_cfg_write(FWCfgState *s, uint8_t value) { @@ -210,9 +211,8 @@ static const VMStateDescription vmstate_fw_cfg = { } }; -int fw_cfg_add_bytes(void *opaque, uint16_t key, uint8_t *data, uint32_t len) +int fw_cfg_add_bytes(FWCfgState *s, uint16_t key, uint8_t *data, uint32_t len) { - FWCfgState *s = opaque; int arch = !!(key & FW_CFG_ARCH_LOCAL); key &= FW_CFG_ENTRY_MASK; @@ -226,37 +226,36 @@ int fw_cfg_add_bytes(void *opaque, uint16_t key, uint8_t *data, uint32_t len) return 1; } -int fw_cfg_add_i16(void *opaque, uint16_t key, uint16_t value) +int fw_cfg_add_i16(FWCfgState *s, uint16_t key, uint16_t value) { uint16_t *copy; copy = qemu_malloc(sizeof(value)); *copy = cpu_to_le16(value); - return fw_cfg_add_bytes(opaque, key, (uint8_t *)copy, sizeof(value)); + return fw_cfg_add_bytes(s, key, (uint8_t *)copy, sizeof(value)); } -int fw_cfg_add_i32(void *opaque, uint16_t key, uint32_t value) +int fw_cfg_add_i32(FWCfgState *s, uint16_t key, uint32_t value) { uint32_t *copy; copy = qemu_malloc(sizeof(value)); *copy = cpu_to_le32(value); - return fw_cfg_add_bytes(opaque, key, (uint8_t *)copy, sizeof(value)); + return fw_cfg_add_bytes(s, key, (uint8_t *)copy, sizeof(value)); } -int fw_cfg_add_i64(void *opaque, uint16_t key, uint64_t value) +int fw_cfg_add_i64(FWCfgState *s, uint16_t key, uint64_t value) { uint64_t *copy; copy = qemu_malloc(sizeof(value)); *copy = cpu_to_le64(value); - return fw_cfg_add_bytes(opaque, key, (uint8_t *)copy, sizeof(value)); + return fw_cfg_add_bytes(s, key, (uint8_t *)copy, sizeof(value)); } -int fw_cfg_add_callback(void *opaque, uint16_t key, FWCfgCallback callback, +int fw_cfg_add_callback(FWCfgState *s, uint16_t key, FWCfgCallback callback, void *callback_opaque, uint8_t *data, size_t len) { - FWCfgState *s = opaque; int arch = !!(key & FW_CFG_ARCH_LOCAL); if (!(key & FW_CFG_WRITE_CHANNEL)) @@ -275,8 +274,50 @@ int fw_cfg_add_callback(void *opaque, uint16_t key, FWCfgCallback callback, return 1; } -void *fw_cfg_init(uint32_t ctl_port, uint32_t data_port, - target_phys_addr_t ctl_addr, target_phys_addr_t data_addr) +int fw_cfg_add_file(FWCfgState *s, const char *dir, const char *filename, + uint8_t *data, uint32_t len) +{ + const char *basename; + int index; + + if (!s->files) { + int dsize = sizeof(uint32_t) + sizeof(FWCfgFile) * FW_CFG_FILE_SLOTS; + s->files = qemu_mallocz(dsize); + fw_cfg_add_bytes(s, FW_CFG_FILE_DIR, (uint8_t*)s->files, dsize); + } + + index = be32_to_cpu(s->files->count); + if (index == FW_CFG_FILE_SLOTS) { + fprintf(stderr, "fw_cfg: out of file slots\n"); + return 0; + } + + fw_cfg_add_bytes(s, FW_CFG_FILE_FIRST + index, data, len); + + basename = strrchr(filename, '/'); + if (basename) { + basename++; + } else { + basename = filename; + } + if (dir) { + snprintf(s->files->f[index].name, sizeof(s->files->f[index].name), + "%s/%s", dir, basename); + } else { + snprintf(s->files->f[index].name, sizeof(s->files->f[index].name), + "%s", basename); + } + s->files->f[index].size = cpu_to_be32(len); + s->files->f[index].select = cpu_to_be16(FW_CFG_FILE_FIRST + index); + FW_CFG_DPRINTF("%s: #%d: %s (%d bytes)\n", __FUNCTION__, + index, s->files->f[index].name, len); + + s->files->count = cpu_to_be32(index+1); + return 1; +} + +FWCfgState *fw_cfg_init(uint32_t ctl_port, uint32_t data_port, + target_phys_addr_t ctl_addr, target_phys_addr_t data_addr) { FWCfgState *s; int io_ctl_memory, io_data_memory; diff --git a/qemu/hw/fw_cfg.h b/qemu/hw/fw_cfg.h index 7070c940..c1019d0b 100644 --- a/qemu/hw/fw_cfg.h +++ b/qemu/hw/fw_cfg.h @@ -26,7 +26,11 @@ #define FW_CFG_SETUP_ADDR 0x16 #define FW_CFG_SETUP_SIZE 0x17 #define FW_CFG_SETUP_DATA 0x18 -#define FW_CFG_MAX_ENTRY 0x19 +#define FW_CFG_FILE_DIR 0x19 + +#define FW_CFG_FILE_FIRST 0x20 +#define FW_CFG_FILE_SLOTS 0x10 +#define FW_CFG_MAX_ENTRY (FW_CFG_FILE_FIRST+FW_CFG_FILE_SLOTS) #define FW_CFG_WRITE_CHANNEL 0x4000 #define FW_CFG_ARCH_LOCAL 0x8000 @@ -35,16 +39,31 @@ #define FW_CFG_INVALID 0xffff #ifndef NO_QEMU_PROTOS +typedef struct FWCfgFile { + uint32_t size; /* file size */ + uint16_t select; /* write this to 0x510 to read it */ + uint16_t reserved; + char name[56]; +} FWCfgFile; + +typedef struct FWCfgFiles { + uint32_t count; + FWCfgFile f[]; +} FWCfgFiles; + typedef void (*FWCfgCallback)(void *opaque, uint8_t *data); -int fw_cfg_add_bytes(void *opaque, uint16_t key, uint8_t *data, uint32_t len); -int fw_cfg_add_i16(void *opaque, uint16_t key, uint16_t value); -int fw_cfg_add_i32(void *opaque, uint16_t key, uint32_t value); -int fw_cfg_add_i64(void *opaque, uint16_t key, uint64_t value); -int fw_cfg_add_callback(void *opaque, uint16_t key, FWCfgCallback callback, +typedef struct _FWCfgState FWCfgState; +int fw_cfg_add_bytes(FWCfgState *s, uint16_t key, uint8_t *data, uint32_t len); +int fw_cfg_add_i16(FWCfgState *s, uint16_t key, uint16_t value); +int fw_cfg_add_i32(FWCfgState *s, uint16_t key, uint32_t value); +int fw_cfg_add_i64(FWCfgState *s, uint16_t key, uint64_t value); +int fw_cfg_add_callback(FWCfgState *s, uint16_t key, FWCfgCallback callback, void *callback_opaque, uint8_t *data, size_t len); -void *fw_cfg_init(uint32_t ctl_port, uint32_t data_port, - target_phys_addr_t crl_addr, target_phys_addr_t data_addr); +int fw_cfg_add_file(FWCfgState *s, const char *dir, const char *filename, + uint8_t *data, uint32_t len); +FWCfgState *fw_cfg_init(uint32_t ctl_port, uint32_t data_port, + target_phys_addr_t crl_addr, target_phys_addr_t data_addr); #endif /* NO_QEMU_PROTOS */ diff --git a/qemu/hw/loader.c b/qemu/hw/loader.c index 2d7a2c49..eef385eb 100644 --- a/qemu/hw/loader.c +++ b/qemu/hw/loader.c @@ -48,6 +48,7 @@ #include "sysemu.h" #include "uboot_image.h" #include "loader.h" +#include "fw_cfg.h" #include @@ -526,11 +527,10 @@ struct Rom { char *path; size_t romsize; uint8_t *data; - int align; int isrom; + char *fw_dir; + char *fw_file; - target_phys_addr_t min; - target_phys_addr_t max; target_phys_addr_t addr; QTAILQ_ENTRY(Rom) next; }; @@ -548,7 +548,7 @@ static void rom_insert(Rom *rom) /* list is ordered by load address */ QTAILQ_FOREACH(item, &roms, next) { - if (rom->min >= item->min) + if (rom->addr >= item->addr) continue; QTAILQ_INSERT_BEFORE(item, rom, next); return; @@ -556,8 +556,8 @@ static void rom_insert(Rom *rom) QTAILQ_INSERT_TAIL(&roms, rom, next); } -int rom_add_file(const char *file, - target_phys_addr_t min, target_phys_addr_t max, int align) +int rom_add_file(const char *file, const char *fw_dir, const char *fw_file, + target_phys_addr_t addr) { Rom *rom; int rc, fd = -1; @@ -576,9 +576,9 @@ int rom_add_file(const char *file, goto err; } - rom->align = align; - rom->min = min; - rom->max = max; + rom->fw_dir = fw_dir ? qemu_strdup(fw_dir) : NULL; + rom->fw_file = fw_file ? qemu_strdup(fw_file) : NULL; + rom->addr = addr; rom->romsize = lseek(fd, 0, SEEK_END); rom->data = qemu_mallocz(rom->romsize); lseek(fd, 0, SEEK_SET); @@ -603,15 +603,13 @@ int rom_add_file(const char *file, } int rom_add_blob(const char *name, const void *blob, size_t len, - target_phys_addr_t min, target_phys_addr_t max, int align) + target_phys_addr_t addr) { Rom *rom; rom = qemu_mallocz(sizeof(*rom)); rom->name = qemu_strdup(name); - rom->align = align; - rom->min = min; - rom->max = max; + rom->addr = addr; rom->romsize = len; rom->data = qemu_mallocz(rom->romsize); memcpy(rom->data, blob, len); @@ -623,14 +621,14 @@ int rom_add_vga(const char *file) { if (!rom_enable_driver_roms) return 0; - return rom_add_file(file, PC_ROM_MIN_VGA, PC_ROM_MAX, PC_ROM_ALIGN); + return rom_add_file(file, "vgaroms", file, 0); } int rom_add_option(const char *file) { if (!rom_enable_driver_roms) return 0; - return rom_add_file(file, PC_ROM_MIN_OPTION, PC_ROM_MAX, PC_ROM_ALIGN); + return rom_add_file(file, "genroms", file, 0); } static void rom_reset(void *unused) @@ -638,6 +636,9 @@ static void rom_reset(void *unused) Rom *rom; QTAILQ_FOREACH(rom, &roms, next) { + if (rom->fw_file) { + continue; + } if (rom->data == NULL) continue; cpu_physical_memory_write_rom(rom->addr, rom->data, rom->romsize); @@ -656,32 +657,17 @@ int rom_load_all(void) Rom *rom; QTAILQ_FOREACH(rom, &roms, next) { - if (addr < rom->min) - addr = rom->min; - if (rom->max) { - /* load address range */ - if (rom->align) { - addr += (rom->align-1); - addr &= ~(rom->align-1); - } - if (addr + rom->romsize > rom->max) { - fprintf(stderr, "rom: out of memory (rom %s, " - "addr 0x" TARGET_FMT_plx - ", size 0x%zx, max 0x" TARGET_FMT_plx ")\n", - rom->name, addr, rom->romsize, rom->max); - return -1; - } - } else { - /* fixed address requested */ - if (addr != rom->min) { - fprintf(stderr, "rom: requested regions overlap " - "(rom %s. free=0x" TARGET_FMT_plx - ", addr=0x" TARGET_FMT_plx ")\n", - rom->name, addr, rom->min); - return -1; - } + if (rom->fw_file) { + continue; + } + if (addr > rom->addr) { + fprintf(stderr, "rom: requested regions overlap " + "(rom %s. free=0x" TARGET_FMT_plx + ", addr=0x" TARGET_FMT_plx ")\n", + rom->name, addr, rom->addr); + return -1; } - rom->addr = addr; + addr = rom->addr; addr += rom->romsize; memtype = cpu_get_physical_page_desc(rom->addr) & (3 << IO_MEM_SHIFT); if (memtype == IO_MEM_ROM) @@ -692,22 +678,37 @@ int rom_load_all(void) return 0; } -static Rom *find_rom(target_phys_addr_t addr) +int rom_load_fw(void *fw_cfg) { Rom *rom; QTAILQ_FOREACH(rom, &roms, next) { - if (rom->max) + if (!rom->fw_file) continue; - if (rom->min > addr) + fw_cfg_add_file(fw_cfg, rom->fw_dir, rom->fw_file, rom->data, rom->romsize); + } + return 0; +} + +static Rom *find_rom(target_phys_addr_t addr) +{ + Rom *rom; + + QTAILQ_FOREACH(rom, &roms, next) { + if (rom->addr > addr) continue; - if (rom->min + rom->romsize < addr) + if (rom->addr + rom->romsize < addr) continue; return rom; } return NULL; } +/* + * Copies memory from registered ROMs to dest. Any memory that is contained in + * a ROM between addr and addr + size is copied. Note that this can involve + * multiple ROMs, which need not start at addr and need not end at addr + size. + */ int rom_copy(uint8_t *dest, target_phys_addr_t addr, size_t size) { target_phys_addr_t end = addr + size; @@ -716,25 +717,21 @@ int rom_copy(uint8_t *dest, target_phys_addr_t addr, size_t size) Rom *rom; QTAILQ_FOREACH(rom, &roms, next) { - if (rom->max) - continue; - if (rom->min > addr) - continue; - if (rom->min + rom->romsize < addr) + if (rom->addr + rom->romsize < addr) continue; - if (rom->min > end) + if (rom->addr > end) break; if (!rom->data) continue; - d = dest + (rom->min - addr); + d = dest + (rom->addr - addr); s = rom->data; l = rom->romsize; - if (rom->min < addr) { + if (rom->addr < addr) { d = dest; - s += (addr - rom->min); - l -= (addr - rom->min); + s += (addr - rom->addr); + l -= (addr - rom->addr); } if ((d + l) > (dest + size)) { l = dest - d; @@ -753,7 +750,7 @@ void *rom_ptr(target_phys_addr_t addr) rom = find_rom(addr); if (!rom || !rom->data) return NULL; - return rom->data + (addr - rom->min); + return rom->data + (addr - rom->addr); } void do_info_roms(Monitor *mon) @@ -761,10 +758,20 @@ void do_info_roms(Monitor *mon) Rom *rom; QTAILQ_FOREACH(rom, &roms, next) { - monitor_printf(mon, "addr=" TARGET_FMT_plx - " size=0x%06zx mem=%s name=\"%s\" \n", - rom->addr, rom->romsize, - rom->isrom ? "rom" : "ram", - rom->name); + if (!rom->fw_file) { + monitor_printf(mon, "addr=" TARGET_FMT_plx + " size=0x%06zx mem=%s name=\"%s\" \n", + rom->addr, rom->romsize, + rom->isrom ? "rom" : "ram", + rom->name); + } else { + monitor_printf(mon, "fw=%s%s%s" + " size=0x%06zx name=\"%s\" \n", + rom->fw_dir ? rom->fw_dir : "", + rom->fw_dir ? "/" : "", + rom->fw_file, + rom->romsize, + rom->name); + } } } diff --git a/qemu/hw/loader.h b/qemu/hw/loader.h index b3311a39..77beb0e9 100644 --- a/qemu/hw/loader.h +++ b/qemu/hw/loader.h @@ -19,19 +19,20 @@ void pstrcpy_targphys(const char *name, target_phys_addr_t dest, int buf_size, const char *source); -int rom_add_file(const char *file, - target_phys_addr_t min, target_phys_addr_t max, int align); +int rom_add_file(const char *file, const char *fw_dir, const char *fw_file, + target_phys_addr_t addr); int rom_add_blob(const char *name, const void *blob, size_t len, - target_phys_addr_t min, target_phys_addr_t max, int align); + target_phys_addr_t addr); int rom_load_all(void); +int rom_load_fw(void *fw_cfg); int rom_copy(uint8_t *dest, target_phys_addr_t addr, size_t size); void *rom_ptr(target_phys_addr_t addr); void do_info_roms(Monitor *mon); #define rom_add_file_fixed(_f, _a) \ - rom_add_file(_f, _a, 0, 0) + rom_add_file(_f, NULL, NULL, _a) #define rom_add_blob_fixed(_f, _b, _l, _a) \ - rom_add_blob(_f, _b, _l, _a, 0, 0) + rom_add_blob(_f, _b, _l, _a) #define PC_ROM_MIN_VGA 0xc0000 #define PC_ROM_MIN_OPTION 0xc8000 diff --git a/qemu/hw/pc.c b/qemu/hw/pc.c index 147a9a70..db7d58ef 100644 --- a/qemu/hw/pc.c +++ b/qemu/hw/pc.c @@ -560,19 +560,21 @@ static int load_multiboot(void *fw_cfg, } if (!(flags & 0x00010000)) { /* MULTIBOOT_HEADER_HAS_ADDR */ uint64_t elf_entry; + uint64_t elf_low, elf_high; int kernel_size; fclose(f); - kernel_size = load_elf(kernel_filename, 0, &elf_entry, NULL, NULL, + kernel_size = load_elf(kernel_filename, 0, &elf_entry, &elf_low, &elf_high, 0, ELF_MACHINE, 0); if (kernel_size < 0) { fprintf(stderr, "Error while loading elf kernel\n"); exit(1); } - mh_load_addr = mh_entry_addr = elf_entry; - mb_kernel_size = kernel_size; + mh_load_addr = elf_low; + mb_kernel_size = elf_high - elf_low; + mh_entry_addr = elf_entry; mb_kernel_data = qemu_malloc(mb_kernel_size); - if (rom_copy(mb_kernel_data, elf_entry, kernel_size) != kernel_size) { + if (rom_copy(mb_kernel_data, mh_load_addr, mb_kernel_size) != mb_kernel_size) { fprintf(stderr, "Error while fetching elf kernel from rom\n"); exit(1); } @@ -1248,6 +1250,8 @@ static void pc_init1(ram_addr_t ram_size, } } } + + rom_load_fw(fw_cfg); } static void pc_init_pci(ram_addr_t ram_size, diff --git a/qemu/hw/pci-hotplug.c b/qemu/hw/pci-hotplug.c index f10c868e..ba13d2bc 100644 --- a/qemu/hw/pci-hotplug.c +++ b/qemu/hw/pci-hotplug.c @@ -199,14 +199,10 @@ static PCIDevice *qemu_pci_hot_add_storage(Monitor *mon, switch (type) { case IF_SCSI: - if (!dinfo) { - monitor_printf(mon, "scsi requires a backing file/device.\n"); - return NULL; - } dev = pci_create(bus, devfn, "lsi53c895a"); if (qdev_init(&dev->qdev) < 0) dev = NULL; - if (dev) { + if (dev && dinfo) { if (scsi_hot_add(&dev->qdev, dinfo, 0) != 0) { qdev_unplug(&dev->qdev); dev = NULL; diff --git a/qemu/hw/pci.c b/qemu/hw/pci.c index e2b38acb..4bf00a5e 100644 --- a/qemu/hw/pci.c +++ b/qemu/hw/pci.c @@ -26,6 +26,7 @@ #include "monitor.h" #include "net.h" #include "sysemu.h" +#include "loader.h" //#define DEBUG_PCI #ifdef DEBUG_PCI @@ -62,12 +63,14 @@ static struct BusInfo pci_bus_info = { .print_dev = pcibus_dev_print, .props = (Property[]) { DEFINE_PROP_PCI_DEVFN("addr", PCIDevice, devfn, -1), + DEFINE_PROP_STRING("romfile", PCIDevice, romfile), DEFINE_PROP_END_OF_LIST() } }; static void pci_update_mappings(PCIDevice *d); static void pci_set_irq(void *opaque, int irq_num, int level); +static int pci_add_option_rom(PCIDevice *pdev); target_phys_addr_t pci_mem_base; static uint16_t pci_default_sub_vendor_id = PCI_SUBVENDOR_ID_REDHAT_QUMRANET; @@ -518,8 +521,7 @@ static void pci_init_wmask(PCIDevice *dev) dev->wmask[PCI_CACHE_LINE_SIZE] = 0xff; dev->wmask[PCI_INTERRUPT_LINE] = 0xff; pci_set_word(dev->wmask + PCI_COMMAND, - PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | - PCI_COMMAND_INTX_DISABLE); + PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER); memset(dev->wmask + PCI_CONFIG_HEADER_SIZE, 0xff, config_size - PCI_CONFIG_HEADER_SIZE); @@ -944,25 +946,6 @@ static void pci_update_mappings(PCIDevice *d) } } -static inline int pci_irq_disabled(PCIDevice *d) -{ - return pci_get_word(d->config + PCI_COMMAND) & PCI_COMMAND_INTX_DISABLE; -} - -/* Called after interrupt disabled field update in config space, - * assert/deassert interrupts if necessary. - * Gets original interrupt disable bit value (before update). */ -static void pci_update_irq_disabled(PCIDevice *d, int was_irq_disabled) -{ - int i, disabled = pci_irq_disabled(d); - if (disabled == was_irq_disabled) - return; - for (i = 0; i < PCI_NUM_PINS; ++i) { - int state = pci_irq_state(d, i); - pci_change_irq_level(d, i, disabled ? -state : state); - } -} - uint32_t pci_default_read_config(PCIDevice *d, uint32_t address, int len) { @@ -975,7 +958,7 @@ uint32_t pci_default_read_config(PCIDevice *d, void pci_default_write_config(PCIDevice *d, uint32_t addr, uint32_t val, int l) { - int i, was_irq_disabled = pci_irq_disabled(d); + int i; uint32_t config_size = pci_config_size(d); for (i = 0; i < l && addr + i < config_size; val >>= 8, ++i) { @@ -987,9 +970,6 @@ void pci_default_write_config(PCIDevice *d, uint32_t addr, uint32_t val, int l) ranges_overlap(addr, l, PCI_ROM_ADDRESS1, 4) || range_covers_byte(addr, l, PCI_COMMAND)) pci_update_mappings(d); - - if (range_covers_byte(addr, l, PCI_COMMAND)) - pci_update_irq_disabled(d, was_irq_disabled); } /***********************************************************/ @@ -1007,8 +987,6 @@ static void pci_set_irq(void *opaque, int irq_num, int level) pci_set_irq_state(pci_dev, irq_num, level); pci_update_irq_status(pci_dev); - if (pci_irq_disabled(pci_dev)) - return; pci_change_irq_level(pci_dev, irq_num, change); } @@ -1386,6 +1364,12 @@ static int pci_qdev_init(DeviceState *qdev, DeviceInfo *base) rc = info->init(pci_dev); if (rc != 0) return rc; + + /* rom loading */ + if (pci_dev->romfile == NULL && info->romfile != NULL) + pci_dev->romfile = qemu_strdup(info->romfile); + pci_add_option_rom(pci_dev); + if (qdev->hotplugged) bus->hotplug(pci_dev, 1); return 0; @@ -1463,6 +1447,50 @@ static uint8_t pci_find_capability_list(PCIDevice *pdev, uint8_t cap_id, return next; } +static void pci_map_option_rom(PCIDevice *pdev, int region_num, pcibus_t addr, pcibus_t size, int type) +{ + cpu_register_physical_memory(addr, size, pdev->rom_offset); +} + +/* Add an option rom for the device */ +static int pci_add_option_rom(PCIDevice *pdev) +{ + int size; + char *path; + void *ptr; + + if (!pdev->romfile) + return 0; + if (strlen(pdev->romfile) == 0) + return 0; + + path = qemu_find_file(QEMU_FILE_TYPE_BIOS, pdev->romfile); + if (path == NULL) { + path = qemu_strdup(pdev->romfile); + } + + size = get_image_size(path); + if (size < 0) { + qemu_error("%s: failed to find romfile \"%s\"\n", __FUNCTION__, + pdev->romfile); + return -1; + } + if (size & (size - 1)) { + size = 1 << qemu_fls(size); + } + + pdev->rom_offset = qemu_ram_alloc(size); + + ptr = qemu_get_ram_ptr(pdev->rom_offset); + load_image(path, ptr); + qemu_free(path); + + pci_register_bar(pdev, PCI_ROM_SLOT, size, + 0, pci_map_option_rom); + + return 0; +} + /* Reserve space and add capability to the linked list in pci config space */ int pci_add_capability(PCIDevice *pdev, uint8_t cap_id, uint8_t size) { diff --git a/qemu/hw/pci.h b/qemu/hw/pci.h index d279e3f7..e52e6323 100644 --- a/qemu/hw/pci.h +++ b/qemu/hw/pci.h @@ -101,7 +101,6 @@ typedef struct PCIIORegion { #define PCI_COMMAND_IO 0x1 /* Enable response in I/O space */ #define PCI_COMMAND_MEMORY 0x2 /* Enable response in Memory space */ #define PCI_COMMAND_MASTER 0x4 /* Enable bus master */ -#define PCI_COMMAND_INTX_DISABLE 0x400 /* INTx Emulation Disable */ #define PCI_STATUS 0x06 /* 16 bits */ #define PCI_STATUS_INTERRUPT 0x08 #define PCI_REVISION_ID 0x08 /* 8 bits */ @@ -243,6 +242,10 @@ struct PCIDevice { uint32_t msix_bar_size; /* Version id needed for VMState */ int32_t version_id; + + /* Location of option rom */ + char *romfile; + ram_addr_t rom_offset; }; PCIDevice *pci_register_device(PCIBus *bus, const char *name, @@ -381,6 +384,9 @@ typedef struct { /* pcie stuff */ int is_express; /* is this device pci express? */ + + /* rom bar */ + const char *romfile; } PCIDeviceInfo; void pci_qdev_register(PCIDeviceInfo *info); diff --git a/qemu/hw/qdev-properties.c b/qemu/hw/qdev-properties.c index f7ac01b4..a5cd4141 100644 --- a/qemu/hw/qdev-properties.c +++ b/qemu/hw/qdev-properties.c @@ -500,7 +500,12 @@ int qdev_prop_parse(DeviceState *dev, const char *name, const char *value) dev->info->name, name); return -1; } - return prop->info->parse(dev, prop, value); + if (prop->info->parse(dev, prop, value) != 0) { + fprintf(stderr, "property \"%s.%s\": failed to parse \"%s\"\n", + dev->info->name, name, value); + return -1; + } + return 0; } void qdev_prop_set(DeviceState *dev, const char *name, void *src, enum PropertyType type) @@ -619,7 +624,7 @@ void qdev_prop_set_globals(DeviceState *dev) continue; } if (qdev_prop_parse(dev, prop->property, prop->value) != 0) { - abort(); + exit(1); } } } diff --git a/qemu/hw/rtl8139.c b/qemu/hw/rtl8139.c index 649e1312..83b6cb66 100644 --- a/qemu/hw/rtl8139.c +++ b/qemu/hw/rtl8139.c @@ -3488,14 +3488,6 @@ static int pci_rtl8139_init(PCIDevice *dev) qemu_mod_timer(s->timer, rtl8139_get_next_tctr_time(s,qemu_get_clock(vm_clock))); #endif /* RTL8139_ONBOARD_TIMER */ - - if (!dev->qdev.hotplugged) { - static int loaded = 0; - if (!loaded) { - rom_add_option("pxe-rtl8139.bin"); - loaded = 1; - } - } return 0; } @@ -3506,6 +3498,7 @@ static PCIDeviceInfo rtl8139_info = { .qdev.vmsd = &vmstate_rtl8139, .init = pci_rtl8139_init, .exit = pci_rtl8139_uninit, + .romfile = "pxe-rtl8139.bin", .qdev.props = (Property[]) { DEFINE_NIC_PROPERTIES(RTL8139State, conf), DEFINE_PROP_END_OF_LIST(), diff --git a/qemu/hw/s390-virtio-bus.c b/qemu/hw/s390-virtio-bus.c index 493e4dae..dc154edb 100644 --- a/qemu/hw/s390-virtio-bus.c +++ b/qemu/hw/s390-virtio-bus.c @@ -307,7 +307,7 @@ static void virtio_s390_notify(void *opaque, uint16_t vector) uint64_t token = s390_virtio_device_vq_token(dev, vector); /* XXX kvm dependency! */ - kvm_s390_virtio_irq(s390_cpu_addr2state(0), 1, token); + kvm_s390_virtio_irq(s390_cpu_addr2state(0), 0, token); } /**************** S390 Virtio Bus Device Descriptions *******************/ diff --git a/qemu/hw/s390-virtio.c b/qemu/hw/s390-virtio.c index 51c032ad..0fa6ba68 100644 --- a/qemu/hw/s390-virtio.c +++ b/qemu/hw/s390-virtio.c @@ -142,6 +142,13 @@ static void s390_init(ram_addr_t ram_size, ram_addr_t initrd_size = 0; int i; + /* XXX we only work on KVM for now */ + + if (!kvm_enabled()) { + fprintf(stderr, "The S390 target only works with KVM enabled\n"); + exit(1); + } + /* get a BUS */ s390_bus = s390_virtio_bus_init(&ram_size); @@ -181,7 +188,7 @@ static void s390_init(ram_addr_t ram_size, cpu_synchronize_state(env); env->psw.addr = KERN_IMAGE_START; - env->psw.mask = 0x0000000180000000UL; + env->psw.mask = 0x0000000180000000ULL; } if (initrd_filename) { @@ -201,7 +208,11 @@ static void s390_init(ram_addr_t ram_size, } /* Create VirtIO console */ - qdev_init_nofail(qdev_create((BusState *)s390_bus, "virtio-console-s390")); + for(i = 0; i < MAX_VIRTIO_CONSOLES; i++) { + if (virtcon_hds[i]) { + qdev_init_nofail(qdev_create((BusState *)s390_bus, "virtio-console-s390")); + } + } /* Create VirtIO network adapters */ for(i = 0; i < nb_nics; i++) { @@ -209,7 +220,7 @@ static void s390_init(ram_addr_t ram_size, DeviceState *dev; if (!nd->model) { - nd->model = (char*)"virtio"; + nd->model = qemu_strdup("virtio"); } if (strcmp(nd->model, "virtio")) { @@ -245,7 +256,7 @@ static QEMUMachine s390_machine = { .init = s390_init, .no_serial = 1, .no_parallel = 1, - .use_virtcon = 1. + .use_virtcon = 1, .no_vga = 1, .max_cpus = 255, .is_default = 1, diff --git a/qemu/hw/scsi-disk.c b/qemu/hw/scsi-disk.c index 547e10ac..5537e115 100644 --- a/qemu/hw/scsi-disk.c +++ b/qemu/hw/scsi-disk.c @@ -5,6 +5,12 @@ * Based on code by Fabrice Bellard * * Written by Paul Brook + * Modifications: + * 2009-Dec-12 Artyom Tarasenko : implemented stamdard inquiry for the case + * when the allocation length of CDB is smaller + * than 36. + * 2009-Oct-13 Artyom Tarasenko : implemented the block descriptor in the + * MODE SENSE response. * * This code is licenced under the LGPL. * @@ -406,11 +412,6 @@ static int scsi_disk_emulate_inquiry(SCSIRequest *req, uint8_t *outbuf) return -1; } - if (req->cmd.xfer < 36) { - BADF("Error: Inquiry (STANDARD) buffer size %zd " - "is less than 36 (TODO: only 5 required)\n", req->cmd.xfer); - } - buflen = req->cmd.xfer; if (buflen > SCSI_MAX_INQUIRY_LEN) buflen = SCSI_MAX_INQUIRY_LEN; @@ -436,7 +437,15 @@ static int scsi_disk_emulate_inquiry(SCSIRequest *req, uint8_t *outbuf) Some later commands are also implemented. */ outbuf[2] = 3; outbuf[3] = 2; /* Format 2 */ - outbuf[4] = buflen - 5; /* Additional Length = (Len - 1) - 4 */ + + if (buflen > 36) { + outbuf[4] = buflen - 5; /* Additional Length = (Len - 1) - 4 */ + } else { + /* If the allocation length of CDB is too small, + the additional length is not adjusted */ + outbuf[4] = 36 - 5; + } + /* Sync data transfer and TCQ. */ outbuf[7] = 0x10 | (req->bus->tcq ? 0x02 : 0); return buflen; diff --git a/qemu/hw/unin_pci.c b/qemu/hw/unin_pci.c index 938b3e99..6aa3bd06 100644 --- a/qemu/hw/unin_pci.c +++ b/qemu/hw/unin_pci.c @@ -148,7 +148,7 @@ PCIBus *pci_pmac_init(qemu_irq *pic) /* Use values found on a real PowerMac */ /* Uninorth main bus */ - dev = qdev_create(NULL, "uni-north-main"); + dev = qdev_create(NULL, "uni-north"); qdev_init_nofail(dev); s = sysbus_from_qdev(dev); d = FROM_SYSBUS(UNINState, s); @@ -157,7 +157,7 @@ PCIBus *pci_pmac_init(qemu_irq *pic) pic, 11 << 3, 4); #if 0 - pci_create_simple(d->host_state.bus, 11 << 3, "uni-north-main"); + pci_create_simple(d->host_state.bus, 11 << 3, "uni-north"); #endif sysbus_mmio_map(s, 0, 0xf2800000); @@ -170,8 +170,8 @@ PCIBus *pci_pmac_init(qemu_irq *pic) #endif /* Uninorth AGP bus */ - pci_create_simple(d->host_state.bus, 11 << 3, "uni-north-AGP"); - dev = qdev_create(NULL, "uni-north-AGP"); + pci_create_simple(d->host_state.bus, 11 << 3, "uni-north-agp"); + dev = qdev_create(NULL, "uni-north-agp"); qdev_init_nofail(dev); s = sysbus_from_qdev(dev); sysbus_mmio_map(s, 0, 0xf0800000); @@ -180,8 +180,8 @@ PCIBus *pci_pmac_init(qemu_irq *pic) /* Uninorth internal bus */ #if 0 /* XXX: not needed for now */ - pci_create_simple(d->host_state.bus, 14 << 3, "uni-north-internal"); - dev = qdev_create(NULL, "uni-north-internal"); + pci_create_simple(d->host_state.bus, 14 << 3, "uni-north-pci"); + dev = qdev_create(NULL, "uni-north-pci"); qdev_init_nofail(dev); s = sysbus_from_qdev(dev); sysbus_mmio_map(s, 0, 0xf4800000); @@ -260,7 +260,7 @@ static int unin_internal_pci_host_init(PCIDevice *d) } static PCIDeviceInfo unin_main_pci_host_info = { - .qdev.name = "uni-north-main", + .qdev.name = "uni-north", .qdev.size = sizeof(PCIDevice), .init = unin_main_pci_host_init, }; @@ -272,29 +272,29 @@ static PCIDeviceInfo dec_21154_pci_host_info = { }; static PCIDeviceInfo unin_agp_pci_host_info = { - .qdev.name = "uni-north-AGP", + .qdev.name = "uni-north-agp", .qdev.size = sizeof(PCIDevice), .init = unin_agp_pci_host_init, }; static PCIDeviceInfo unin_internal_pci_host_info = { - .qdev.name = "uni-north-internal", + .qdev.name = "uni-north-pci", .qdev.size = sizeof(PCIDevice), .init = unin_internal_pci_host_init, }; static void unin_register_devices(void) { - sysbus_register_dev("uni-north-main", sizeof(UNINState), + sysbus_register_dev("uni-north", sizeof(UNINState), pci_unin_main_init_device); pci_qdev_register(&unin_main_pci_host_info); sysbus_register_dev("dec-21154", sizeof(UNINState), pci_dec_21154_init_device); pci_qdev_register(&dec_21154_pci_host_info); - sysbus_register_dev("uni-north-AGP", sizeof(UNINState), + sysbus_register_dev("uni-north-agp", sizeof(UNINState), pci_unin_agp_init_device); pci_qdev_register(&unin_agp_pci_host_info); - sysbus_register_dev("uni-north-internal", sizeof(UNINState), + sysbus_register_dev("uni-north-pci", sizeof(UNINState), pci_unin_internal_init_device); pci_qdev_register(&unin_internal_pci_host_info); } diff --git a/qemu/hw/usb-net.c b/qemu/hw/usb-net.c index 3412af34..89d371ba 100644 --- a/qemu/hw/usb-net.c +++ b/qemu/hw/usb-net.c @@ -1420,8 +1420,7 @@ static void usbnet_cleanup(VLANClientState *nc) { USBNetState *s = DO_UPCAST(NICState, nc, nc)->opaque; - rndis_clear_responsequeue(s); - qemu_free(s); + s->nic = NULL; } static void usb_net_handle_destroy(USBDevice *dev) @@ -1429,9 +1428,18 @@ static void usb_net_handle_destroy(USBDevice *dev) USBNetState *s = (USBNetState *) dev; /* TODO: remove the nd_table[] entry */ + rndis_clear_responsequeue(s); qemu_del_vlan_client(&s->nic->nc); } +static NetClientInfo net_usbnet_info = { + .type = NET_CLIENT_TYPE_NIC, + .size = sizeof(NICState), + .can_receive = usbnet_can_receive, + .receive = usbnet_receive, + .cleanup = usbnet_cleanup, +}; + static int usb_net_initfn(USBDevice *dev) { USBNetState *s = DO_UPCAST(USBNetState, dev, dev); @@ -1447,43 +1455,45 @@ static int usb_net_initfn(USBDevice *dev) s->media_state = 0; /* NDIS_MEDIA_STATE_CONNECTED */; s->filter = 0; s->vendorid = 0x1234; + + qemu_macaddr_default_if_unset(&s->conf.macaddr); + s->nic = qemu_new_nic(&net_usbnet_info, &s->conf, + s->dev.qdev.info->name, s->dev.qdev.id, s); + qemu_format_nic_info_str(&s->nic->nc, s->conf.macaddr.a); + snprintf(s->usbstring_mac, sizeof(s->usbstring_mac), + "%02x%02x%02x%02x%02x%02x", + 0x40, + s->conf.macaddr.a[1], + s->conf.macaddr.a[2], + s->conf.macaddr.a[3], + s->conf.macaddr.a[4], + s->conf.macaddr.a[5]); + return 0; } -static NetClientInfo net_usbnet_info = { - .type = NET_CLIENT_TYPE_NIC, - .size = sizeof(NICState), - .can_receive = usbnet_can_receive, - .receive = usbnet_receive, - .cleanup = usbnet_cleanup, -}; - -USBDevice *usb_net_init(NICInfo *nd) +static USBDevice *usb_net_init(const char *cmdline) { USBDevice *dev; - USBNetState *s; - - dev = usb_create_simple(NULL /* FIXME */, "usb-net"); - s = DO_UPCAST(USBNetState, dev, dev); + QemuOpts *opts; + int idx; - memcpy(s->conf.macaddr.a, nd->macaddr, sizeof(nd->macaddr)); - s->conf.vlan = nd->vlan; - s->conf.peer = nd->netdev; - - s->nic = qemu_new_nic(&net_usbnet_info, &s->conf, - nd->model, nd->name, s); + opts = qemu_opts_parse(&qemu_net_opts, cmdline, NULL); + if (!opts) { + return NULL; + } + qemu_opt_set(opts, "type", "nic"); + qemu_opt_set(opts, "model", "usb"); - qemu_format_nic_info_str(&s->nic->nc, s->conf.macaddr.a); + idx = net_client_init(NULL, opts, 0); + if (idx == -1) { + return NULL; + } - snprintf(s->usbstring_mac, sizeof(s->usbstring_mac), - "%02x%02x%02x%02x%02x%02x", - 0x40, s->conf.macaddr.a[1], s->conf.macaddr.a[2], - s->conf.macaddr.a[3], s->conf.macaddr.a[4], s->conf.macaddr.a[5]); - fprintf(stderr, "usbnet: initialized mac %02x:%02x:%02x:%02x:%02x:%02x\n", - s->conf.macaddr.a[0], s->conf.macaddr.a[1], s->conf.macaddr.a[2], - s->conf.macaddr.a[3], s->conf.macaddr.a[4], s->conf.macaddr.a[5]); - - return (USBDevice *) s; + dev = usb_create(NULL /* FIXME */, "usb-net"); + qdev_set_nic_properties(&dev->qdev, &nd_table[idx]); + qdev_init(&dev->qdev); + return dev; } static struct USBDeviceInfo net_info = { @@ -1496,6 +1506,12 @@ static struct USBDeviceInfo net_info = { .handle_control = usb_net_handle_control, .handle_data = usb_net_handle_data, .handle_destroy = usb_net_handle_destroy, + .usbdevice_name = "net", + .usbdevice_init = usb_net_init, + .qdev.props = (Property[]) { + DEFINE_NIC_PROPERTIES(USBNetState, conf), + DEFINE_PROP_END_OF_LIST(), + } }; static void usb_net_register_devices(void) diff --git a/qemu/hw/usb.h b/qemu/hw/usb.h index 06845885..106d1744 100644 --- a/qemu/hw/usb.h +++ b/qemu/hw/usb.h @@ -258,9 +258,6 @@ void usb_host_info(Monitor *mon); /* usb-hid.c */ void usb_hid_datain_cb(USBDevice *dev, void *opaque, void (*datain)(void *)); -/* usb-net.c */ -USBDevice *usb_net_init(NICInfo *nd); - /* usb-bt.c */ USBDevice *usb_bt_init(HCIInfo *hci); diff --git a/qemu/hw/vga-isa.c b/qemu/hw/vga-isa.c index 5f299041..79371441 100644 --- a/qemu/hw/vga-isa.c +++ b/qemu/hw/vga-isa.c @@ -42,11 +42,7 @@ int isa_vga_init(void) s->ds = graphic_console_init(s->update, s->invalidate, s->screen_dump, s->text_update, s); -#ifdef CONFIG_BOCHS_VBE - /* XXX: use optimized standard vga accesses */ - cpu_register_physical_memory(VBE_DISPI_LFB_PHYSICAL_ADDRESS, - VGA_RAM_SIZE, s->vram_offset); -#endif + vga_init_vbe(s); /* ROM BIOS */ rom_add_vga(VGABIOS_FILENAME); return 0; diff --git a/qemu/hw/vga-pci.c b/qemu/hw/vga-pci.c index e8cc0247..eef78ed0 100644 --- a/qemu/hw/vga-pci.c +++ b/qemu/hw/vga-pci.c @@ -106,12 +106,7 @@ static int pci_vga_initfn(PCIDevice *dev) PCI_BASE_ADDRESS_MEM_PREFETCH, vga_map); } -#ifdef CONFIG_BOCHS_VBE - /* XXX: use optimized standard vga accesses */ - cpu_register_physical_memory(VBE_DISPI_LFB_PHYSICAL_ADDRESS, - VGA_RAM_SIZE, s->vram_offset); -#endif - + vga_init_vbe(s); /* ROM BIOS */ rom_add_vga(VGABIOS_FILENAME); return 0; diff --git a/qemu/hw/vga.c b/qemu/hw/vga.c index 1de3b509..c2acd76a 100644 --- a/qemu/hw/vga.c +++ b/qemu/hw/vga.c @@ -1600,6 +1600,14 @@ static void vga_sync_dirty_bitmap(VGACommonState *s) cpu_physical_sync_dirty_bitmap(isa_mem_base + 0xa0000, 0xa8000); cpu_physical_sync_dirty_bitmap(isa_mem_base + 0xa8000, 0xb0000); } + +#ifdef CONFIG_BOCHS_VBE + if (s->vbe_mapped) { + cpu_physical_sync_dirty_bitmap(VBE_DISPI_LFB_PHYSICAL_ADDRESS, + VBE_DISPI_LFB_PHYSICAL_ADDRESS + s->vram_size); + } +#endif + } void vga_dirty_log_start(VGACommonState *s) @@ -1611,6 +1619,35 @@ void vga_dirty_log_start(VGACommonState *s) kvm_log_start(isa_mem_base + 0xa0000, 0x8000); kvm_log_start(isa_mem_base + 0xa8000, 0x8000); } + +#ifdef CONFIG_BOCHS_VBE + if (kvm_enabled() && s->vbe_mapped) { + kvm_log_start(VBE_DISPI_LFB_PHYSICAL_ADDRESS, s->vram_size); + } +#endif +} + +void vga_dirty_log_stop(VGACommonState *s) +{ + if (kvm_enabled() && s->map_addr) + kvm_log_stop(s->map_addr, s->map_end - s->map_addr); + + if (kvm_enabled() && s->lfb_vram_mapped) { + kvm_log_stop(isa_mem_base + 0xa0000, 0x80000); + kvm_log_stop(isa_mem_base + 0xa8000, 0x80000); + } + +#ifdef CONFIG_BOCHS_VBE + if (kvm_enabled() && s->vbe_mapped) { + kvm_log_stop(VBE_DISPI_LFB_PHYSICAL_ADDRESS, s->vram_size); + } +#endif +} + +void vga_dirty_log_restart(VGACommonState *s) +{ + vga_dirty_log_stop(s); + vga_dirty_log_start(s); } /* @@ -2313,6 +2350,15 @@ void vga_init(VGACommonState *s) qemu_register_coalesced_mmio(isa_mem_base + 0x000a0000, 0x20000); } +void vga_init_vbe(VGACommonState *s) +{ +#ifdef CONFIG_BOCHS_VBE + /* XXX: use optimized standard vga accesses */ + cpu_register_physical_memory(VBE_DISPI_LFB_PHYSICAL_ADDRESS, + VGA_RAM_SIZE, s->vram_offset); + s->vbe_mapped = 1; +#endif +} /********************************************************/ /* vga screen dump */ diff --git a/qemu/hw/vga_int.h b/qemu/hw/vga_int.h index c03c220f..23a42efc 100644 --- a/qemu/hw/vga_int.h +++ b/qemu/hw/vga_int.h @@ -71,8 +71,8 @@ uint16_t vbe_regs[VBE_DISPI_INDEX_NB]; \ uint32_t vbe_start_addr; \ uint32_t vbe_line_offset; \ - uint32_t vbe_bank_mask; - + uint32_t vbe_bank_mask; \ + int vbe_mapped; #else #define VGA_STATE_COMMON_BOCHS_VBE @@ -194,6 +194,8 @@ void vga_init(VGACommonState *s); void vga_common_reset(VGACommonState *s); void vga_dirty_log_start(VGACommonState *s); +void vga_dirty_log_stop(VGACommonState *s); +void vga_dirty_log_restart(VGACommonState *s); extern const VMStateDescription vmstate_vga_common; uint32_t vga_ioport_read(void *opaque, uint32_t addr); @@ -217,6 +219,7 @@ void vga_draw_cursor_line_32(uint8_t *d1, const uint8_t *src1, unsigned int color_xor); int vga_ioport_invalid(VGACommonState *s, uint32_t addr); +void vga_init_vbe(VGACommonState *s); extern const uint8_t sr_mask[8]; extern const uint8_t gr_mask[16]; diff --git a/qemu/hw/virtio-pci.c b/qemu/hw/virtio-pci.c index 99ce401b..37a079e7 100644 --- a/qemu/hw/virtio-pci.c +++ b/qemu/hw/virtio-pci.c @@ -518,14 +518,6 @@ static int virtio_net_init_pci(PCIDevice *pci_dev) /* make the actual value visible */ proxy->nvectors = vdev->nvectors; - - if (!pci_dev->qdev.hotplugged) { - static int loaded = 0; - if (!loaded) { - rom_add_option("pxe-virtio.bin"); - loaded = 1; - } - } return 0; } @@ -569,6 +561,7 @@ static PCIDeviceInfo virtio_info[] = { .qdev.size = sizeof(VirtIOPCIProxy), .init = virtio_net_init_pci, .exit = virtio_net_exit_pci, + .romfile = "pxe-virtio.bin", .qdev.props = (Property[]) { DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors, 3), DEFINE_NIC_PROPERTIES(VirtIOPCIProxy, nic), diff --git a/qemu/hw/vmware_vga.c b/qemu/hw/vmware_vga.c index 3a8ca234..d93c5449 100644 --- a/qemu/hw/vmware_vga.c +++ b/qemu/hw/vmware_vga.c @@ -78,6 +78,11 @@ struct vmsvga_state_s { int syncing; int fb_size; + ram_addr_t fifo_offset; + uint8_t *fifo_ptr; + unsigned int fifo_size; + target_phys_addr_t fifo_base; + union { uint32_t *fifo; @@ -486,7 +491,7 @@ struct vmsvga_cursor_definition_s { int hot_x; int hot_y; uint32_t mask[1024]; - uint32_t image[1024]; + uint32_t image[4096]; }; #define SVGA_BITMAP_SIZE(w, h) ((((w) + 31) >> 5) * (h)) @@ -704,7 +709,7 @@ static uint32_t vmsvga_value_read(void *opaque, uint32_t address) return 0x0; case SVGA_REG_VRAM_SIZE: - return s->vga.vram_size - SVGA_FIFO_SIZE; + return s->vga.vram_size; case SVGA_REG_FB_SIZE: return s->fb_size; @@ -725,10 +730,10 @@ static uint32_t vmsvga_value_read(void *opaque, uint32_t address) return caps; case SVGA_REG_MEM_START: - return s->vram_base + s->vga.vram_size - SVGA_FIFO_SIZE; + return s->fifo_base; case SVGA_REG_MEM_SIZE: - return SVGA_FIFO_SIZE; + return s->fifo_size; case SVGA_REG_CONFIG_DONE: return s->config; @@ -807,8 +812,12 @@ static void vmsvga_value_write(void *opaque, uint32_t address, uint32_t value) s->height = -1; s->invalidated = 1; s->vga.invalidate(&s->vga); - if (s->enable) - s->fb_size = ((s->depth + 7) >> 3) * s->new_width * s->new_height; + if (s->enable) { + s->fb_size = ((s->depth + 7) >> 3) * s->new_width * s->new_height; + vga_dirty_log_stop(&s->vga); + } else { + vga_dirty_log_start(&s->vga); + } break; case SVGA_REG_WIDTH: @@ -831,7 +840,7 @@ static void vmsvga_value_write(void *opaque, uint32_t address, uint32_t value) case SVGA_REG_CONFIG_DONE: if (value) { - s->fifo = (uint32_t *) &s->vga.vram_ptr[s->vga.vram_size - SVGA_FIFO_SIZE]; + s->fifo = (uint32_t *) s->fifo_ptr; /* Check range and alignment. */ if ((CMD(min) | CMD(max) | CMD(next_cmd) | CMD(stop)) & 3) @@ -914,7 +923,7 @@ static void vmsvga_value_write(void *opaque, uint32_t address, uint32_t value) } } #endif -} + } } static uint32_t vmsvga_bios_read(void *opaque, uint32_t address) @@ -970,8 +979,8 @@ static void vmsvga_reset(struct vmsvga_state_s *s) s->width = -1; s->height = -1; s->svgaid = SVGA_ID; - s->depth = 24; - s->bypp = (s->depth + 7) >> 3; + s->depth = ds_get_bits_per_pixel(s->vga.ds); + s->bypp = ds_get_bytes_per_pixel(s->vga.ds); s->cursor.on = 0; s->redraw_fifo_first = 0; s->redraw_fifo_last = 0; @@ -1003,6 +1012,8 @@ static void vmsvga_reset(struct vmsvga_state_s *s) break; } s->syncing = 0; + + vga_dirty_log_start(&s->vga); } static void vmsvga_invalidate_display(void *opaque) @@ -1119,7 +1130,7 @@ static int vmsvga_post_load(void *opaque, int version_id) s->invalidated = 1; if (s->config) - s->fifo = (uint32_t *) &s->vga.vram_ptr[s->vga.vram_size - SVGA_FIFO_SIZE]; + s->fifo = (uint32_t *) s->fifo_ptr; return 0; } @@ -1169,23 +1180,25 @@ static void vmsvga_init(struct vmsvga_state_s *s, int vga_ram_size) s->scratch_size = SVGA_SCRATCH_SIZE; s->scratch = qemu_malloc(s->scratch_size * 4); - vmsvga_reset(s); + s->vga.ds = graphic_console_init(vmsvga_update_display, + vmsvga_invalidate_display, + vmsvga_screen_dump, + vmsvga_text_update, s); + + + s->fifo_size = SVGA_FIFO_SIZE; + s->fifo_offset = qemu_ram_alloc(s->fifo_size); + s->fifo_ptr = qemu_get_ram_ptr(s->fifo_offset); vga_common_init(&s->vga, vga_ram_size); vga_init(&s->vga); vmstate_register(0, &vmstate_vga_common, &s->vga); - s->vga.ds = graphic_console_init(vmsvga_update_display, - vmsvga_invalidate_display, - vmsvga_screen_dump, - vmsvga_text_update, s); + vga_init_vbe(&s->vga); -#ifdef CONFIG_BOCHS_VBE - /* XXX: use optimized standard vga accesses */ - cpu_register_physical_memory(VBE_DISPI_LFB_PHYSICAL_ADDRESS, - vga_ram_size, s->vga.vram_offset); -#endif rom_add_vga(VGABIOS_FILENAME); + + vmsvga_reset(s); } static void pci_vmsvga_map_ioport(PCIDevice *pci_dev, int region_num, @@ -1224,6 +1237,23 @@ static void pci_vmsvga_map_mem(PCIDevice *pci_dev, int region_num, #endif cpu_register_physical_memory(s->vram_base, s->vga.vram_size, iomemtype); + + s->vga.map_addr = addr; + s->vga.map_end = addr + s->vga.vram_size; + vga_dirty_log_restart(&s->vga); +} + +static void pci_vmsvga_map_fifo(PCIDevice *pci_dev, int region_num, + pcibus_t addr, pcibus_t size, int type) +{ + struct pci_vmsvga_state_s *d = (struct pci_vmsvga_state_s *) pci_dev; + struct vmsvga_state_s *s = &d->chip; + ram_addr_t iomemtype; + + s->fifo_base = addr; + iomemtype = s->fifo_offset | IO_MEM_RAM; + cpu_register_physical_memory(s->fifo_base, s->fifo_size, + iomemtype); } static int pci_vmsvga_initfn(PCIDevice *dev) @@ -1249,6 +1279,9 @@ static int pci_vmsvga_initfn(PCIDevice *dev) pci_register_bar(&s->card, 1, VGA_RAM_SIZE, PCI_BASE_ADDRESS_MEM_PREFETCH, pci_vmsvga_map_mem); + pci_register_bar(&s->card, 2, SVGA_FIFO_SIZE, + PCI_BASE_ADDRESS_MEM_PREFETCH, pci_vmsvga_map_fifo); + vmsvga_init(&s->chip, VGA_RAM_SIZE); return 0; @@ -1256,11 +1289,11 @@ static int pci_vmsvga_initfn(PCIDevice *dev) void pci_vmsvga_init(PCIBus *bus) { - pci_create_simple(bus, -1, "QEMUware SVGA"); + pci_create_simple(bus, -1, "vmware-svga"); } static PCIDeviceInfo vmsvga_info = { - .qdev.name = "QEMUware SVGA", + .qdev.name = "vmware-svga", .qdev.size = sizeof(struct pci_vmsvga_state_s), .qdev.vmsd = &vmstate_vmware_vga, .init = pci_vmsvga_initfn, diff --git a/qemu/migration-unix.c b/qemu/migration-unix.c index 783228b3..a141dbbb 100644 --- a/qemu/migration-unix.c +++ b/qemu/migration-unix.c @@ -112,10 +112,6 @@ MigrationState *unix_start_outgoing_migration(Monitor *mon, socket_set_nonblock(s->fd); - if (!detach) { - migrate_fd_monitor_suspend(s, mon); - } - do { ret = connect(s->fd, (struct sockaddr *)&addr, sizeof(addr)); if (ret == -1) @@ -128,7 +124,13 @@ MigrationState *unix_start_outgoing_migration(Monitor *mon, if (ret < 0 && ret != -EINPROGRESS && ret != -EWOULDBLOCK) { dprintf("connect failed\n"); goto err_after_open; - } else if (ret >= 0) + } + + if (!detach) { + migrate_fd_monitor_suspend(s, mon); + } + + if (ret >= 0) migrate_fd_connect(s); return &s->mig_state; diff --git a/qemu/migration.c b/qemu/migration.c index fda61e64..598f8df5 100644 --- a/qemu/migration.c +++ b/qemu/migration.c @@ -106,7 +106,7 @@ void do_migrate_cancel(Monitor *mon, const QDict *qdict, QObject **ret_data) s->cancel(s); } -void do_migrate_set_speed(Monitor *mon, const QDict *qdict, QObject **ret_data) +void do_migrate_set_speed(Monitor *mon, const QDict *qdict) { double d; char *ptr; diff --git a/qemu/migration.h b/qemu/migration.h index 3ac208bf..cbd456b9 100644 --- a/qemu/migration.h +++ b/qemu/migration.h @@ -56,7 +56,7 @@ void do_migrate(Monitor *mon, const QDict *qdict, QObject **ret_data); void do_migrate_cancel(Monitor *mon, const QDict *qdict, QObject **ret_data); -void do_migrate_set_speed(Monitor *mon, const QDict *qdict, QObject **ret_data); +void do_migrate_set_speed(Monitor *mon, const QDict *qdict); uint64_t migrate_max_downtime(void); diff --git a/qemu/monitor.c b/qemu/monitor.c index 781f8431..1ba67840 100644 --- a/qemu/monitor.c +++ b/qemu/monitor.c @@ -140,6 +140,9 @@ static inline int monitor_ctrl_mode(const Monitor *mon) static void monitor_read_command(Monitor *mon, int show_prompt) { + if (!mon->rs) + return; + readline_start(mon->rs, "(qemu) ", 0, monitor_command_cb, NULL); if (show_prompt) readline_show_prompt(mon->rs); @@ -174,9 +177,6 @@ static void monitor_puts(Monitor *mon, const char *str) { char c; - if (!mon) - return; - for(;;) { c = *str++; if (c == '\0') @@ -192,6 +192,9 @@ static void monitor_puts(Monitor *mon, const char *str) void monitor_vprintf(Monitor *mon, const char *fmt, va_list ap) { + if (!mon) + return; + if (mon->mc && !mon->mc->print_enabled) { qemu_error_new(QERR_UNDEFINED_ERROR); } else { @@ -280,10 +283,12 @@ static void monitor_protocol_emitter(Monitor *mon, QObject *data) if (!monitor_has_error(mon)) { /* success response */ if (data) { + assert(qobject_type(data) == QTYPE_QDICT); qobject_incref(data); qdict_put_obj(qmp, "return", data); } else { - qdict_put(qmp, "return", qstring_from_str("OK")); + /* return an empty QDict by default */ + qdict_put(qmp, "return", qdict_new()); } } else { /* error response */ @@ -867,7 +872,7 @@ static void do_eject(Monitor *mon, const QDict *qdict, QObject **ret_data) { BlockDriverState *bs; int force = qdict_get_int(qdict, "force"); - const char *filename = qdict_get_str(qdict, "filename"); + const char *filename = qdict_get_str(qdict, "device"); bs = bdrv_find(filename); if (!bs) { @@ -2056,14 +2061,33 @@ static void do_info_status(Monitor *mon, QObject **ret_data) vm_running, singlestep); } +static ram_addr_t balloon_get_value(void) +{ + ram_addr_t actual; + + if (kvm_enabled() && !kvm_has_sync_mmu()) { + qemu_error_new(QERR_KVM_MISSING_CAP, "synchronous MMU", "balloon"); + return 0; + } + + actual = qemu_balloon_status(); + if (actual == 0) { + qemu_error_new(QERR_DEVICE_NOT_ACTIVE, "balloon"); + return 0; + } + + return actual; +} + /** * do_balloon(): Request VM to change its memory allocation */ static void do_balloon(Monitor *mon, const QDict *qdict, QObject **ret_data) { - int value = qdict_get_int(qdict, "value"); - ram_addr_t target = value; - qemu_balloon(target << 20); + if (balloon_get_value()) { + /* ballooning is active */ + qemu_balloon(qdict_get_int(qdict, "value")); + } } static void monitor_print_balloon(Monitor *mon, const QObject *data) @@ -2091,14 +2115,11 @@ static void do_info_balloon(Monitor *mon, QObject **ret_data) { ram_addr_t actual; - actual = qemu_balloon_status(); - if (kvm_enabled() && !kvm_has_sync_mmu()) - qemu_error_new(QERR_KVM_MISSING_CAP, "synchronous MMU", "balloon"); - else if (actual == 0) - qemu_error_new(QERR_DEVICE_NOT_ACTIVE, "balloon"); - else + actual = balloon_get_value(); + if (actual != 0) { *ret_data = qobject_from_jsonf("{ 'balloon': %" PRId64 "}", (int64_t) actual); + } } static qemu_acl *find_acl(Monitor *mon, const char *name) @@ -3482,6 +3503,7 @@ static const mon_cmd_t *monitor_parse_command(Monitor *mon, break; case 'i': case 'l': + case 'M': { int64_t val; @@ -3512,6 +3534,8 @@ static const mon_cmd_t *monitor_parse_command(Monitor *mon, monitor_printf(mon, "\'%s\' has failed: ", cmdname); monitor_printf(mon, "integer is for 32-bit values\n"); goto fail; + } else if (c == 'M') { + val <<= 20; } qdict_put(qdict, key, qint_from_int(val)); } @@ -3847,7 +3871,7 @@ static int monitor_can_read(void *opaque) { Monitor *mon = opaque; - return (mon->suspend_cnt == 0) ? 128 : 0; + return (mon->suspend_cnt == 0) ? 1 : 0; } typedef struct CmdArgs { @@ -3916,6 +3940,7 @@ static int check_arg(const CmdArgs *cmd_args, QDict *args) } case 'i': case 'l': + case 'M': if (qobject_type(value) != QTYPE_QINT) { qemu_error_new(QERR_INVALID_PARAMETER_TYPE, name, "int"); return -1; @@ -4053,7 +4078,7 @@ static void handle_qmp_command(JSONMessageParser *parser, QList *tokens) qobject_from_jsonf("{ 'item': %s }", info_item)); } else { cmd = monitor_find_command(cmd_name); - if (!cmd) { + if (!cmd || !monitor_handler_ported(cmd)) { qemu_error_new(QERR_COMMAND_NOT_FOUND, cmd_name); goto err_input; } diff --git a/qemu/osdep.c b/qemu/osdep.c index f5fc1e29..c80382cb 100644 --- a/qemu/osdep.c +++ b/qemu/osdep.c @@ -265,13 +265,15 @@ int qemu_pipe(int pipefd[2]) #ifdef CONFIG_PIPE2 ret = pipe2(pipefd, O_CLOEXEC); -#else + if (ret != -1 || errno != ENOSYS) { + return ret; + } +#endif ret = pipe(pipefd); if (ret == 0) { qemu_set_cloexec(pipefd[0]); qemu_set_cloexec(pipefd[1]); } -#endif return ret; } @@ -286,12 +288,14 @@ int qemu_socket(int domain, int type, int protocol) #ifdef SOCK_CLOEXEC ret = socket(domain, type | SOCK_CLOEXEC, protocol); -#else + if (ret != -1 || errno != EINVAL) { + return ret; + } +#endif ret = socket(domain, type, protocol); if (ret >= 0) { qemu_set_cloexec(ret); } -#endif return ret; } @@ -305,12 +309,14 @@ int qemu_accept(int s, struct sockaddr *addr, socklen_t *addrlen) #ifdef CONFIG_ACCEPT4 ret = accept4(s, addr, addrlen, SOCK_CLOEXEC); -#else + if (ret != -1 || errno != EINVAL) { + return ret; + } +#endif ret = accept(s, addr, addrlen); if (ret >= 0) { qemu_set_cloexec(ret); } -#endif return ret; } diff --git a/qemu/pc-bios/bios.bin b/qemu/pc-bios/bios.bin index 29495801950660c19630444e410ff30d673e46af..827327db9e0bb29c48efa92b40a6f489fc1500ed 100644 GIT binary patch delta 29110 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 SYGqb{table[hash], entry, next); + qdict->size++; } - - qdict->size++; } /** diff --git a/qemu/qemu-config.h b/qemu/qemu-config.h index 34dfadc5..dd89ae46 100644 --- a/qemu/qemu-config.h +++ b/qemu/qemu-config.h @@ -7,6 +7,7 @@ extern QemuOptsList qemu_device_opts; extern QemuOptsList qemu_netdev_opts; extern QemuOptsList qemu_net_opts; extern QemuOptsList qemu_rtc_opts; +extern QemuOptsList qemu_global_opts; extern QemuOptsList qemu_mon_opts; int qemu_set_option(const char *str); diff --git a/qemu/qemu-io.c b/qemu/qemu-io.c index 3f7f222a..a0307ae8 100644 --- a/qemu/qemu-io.c +++ b/qemu/qemu-io.c @@ -129,7 +129,8 @@ create_iovec(QEMUIOVector *qiov, char **argv, int nr_iov, int pattern) { size_t *sizes = calloc(nr_iov, sizeof(size_t)); size_t count = 0; - void *buf, *p; + void *buf = NULL; + void *p; int i; for (i = 0; i < nr_iov; i++) { @@ -139,19 +140,19 @@ create_iovec(QEMUIOVector *qiov, char **argv, int nr_iov, int pattern) len = cvtnum(arg); if (len < 0) { printf("non-numeric length argument -- %s\n", arg); - return NULL; + goto fail; } /* should be SIZE_T_MAX, but that doesn't exist */ if (len > UINT_MAX) { printf("too large length argument -- %s\n", arg); - return NULL; + goto fail; } if (len & 0x1ff) { printf("length argument %lld is not sector aligned\n", len); - return NULL; + goto fail; } sizes[i] = len; @@ -167,6 +168,7 @@ create_iovec(QEMUIOVector *qiov, char **argv, int nr_iov, int pattern) p += sizes[i]; } +fail: free(sizes); return buf; } diff --git a/qemu/qemu-monitor.h b/qemu/qemu-monitor.h index 16ca57de..dffa657a 100644 --- a/qemu/qemu-monitor.h +++ b/qemu/qemu-monitor.h @@ -40,7 +40,7 @@ { .name = "eject", -.args_type = "force:-f,filename:B", +.args_type = "force:-f,device:B", .params = "[-f] device", .help = "eject a removable medium (use -f to force it)", .user_print = monitor_user_noop, @@ -394,8 +394,7 @@ .args_type = "value:s", .params = "value", .help = "set maximum speed (in bytes) for migrations", -.user_print = monitor_user_noop, -.mhandler.cmd_new = do_migrate_set_speed, +.mhandler.cmd = do_migrate_set_speed, }, @@ -486,7 +485,7 @@ { .name = "balloon", -.args_type = "value:i", +.args_type = "value:M", .params = "target", .help = "request VM to change it's memory allocation (in MB)", .user_print = monitor_user_noop, diff --git a/qemu/qemu-monitor.hx b/qemu/qemu-monitor.hx index c788c737..1aa78186 100644 --- a/qemu/qemu-monitor.hx +++ b/qemu/qemu-monitor.hx @@ -130,7 +130,7 @@ ETEXI { .name = "eject", - .args_type = "force:-f,filename:B", + .args_type = "force:-f,device:B", .params = "[-f] device", .help = "eject a removable medium (use -f to force it)", .user_print = monitor_user_noop, @@ -763,8 +763,7 @@ ETEXI .args_type = "value:s", .params = "value", .help = "set maximum speed (in bytes) for migrations", - .user_print = monitor_user_noop, - .mhandler.cmd_new = do_migrate_set_speed, + .mhandler.cmd = do_migrate_set_speed, }, STEXI @@ -887,7 +886,7 @@ ETEXI { .name = "balloon", - .args_type = "value:i", + .args_type = "value:M", .params = "target", .help = "request VM to change it's memory allocation (in MB)", .user_print = monitor_user_noop, diff --git a/qemu/qemu-options.h b/qemu/qemu-options.h index 10899cb9..a07da620 100644 --- a/qemu/qemu-options.h +++ b/qemu/qemu-options.h @@ -572,4 +572,4 @@ DEF("readconfig", HAS_ARG, QEMU_OPTION_readconfig, "-readconfig \n") DEF("writeconfig", HAS_ARG, QEMU_OPTION_writeconfig, "-writeconfig \n" -" read/write config file") +" read/write config file\n") diff --git a/qemu/qemu-options.hx b/qemu/qemu-options.hx index b8cc3750..ecd50ebe 100644 --- a/qemu/qemu-options.hx +++ b/qemu/qemu-options.hx @@ -1936,4 +1936,4 @@ DEF("readconfig", HAS_ARG, QEMU_OPTION_readconfig, "-readconfig \n") DEF("writeconfig", HAS_ARG, QEMU_OPTION_writeconfig, "-writeconfig \n" - " read/write config file") + " read/write config file\n") diff --git a/qemu/target-alpha/op_helper.c b/qemu/target-alpha/op_helper.c index fe222dcc..7a3bf9c0 100644 --- a/qemu/target-alpha/op_helper.c +++ b/qemu/target-alpha/op_helper.c @@ -46,10 +46,10 @@ uint64_t helper_load_fpcr (void) { uint64_t ret = 0; #ifdef CONFIG_SOFTFLOAT - ret |= env->fp_status.float_exception_flags << 52; + ret |= (uint64_t)env->fp_status.float_exception_flags << 52; if (env->fp_status.float_exception_flags) ret |= 1ULL << 63; - env->ipr[IPR_EXC_SUM] &= ~0x3E: + env->ipr[IPR_EXC_SUM] &= ~0x3E; env->ipr[IPR_EXC_SUM] |= env->fp_status.float_exception_flags << 1; #endif switch (env->fp_status.float_rounding_mode) { diff --git a/qemu/target-i386/cpu.h b/qemu/target-i386/cpu.h index 235cb145..7d4cb932 100644 --- a/qemu/target-i386/cpu.h +++ b/qemu/target-i386/cpu.h @@ -707,6 +707,7 @@ typedef struct CPUX86State { /* For KVM */ uint32_t mp_state; + int32_t exception_injected; int32_t interrupt_injected; uint8_t soft_interrupt; uint8_t nmi_injected; @@ -847,12 +848,12 @@ static inline int hw_breakpoint_enabled(unsigned long dr7, int index) static inline int hw_breakpoint_type(unsigned long dr7, int index) { - return (dr7 >> (DR7_TYPE_SHIFT + (index * 2))) & 3; + return (dr7 >> (DR7_TYPE_SHIFT + (index * 4))) & 3; } static inline int hw_breakpoint_len(unsigned long dr7, int index) { - int len = ((dr7 >> (DR7_LEN_SHIFT + (index * 2))) & 3); + int len = ((dr7 >> (DR7_LEN_SHIFT + (index * 4))) & 3); return (len == 2) ? 8 : len + 1; } diff --git a/qemu/target-i386/helper.c b/qemu/target-i386/helper.c index 52820394..ca669014 100644 --- a/qemu/target-i386/helper.c +++ b/qemu/target-i386/helper.c @@ -142,10 +142,11 @@ static x86_def_t x86_defs[] = { CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA | /* this feature is needed for Solaris and isn't fully implemented */ CPUID_PSE36, - .ext_features = CPUID_EXT_SSE3, + .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_CX16 | CPUID_EXT_POPCNT, .ext2_features = (PPRO_FEATURES & 0x0183F3FF) | CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX, - .ext3_features = CPUID_EXT3_SVM, + .ext3_features = CPUID_EXT3_LAHF_LM | CPUID_EXT3_SVM | + CPUID_EXT3_ABM | CPUID_EXT3_SSE4A, .xlevel = 0x8000000A, .model_id = "QEMU Virtual CPU version " QEMU_VERSION, }, @@ -162,18 +163,19 @@ static x86_def_t x86_defs[] = { .features = PPRO_FEATURES | CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA | CPUID_PSE36, - /* Missing: CPUID_EXT_CX16, CPUID_EXT_POPCNT */ - .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_MONITOR, + .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_MONITOR | CPUID_EXT_CX16 | + CPUID_EXT_POPCNT, /* Missing: CPUID_EXT2_PDPE1GB, CPUID_EXT2_RDTSCP */ .ext2_features = (PPRO_FEATURES & 0x0183F3FF) | CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX | CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT | CPUID_EXT2_MMXEXT | CPUID_EXT2_FFXSR, - /* Missing: CPUID_EXT3_LAHF_LM, CPUID_EXT3_CMP_LEG, CPUID_EXT3_EXTAPIC, - CPUID_EXT3_CR8LEG, CPUID_EXT3_ABM, CPUID_EXT3_SSE4A, + /* Missing: CPUID_EXT3_CMP_LEG, CPUID_EXT3_EXTAPIC, + CPUID_EXT3_CR8LEG, CPUID_EXT3_MISALIGNSSE, CPUID_EXT3_3DNOWPREFETCH, CPUID_EXT3_OSVW, CPUID_EXT3_IBS */ - .ext3_features = CPUID_EXT3_SVM, + .ext3_features = CPUID_EXT3_LAHF_LM | CPUID_EXT3_SVM | + CPUID_EXT3_ABM | CPUID_EXT3_SSE4A, .xlevel = 0x8000001A, .model_id = "AMD Phenom(tm) 9550 Quad-Core Processor" }, @@ -194,7 +196,7 @@ static x86_def_t x86_defs[] = { CPUID_EXT_TM2, CPUID_EXT_CX16, CPUID_EXT_XTPR, CPUID_EXT_PDCM */ .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_MONITOR | CPUID_EXT_SSSE3, .ext2_features = CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX, - /* Missing: .ext3_features = CPUID_EXT3_LAHF_LM */ + .ext3_features = CPUID_EXT3_LAHF_LM, .xlevel = 0x80000008, .model_id = "Intel(R) Core(TM)2 Duo CPU T7700 @ 2.40GHz", }, @@ -232,7 +234,7 @@ static x86_def_t x86_defs[] = { .model = 3, .stepping = 3, .features = PPRO_FEATURES, - .ext_features = CPUID_EXT_SSE3, + .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_POPCNT, .xlevel = 0, .model_id = "QEMU Virtual CPU version " QEMU_VERSION, }, @@ -1810,11 +1812,8 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count, } if (kvm_enabled()) { - /* Nested SVM not yet supported in KVM */ + /* Nested SVM not yet supported in upstream QEMU */ *ecx &= ~CPUID_EXT3_SVM; - } else { - /* AMD 3DNow! is not supported in QEMU */ - *edx &= ~(CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT); } break; case 0x80000002: diff --git a/qemu/target-i386/kvm.c b/qemu/target-i386/kvm.c index 53955b40..de79eb76 100644 --- a/qemu/target-i386/kvm.c +++ b/qemu/target-i386/kvm.c @@ -720,8 +720,8 @@ static int kvm_put_vcpu_events(CPUState *env) return 0; } - events.exception.injected = (env->exception_index >= 0); - events.exception.nr = env->exception_index; + events.exception.injected = (env->exception_injected >= 0); + events.exception.nr = env->exception_injected; events.exception.has_error_code = env->has_error_code; events.exception.error_code = env->error_code; @@ -755,7 +755,7 @@ static int kvm_get_vcpu_events(CPUState *env) if (ret < 0) { return ret; } - env->exception_index = + env->exception_injected = events.exception.injected ? events.exception.nr : -1; env->has_error_code = events.exception.has_error_code; env->error_code = events.exception.error_code; diff --git a/qemu/target-i386/machine.c b/qemu/target-i386/machine.c index bdfdfffd..d1b58bd3 100644 --- a/qemu/target-i386/machine.c +++ b/qemu/target-i386/machine.c @@ -452,12 +452,12 @@ static const VMStateDescription vmstate_cpu = { VMSTATE_INT32_V(interrupt_injected, CPUState, 9), VMSTATE_UINT32_V(mp_state, CPUState, 9), VMSTATE_UINT64_V(tsc, CPUState, 9), + VMSTATE_INT32_V(exception_injected, CPUState, 11), VMSTATE_UINT8_V(soft_interrupt, CPUState, 11), VMSTATE_UINT8_V(nmi_injected, CPUState, 11), VMSTATE_UINT8_V(nmi_pending, CPUState, 11), VMSTATE_UINT8_V(has_error_code, CPUState, 11), VMSTATE_UINT32_V(sipi_vector, CPUState, 11), - VMSTATE_INT32_V(exception_index, CPUState, 11), /* MCE */ VMSTATE_UINT64_V(mcg_cap, CPUState, 10), VMSTATE_UINT64_V(mcg_status, CPUState, 10), diff --git a/qemu/target-i386/translate.c b/qemu/target-i386/translate.c index d8dd69de..fbc3d1e3 100644 --- a/qemu/target-i386/translate.c +++ b/qemu/target-i386/translate.c @@ -6496,6 +6496,8 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) tval += next_eip; if (s->dflag == 0) tval &= 0xffff; + else if (!CODE64(s)) + tval &= 0xffffffff; gen_movtl_T0_im(next_eip); gen_push_T0(s); gen_jmp(s, tval); diff --git a/qemu/target-mips/translate.c b/qemu/target-mips/translate.c index 9d62b64b..f756ab9d 100644 --- a/qemu/target-mips/translate.c +++ b/qemu/target-mips/translate.c @@ -8652,6 +8652,14 @@ void cpu_reset (CPUMIPSState *env) env->hflags = MIPS_HFLAG_UM; /* Enable access to the SYNCI_Step register. */ env->CP0_HWREna |= (1 << 1); + if (env->CP0_Config1 & (1 << CP0C1_FP)) { + env->hflags |= MIPS_HFLAG_FPU; + } +#ifdef TARGET_MIPS64 + if (env->active_fpu.fcr0 & (1 << FCR0_F64)) { + env->hflags |= MIPS_HFLAG_F64; + } +#endif #else if (env->hflags & MIPS_HFLAG_BMASK) { /* If the exception was raised from a delay slot, diff --git a/qemu/target-mips/translate_init.c b/qemu/target-mips/translate_init.c index c950eab1..39789086 100644 --- a/qemu/target-mips/translate_init.c +++ b/qemu/target-mips/translate_init.c @@ -524,14 +524,6 @@ static void fpu_init (CPUMIPSState *env, const mips_def_t *def) env->fpus[i].fcr0 = def->CP1_fcr0; memcpy(&env->active_fpu, &env->fpus[0], sizeof(env->active_fpu)); -#if defined(CONFIG_USER_ONLY) - if (env->CP0_Config1 & (1 << CP0C1_FP)) - env->hflags |= MIPS_HFLAG_FPU; -#ifdef TARGET_MIPS64 - if (env->active_fpu.fcr0 & (1 << FCR0_F64)) - env->hflags |= MIPS_HFLAG_F64; -#endif -#endif } static void mvp_init (CPUMIPSState *env, const mips_def_t *def) diff --git a/qemu/target-ppc/kvm.c b/qemu/target-ppc/kvm.c index 2b5abf43..0424a784 100644 --- a/qemu/target-ppc/kvm.c +++ b/qemu/target-ppc/kvm.c @@ -135,10 +135,12 @@ int kvm_arch_get_registers(CPUState *env) env->sdr1 = sregs.u.s.sdr1; /* Sync SLB */ +#ifdef TARGET_PPC64 for (i = 0; i < 64; i++) { ppc_store_slb(env, sregs.u.s.ppc64.slb[i].slbe, sregs.u.s.ppc64.slb[i].slbv); } +#endif /* Sync SRs */ for (i = 0; i < 16; i++) { diff --git a/qemu/target-s390x/kvm.c b/qemu/target-s390x/kvm.c index b6aac424..09925639 100644 --- a/qemu/target-s390x/kvm.c +++ b/qemu/target-s390x/kvm.c @@ -405,7 +405,7 @@ static int handle_instruction(CPUState *env, struct kvm_run *run) unsigned int ipa0 = (run->s390_sieic.ipa & 0xff00); uint8_t ipa1 = run->s390_sieic.ipa & 0x00ff; int ipb_code = (run->s390_sieic.ipb & 0x0fff0000) >> 16; - int r = 0; + int r = -1; dprintf("handle_instruction 0x%x 0x%x\n", run->s390_sieic.ipa, run->s390_sieic.ipb); switch (ipa0) { diff --git a/qemu/usb-linux.c b/qemu/usb-linux.c index 105ce88f..88728e92 100644 --- a/qemu/usb-linux.c +++ b/qemu/usb-linux.c @@ -1206,7 +1206,8 @@ static int usb_host_read_file(char *line, size_t line_size, const char *device_f ret = 1; #if 0 } else { - monitor_printf(mon, "husb: could not open %s\n", filename); + if (mon) + monitor_printf(mon, "husb: could not open %s\n", filename); #endif } @@ -1339,15 +1340,17 @@ static int usb_host_scan(void *opaque, USBScanFunc *func) } found_devices: if (!usb_fs_type) { - monitor_printf(mon, "husb: unable to access USB devices\n"); + if (mon) + monitor_printf(mon, "husb: unable to access USB devices\n"); return -ENOENT; } /* the module setting (used later for opening devices) */ usb_host_device_path = qemu_mallocz(strlen(devpath)+1); strcpy(usb_host_device_path, devpath); - monitor_printf(mon, "husb: using %s file-system with %s\n", - fs_type[usb_fs_type], usb_host_device_path); + if (mon) + monitor_printf(mon, "husb: using %s file-system with %s\n", + fs_type[usb_fs_type], usb_host_device_path); } switch (usb_fs_type) { diff --git a/qemu/vl.c b/qemu/vl.c index 30bd3420..15971484 100644 --- a/qemu/vl.c +++ b/qemu/vl.c @@ -285,7 +285,9 @@ static int default_parallel = 1; static int default_virtcon = 1; static int default_monitor = 1; static int default_vga = 1; -static int default_drive = 1; +static int default_floppy = 1; +static int default_cdrom = 1; +static int default_sdcard = 1; static struct { const char *driver; @@ -293,11 +295,13 @@ static struct { } default_list[] = { { .driver = "isa-serial", .flag = &default_serial }, { .driver = "isa-parallel", .flag = &default_parallel }, + { .driver = "isa-fdc", .flag = &default_floppy }, + { .driver = "ide-drive", .flag = &default_cdrom }, { .driver = "virtio-console-pci", .flag = &default_virtcon }, { .driver = "virtio-console-s390", .flag = &default_virtcon }, { .driver = "VGA", .flag = &default_vga }, - { .driver = "Cirrus VGA", .flag = &default_vga }, - { .driver = "QEMUware SVGA", .flag = &default_vga }, + { .driver = "cirrus-vga", .flag = &default_vga }, + { .driver = "vmware-svga", .flag = &default_vga }, }; static int default_driver_check(QemuOpts *opts, void *opaque) @@ -2055,10 +2059,6 @@ BlockInterfaceErrorAction drive_get_on_error( { DriveInfo *dinfo; - if (is_read) { - return BLOCK_ERR_REPORT; - } - QTAILQ_FOREACH(dinfo, &drives, next) { if (dinfo->bdrv == bdrv) return is_read ? dinfo->on_read_error : dinfo->on_write_error; @@ -2665,24 +2665,6 @@ static int usb_device_add(const char *devname, int is_hotplug) /* the other ones */ if (strstart(devname, "host:", &p)) { dev = usb_host_device_open(p); - } else if (strstart(devname, "net:", &p)) { - QemuOpts *opts; - int idx; - - opts = qemu_opts_parse(&qemu_net_opts, p, NULL); - if (!opts) { - return -1; - } - - qemu_opt_set(opts, "type", "nic"); - qemu_opt_set(opts, "model", "usb"); - - idx = net_client_init(NULL, opts, 0); - if (idx == -1) { - return -1; - } - - dev = usb_net_init(&nd_table[idx]); } else if (!strcmp(devname, "bt") || strstart(devname, "bt:", &p)) { dev = usb_bt_init(devname[2] ? hci_init(p) : bt_new_hci(qemu_find_bt_vlan(0))); @@ -2718,17 +2700,28 @@ static int usb_device_del(const char *devname) static int usb_parse(const char *cmdline) { - return usb_device_add(cmdline, 0); + int r; + r = usb_device_add(cmdline, 0); + if (r < 0) { + fprintf(stderr, "qemu: could not add USB device '%s'\n", cmdline); + } + return r; } void do_usb_add(Monitor *mon, const QDict *qdict) { - usb_device_add(qdict_get_str(qdict, "devname"), 1); + const char *devname = qdict_get_str(qdict, "devname"); + if (usb_device_add(devname, 1) < 0) { + qemu_error("could not add USB device '%s'\n", devname); + } } void do_usb_del(Monitor *mon, const QDict *qdict) { - usb_device_del(qdict_get_str(qdict, "devname")); + const char *devname = qdict_get_str(qdict, "devname"); + if (usb_device_del(devname) < 0) { + qemu_error("could not delete USB device '%s'\n", devname); + } } /***********************************************************/ @@ -5612,7 +5605,9 @@ int __declspec(dllexport) qemu_main(int argc, char** argv, char** envp) default_monitor = 0; default_vga = 0; default_net = 0; - default_drive = 0; + default_floppy = 0; + default_cdrom = 0; + default_sdcard = 0; break; #ifndef _WIN32 case QEMU_OPTION_chroot: @@ -5693,6 +5688,7 @@ int __declspec(dllexport) qemu_main(int argc, char** argv, char** envp) } qemu_opts_foreach(&qemu_device_opts, default_driver_check, NULL, 0); + qemu_opts_foreach(&qemu_global_opts, default_driver_check, NULL, 0); if (machine->no_serial) { default_serial = 0; @@ -5706,6 +5702,15 @@ int __declspec(dllexport) qemu_main(int argc, char** argv, char** envp) if (machine->no_vga) { default_vga = 0; } + if (machine->no_floppy) { + default_floppy = 0; + } + if (machine->no_cdrom) { + default_cdrom = 0; + } + if (machine->no_sdcard) { + default_sdcard = 0; + } if (display_type == DT_NOGRAPHIC) { if (default_parallel) @@ -5729,6 +5734,8 @@ int __declspec(dllexport) qemu_main(int argc, char** argv, char** envp) add_device_config(DEV_PARALLEL, "vc:80Cx24C"); if (default_monitor) monitor_parse("vc:80Cx24C", "readline"); + if (default_virtcon) + add_device_config(DEV_VIRTCON, "vc:80Cx24C"); } if (default_vga) vga_interface_type = VGA_CIRRUS; @@ -5862,13 +5869,17 @@ int __declspec(dllexport) qemu_main(int argc, char** argv, char** envp) blk_mig_init(); - if (default_drive) { + if (default_cdrom) { /* we always create the cdrom drive, even if no disk is there */ drive_add(NULL, CDROM_ALIAS); + } + if (default_floppy) { /* we always create at least one floppy */ drive_add(NULL, FD_ALIAS, 0); + } + if (default_sdcard) { /* we always create one sd slot, even if no card is in it */ drive_add(NULL, SD_ALIAS); } @@ -6048,7 +6059,10 @@ int __declspec(dllexport) qemu_main(int argc, char** argv, char** envp) qdev_machine_creation_done(); - rom_load_all(); + if (rom_load_all() != 0) { + fprintf(stderr, "rom loading failed\n"); + exit(1); + } qemu_system_reset(); if (loadvm) { diff --git a/qemu/vnchextile.h b/qemu/vnchextile.h index 96cf6454..1e1cd11d 100644 --- a/qemu/vnchextile.h +++ b/qemu/vnchextile.h @@ -73,7 +73,7 @@ static void CONCAT(send_hextile_tile_, NAME)(VncState *vs, *last_bg = bg; } - if (!*has_fg || *last_fg != fg) { + if (n_colors < 3 && (!*has_fg || *last_fg != fg)) { flags |= 0x04; *has_fg = 1; *last_fg = fg;