Re: [Qemu-devel] [PULL 10/42] qtest: Fix the bug about disable vnc causes make check fail
2014/1/26 Andreas Färber afaer...@suse.de Am 18.01.2014 12:54, schrieb Kewei Yu: 2014/1/17 Andreas Färber afaer...@suse.de mailto:afaer...@suse.de Am 15.01.2014 11:22, schrieb Kevin Wolf: From: Kewei Yu kewe...@gmail.com mailto:kewe...@gmail.com When we disable vnc from ./configure, QEMU can't use the vnc option. So qtest can't use the vnc -none , otherwise make check fails. If QEMU uses -display none, -vnc none is excrescent, So we just need to drop it. Signed-off-by: Kewei Yu kewe...@gmail.com mailto: kewe...@gmail.com Reviewed-by: Paolo Bonzini pbonz...@redhat.com mailto:pbonz...@redhat.com Signed-off-by: Kevin Wolf kw...@redhat.com mailto: kw...@redhat.com If the pull does get respun, 'Fix make check failing for --disable-vnc' would be better English. ;) Yes, It is more accurate. So I should re-submit it? Sorry for the late answer. Since it was already in the maintainer's queue and just about the commit message, it's not necessary for you to resubmit, my comment was addressed to Kevin. When a PULL has been sent, only major reasons (like build breakages, missing/wrong Sob, etc.) lead to a resubmission by the maintainer. Apart from the grammar issues (causes ... to fail or ... failure, disabling ... causes), please keep in mind that many commits fix bugs, so it will be more useful to the reader of patch/commit to read prominently what is changing (and why) to determine whether he/she is affected. Hope that explains. Thank you for your patient explains, I will. ^ ^ Regards, Kewei Regards, Andreas Andreas -- SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg Kewei -- SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg
Re: [Qemu-devel] [PATCH 0/2] acpi: Fix PCI hole handling on SRAT table
On Thu, Jan 09, 2014 at 05:12:41PM -0200, Eduardo Habkost wrote: The original SeaBIOS code used the RamSize variable, that was used by SeaBIOS for the size of RAM below 4GB, not for all RAM. When copied to QEMU, the code was changed to use the full RAM size, and this broke the build_srat() code that handles the PCI hole. This series fixes the problem by restoring the original behavior from SeaBIOS. Example Linux guest dmesg output when the bug is present (using -m 4G and 4 1GB NUMA nodes): e820: BIOS-provided physical RAM map: BIOS-e820: [mem 0x-0x0009fbff] usable BIOS-e820: [mem 0x0009fc00-0x0009] reserved BIOS-e820: [mem 0x000f-0x000f] reserved BIOS-e820: [mem 0x0010-0xdfffdfff] usable BIOS-e820: [mem 0xdfffe000-0xdfff] reserved BIOS-e820: [mem 0xfeffc000-0xfeff] reserved BIOS-e820: [mem 0xfffc-0x] reserved BIOS-e820: [mem 0x0001-0x00011fff] usable e820: update [mem 0x-0x0fff] usable == reserved e820: remove [mem 0x000a-0x000f] usable e820: last_pfn = 0x12 max_arch_pfn = 0x4 e820: last_pfn = 0xdfffe max_arch_pfn = 0x4 ACPI: SRAT dc0e 00160 (v01 BOCHS BXPCSRAT 0001 BXPC 0001) SRAT: PXM 0 - APIC 0x00 - Node 0 SRAT: PXM 1 - APIC 0x01 - Node 1 SRAT: PXM 2 - APIC 0x02 - Node 2 SRAT: PXM 3 - APIC 0x03 - Node 3 SRAT: Node 0 PXM 0 [mem 0x-0x0009] SRAT: Node 0 PXM 0 [mem 0x0010-0x3fff] SRAT: Node 1 PXM 1 [mem 0x4000-0x7fff] SRAT: Node 2 PXM 2 [mem 0x8000-0xbfff] SRAT: Node 3 PXM 3 [mem 0xc000-0x] NUMA: nodes only cover 3583MB of your 4095MB e820 RAM. Not used. e820: [mem 0xe000-0xfeffbfff] available for PCI devices e820: reserve RAM buffer [mem 0x0009fc00-0x0009] e820: reserve RAM buffer [mem 0xdfffe000-0xdfff] Output after the series is applied: e820: BIOS-provided physical RAM map: BIOS-e820: [mem 0x-0x0009fbff] usable BIOS-e820: [mem 0x0009fc00-0x0009] reserved BIOS-e820: [mem 0x000f-0x000f] reserved BIOS-e820: [mem 0x0010-0xdfffdfff] usable BIOS-e820: [mem 0xdfffe000-0xdfff] reserved BIOS-e820: [mem 0xfeffc000-0xfeff] reserved BIOS-e820: [mem 0xfffc-0x] reserved BIOS-e820: [mem 0x0001-0x00011fff] usable e820: update [mem 0x-0x0fff] usable == reserved e820: remove [mem 0x000a-0x000f] usable e820: last_pfn = 0x12 max_arch_pfn = 0x4 e820: last_pfn = 0xdfffe max_arch_pfn = 0x4 ACPI: SRAT dc0e 00160 (v01 BOCHS BXPCSRAT 0001 BXPC 0001) SRAT: PXM 0 - APIC 0x00 - Node 0 SRAT: PXM 1 - APIC 0x01 - Node 1 SRAT: PXM 2 - APIC 0x02 - Node 2 SRAT: PXM 3 - APIC 0x03 - Node 3 SRAT: Node 0 PXM 0 [mem 0x-0x0009] SRAT: Node 0 PXM 0 [mem 0x0010-0x3fff] SRAT: Node 1 PXM 1 [mem 0x4000-0x7fff] SRAT: Node 2 PXM 2 [mem 0x8000-0xbfff] SRAT: Node 3 PXM 3 [mem 0xc000-0xdfff] SRAT: Node 3 PXM 3 [mem 0x1-0x11fff] e820: [mem 0xe000-0xfeffbfff] available for PCI devices e820: reserve RAM buffer [mem 0x0009fc00-0x0009] e820: reserve RAM buffer [mem 0xdfffe000-0xdfff] Thanks, applied. Eduardo Habkost (2): pc: Save size of RAM below 4GB acpi-build: Fix PCI hole handling on build_srat() hw/i386/acpi-build.c | 10 +- hw/i386/pc.c | 1 + include/hw/i386/pc.h | 2 +- 3 files changed, 7 insertions(+), 6 deletions(-) -- 1.8.4.2
Re: [Qemu-devel] [PULL 00/29] acpi, pci, pc, virtio fixes and enhancements
On Mon, Jan 20, 2014 at 04:09:16PM +0200, Michael S. Tsirkin wrote: The following changes since commit 1cf892ca2689c84960b4ce4d2723b6bee453711c: SPARC: Fix LEON3 power down instruction (2014-01-15 15:37:33 +1000) are available in the git repository at: git://git.kernel.org/pub/scm/virt/kvm/mst/qemu.git tags/for_anthony for you to fetch changes up to ed25eb3675186b7bbb0c9876fe0e7cf8fa868642: acpi-test: update expected AML since recent changes (2014-01-20 16:06:14 +0200) Hi Anthony, I guess this got lost because I forgot to Cc you? I'll send a new one with more stuff that got buffered up since. acpi,pci,pc,virtio fixes and enhancements This includes new unit-tests for acpi by Marcel, hotplug for pci bridges by myself (piix only so far) and cpu hotplug for q35. And a bunch of fixes all over the place as usual. Still keeping memory alignment fix for q35 out of tree in the hope that we can fix it without limiting 32 bit guests to 2G RAM. Signed-off-by: Michael S. Tsirkin m...@redhat.com Alexey Kardashevskiy (1): tests: fix acpi to work on bigendian host Gabriel L. Somlo (2): Add DSDT node for AppleSMC ACPI: Fix AppleSMC _STA size Igor Mammedov (9): pc: make: fix dependencies: rebuild when included file is changed acpi: factor out common cpu hotplug code for PIIX4/Q35 acpi: ich9: add CPU hotplug handling to Q35 machine pc: set PRST base in DSDT depending on chipset pc: PIIX DSDT: exclude CPU/PCI hotplug GPE0 IO range from PCI bus resources pc: Q35 DSDT: exclude CPU hotplug IO range from PCI bus resources pc: ACPI: expose PRST IO range via _CRS pc: ACPI: unify source of CPU hotplug IO base/len pc: ACPI: update acpi-dsdt.hex.generated q35-acpi-dsdt.hex.generated Laszlo Ersek (1): Python-lang gdb script to extract x86_64 guest vmcore from qemu coredump Marcel Apfelbaum (10): acpi unit-test: add test files configure: added acpi unit-test files acpi unit-test: compare DSDT and SSDT tables against expected values configure: add CONFIG_IASL to config-host.h acpi unit-test: extract iasl executable from configuration acpi unit-test: added script to rebuild the expected aml files acpi unit-test: hook to rebuild expected aml files acpi unit-test: renamed ssdt_tables to tables acpi unit-test: resolved iasl crash acpi unit-test: do not fail on asl mismatch Michael S. Tsirkin (5): pci: add pci_for_each_bus_depth_first pcihp: generalization of piix4 acpi piix4: add acpi pci hotplug support acpi-build: enable hotplug for PCI bridges acpi-test: update expected AML since recent changes Stefan Weil (1): virtio: Fix return value for dummy function vhost_net_virtqueue_pending configure| 4 + include/hw/acpi/cpu_hotplug.h| 27 ++ include/hw/acpi/cpu_hotplug_defs.h | 24 ++ include/hw/acpi/ich9.h | 4 + include/hw/acpi/pcihp.h | 72 ++ include/hw/i386/pc.h | 5 + include/hw/isa/isa.h | 7 + include/hw/pci/pci.h | 14 ++ hw/acpi/cpu_hotplug.c| 64 + hw/acpi/ich9.c | 14 ++ hw/acpi/pcihp.c | 316 hw/acpi/piix4.c | 155 ++-- hw/i386/acpi-build.c | 354 +-- hw/misc/applesmc.c | 1 - hw/net/vhost_net.c | 2 +- hw/pci/pci.c | 28 +++ tests/acpi-test.c| 305 --- docs/specs/acpi_cpu_hotplug.txt | 4 +- hw/acpi/Makefile.objs| 3 +- hw/i386/Makefile.objs| 2 +- hw/i386/acpi-dsdt-cpu-hotplug.dsl| 14 +- hw/i386/acpi-dsdt-isa.dsl| 11 + hw/i386/acpi-dsdt-pci-crs.dsl| 15 +- hw/i386/acpi-dsdt.dsl| 76 -- hw/i386/acpi-dsdt.hex.generated | 217 +++- hw/i386/q35-acpi-dsdt.dsl| 19 ++ hw/i386/q35-acpi-dsdt.hex.generated | 74 +- hw/i386/ssdt-pcihp.dsl | 11 +- hw/i386/ssdt-pcihp.hex.generated | 20 +- hw/i386/ssdt-proc.hex.generated | 6 +- scripts/create_config| 4 + scripts/dump-guest-memory.py | 339 + tests/acpi-test-data/pc/APIC | Bin 0 - 120 bytes
Re: [Qemu-devel] [PATCH 3/4] hw:acpi:pcihp: assume root PCI bus if bus has no ACPI_PCIHP_PROP_BSEL property
On Tue, Jan 21, 2014 at 03:40:05PM +0100, Igor Mammedov wrote: when running with machine types older than 1.7 (i.e. without ACPI builtin tables), PCI bus won't have ACPI_PCIHP_PROP_BSEL property set. Taking in account that acpi hotplug handler in 1.7 and older machines is called only for root PCI bus, to make pcihp code compatible with legacy machine types assume that bus without ACPI_PCIHP_PROP_BSEL property has it equal to 0 and bail out if it's not root bus. Signed-off-by: Igor Mammedov imamm...@redhat.com I think that's not the best way to do this. If bsel 0 *is* set on some bus, it should select it. Fallback to bus 0 only if bsel value 0 is not set anywhere. See e.g. how acpi_pcihp_find_hotplug_bus does it: if (!bsel !find.bus) { find.bus = s-root; } otherwise we introduce dependency on the logic that sets bsel, this makes code fragile. --- hw/acpi/pcihp.c | 10 +++--- 1 files changed, 3 insertions(+), 7 deletions(-) diff --git a/hw/acpi/pcihp.c b/hw/acpi/pcihp.c index 6d34fe9..76dce8d 100644 --- a/hw/acpi/pcihp.c +++ b/hw/acpi/pcihp.c @@ -63,14 +63,10 @@ static int acpi_pcihp_get_bsel(PCIBus *bus) { QObject *o = object_property_get_qobject(OBJECT(bus), ACPI_PCIHP_PROP_BSEL, NULL); -int64_t bsel = -1; if (o) { -bsel = qint_get_int(qobject_to_qint(o)); +return qint_get_int(qobject_to_qint(o)); } -if (bsel 0) { -return -1; -} -return bsel; +return 0; } static void acpi_pcihp_test_hotplug_bus(PCIBus *bus, void *opaque) @@ -190,7 +186,7 @@ int acpi_pcihp_device_hotplug(AcpiPciHpState *s, PCIDevice *dev, { int slot = PCI_SLOT(dev-devfn); int bsel = acpi_pcihp_get_bsel(dev-bus); -if (bsel 0) { +if ((bsel == 0) (dev-bus != s-root)) { return -1; } -- 1.7.1
[Qemu-devel] [Bug 1263318] Re: Cannot add a USB 2.0 device under QEMU when running eudev
The bug has been fixed. It had nothing to do with QEMU. The problem was that eudev didn't ship a file with rules for USB devices. See https://bugs.gentoo.org/show_bug.cgi?id=499236 for detais. Sorry for the noise. ** Bug watch added: Gentoo Bugzilla #499236 https://bugs.gentoo.org/show_bug.cgi?id=499236 -- You received this bug notification because you are a member of qemu- devel-ml, which is subscribed to QEMU. https://bugs.launchpad.net/bugs/1263318 Title: Cannot add a USB 2.0 device under QEMU when running eudev Status in QEMU: New Bug description: Hello. I have a USB webcam I'm using under QEMU (version 1.6.1). The guest is Windows 7 (32-bit) while the host is Gentoo Linux (64-bit). I have been using it for several weeks without any problem, but now it doesn't work any more. I have been able to pinpoint the cause: it is because I switched from udev-208 to eudev-1.3 (which is based on udev-207). These are the command line options for QEMU: qemu-system-i386 -cpu host -m 1G -k it -drive file=Windows_7.qcow2,media=disk,index=0 -vga std -net nic -net user -enable-kvm -display sdl -soundhw ac97 -device usb-ehci,id=ehci -usb -rtc base=localtime -usbdevice tablet The relevant options are -device usb-ehci,id=ehci -usb. That is, I'm enabling both USB 2.0 (EHCI) and USB 1.1 (UHCI). I manually add the webcam using: device_add usb-host,hostbus=x,hostaddr=y,id=webcam but if I do so when running eudev it gets added as a slow USB 1.1 1.5 Mb/s device: (qemu) info usb [...] Device 1.0, Port 1, Speed 1.5 Mb/s, Product USB Host Device I also noticed that the info usbhost command works differently now, in that it doesn't display any more a description, such as the brand name (Creative): (qemu) info usbhost [...] Bus 1, Addr 3, Port 3, Speed 480 Mb/s Class ef: USB device 041e:4088 From the host system: $ lsusb | grep Creative Bus 001 Device 003: ID 041e:4088 Creative Technology, Ltd Live! Cam Chat HD [VF0700] If I turn back to udev I get the following results instead: (qemu) info usb [...] Device 1.1, Port 1, Speed 480 Mb/s, Product VF0700 Live! Cam Chat HD (qemu) info usbhost [...] Bus 1, Addr 2, Port 4, Speed 480 Mb/s Class ef: USB device 041e:4088, VF0700 Live! Cam Chat HD I don't know if this is a problem with QEMU or with eudev, so I'm also going to report this bug on the Gentoo Bugzilla (eudev is a Gentoo project). To manage notifications about this bug go to: https://bugs.launchpad.net/qemu/+bug/1263318/+subscriptions
[Qemu-devel] [PATCH] pcihp: reduce number of device check events
PIIX created a made-up value for the UP register since it was read by guest 32 times for each interrupt. There's no reason to do this for the new PCIHP: register is only read once for each interrupt, so clean up code by making read act as an interrupt acknowledgement: the new UP register clear on read. In this way we cut down the number of bus rescans by a factor of 32, and drop a bunch of code that's now unused. Signed-off-by: Michael S. Tsirkin m...@redhat.com --- hw/acpi/pcihp.c | 21 + include/hw/acpi/pcihp.h | 2 +- 2 files changed, 6 insertions(+), 17 deletions(-) diff --git a/hw/acpi/pcihp.c b/hw/acpi/pcihp.c index 3fa3d7c..4345f5d 100644 --- a/hw/acpi/pcihp.c +++ b/hw/acpi/pcihp.c @@ -116,7 +116,6 @@ static void acpi_pcihp_eject_slot(AcpiPciHpState *s, unsigned bsel, unsigned slo { BusChild *kid, *next; int slot = ffs(slots) - 1; -bool slot_free = true; PCIBus *bus = acpi_pcihp_find_hotplug_bus(s, bsel); if (!bus) { @@ -125,21 +124,17 @@ static void acpi_pcihp_eject_slot(AcpiPciHpState *s, unsigned bsel, unsigned slo /* Mark request as complete */ s-acpi_pcihp_pci_status[bsel].down = ~(1U slot); +s-acpi_pcihp_pci_status[bsel].up = ~(1U slot); QTAILQ_FOREACH_SAFE(kid, bus-qbus.children, sibling, next) { DeviceState *qdev = kid-child; PCIDevice *dev = PCI_DEVICE(qdev); if (PCI_SLOT(dev-devfn) == slot) { -if (acpi_pcihp_pc_no_hotplug(s, dev)) { -slot_free = false; -} else { +if (!acpi_pcihp_pc_no_hotplug(s, dev)) { object_unparent(OBJECT(qdev)); } } } -if (slot_free) { -s-acpi_pcihp_pci_status[bsel].device_present = ~(1U slot); -} } static void acpi_pcihp_update_hotplug_bus(AcpiPciHpState *s, int bsel) @@ -153,7 +148,6 @@ static void acpi_pcihp_update_hotplug_bus(AcpiPciHpState *s, int bsel) } s-acpi_pcihp_pci_status[bsel].hotplug_enable = ~0; -s-acpi_pcihp_pci_status[bsel].device_present = 0; if (!bus) { return; @@ -166,8 +160,6 @@ static void acpi_pcihp_update_hotplug_bus(AcpiPciHpState *s, int bsel) if (acpi_pcihp_pc_no_hotplug(s, pdev)) { s-acpi_pcihp_pci_status[bsel].hotplug_enable = ~(1U slot); } - -s-acpi_pcihp_pci_status[bsel].device_present |= (1U slot); } } @@ -187,7 +179,7 @@ void acpi_pcihp_reset(AcpiPciHpState *s) static void enable_device(AcpiPciHpState *s, unsigned bsel, int slot) { -s-acpi_pcihp_pci_status[bsel].device_present |= (1U slot); +s-acpi_pcihp_pci_status[bsel].up |= (1U slot); } static void disable_device(AcpiPciHpState *s, unsigned bsel, int slot) @@ -208,7 +200,6 @@ int acpi_pcihp_device_hotplug(AcpiPciHpState *s, PCIDevice *dev, * it is present on boot, no hotplug event is necessary. We do send an * event when the device is disabled later. */ if (state == PCI_COLDPLUG_ENABLED) { -s-acpi_pcihp_pci_status[bsel].device_present |= (1U slot); return 0; } @@ -233,10 +224,8 @@ static uint64_t pci_read(void *opaque, hwaddr addr, unsigned int size) switch (addr) { case PCI_UP_BASE - PCI_HOTPLUG_ADDR: -/* Manufacture an up value to cause a device check on any hotplug - * slot with a device. Extra device checks are harmless. */ -val = s-acpi_pcihp_pci_status[bsel].device_present -s-acpi_pcihp_pci_status[bsel].hotplug_enable; +val = s-acpi_pcihp_pci_status[bsel].up; +s-acpi_pcihp_pci_status[bsel].up = 0; ACPI_PCIHP_DPRINTF(pci_up_read % PRIu32 \n, val); break; case PCI_DOWN_BASE - PCI_HOTPLUG_ADDR: diff --git a/include/hw/acpi/pcihp.h b/include/hw/acpi/pcihp.h index 6230e60..aa297c2 100644 --- a/include/hw/acpi/pcihp.h +++ b/include/hw/acpi/pcihp.h @@ -32,7 +32,7 @@ #include hw/pci/pci.h /* for PCIHotplugState */ typedef struct AcpiPciHpPciStatus { -uint32_t up; /* deprecated, maintained for migration compatibility */ +uint32_t up; uint32_t down; uint32_t hotplug_enable; uint32_t device_present; -- MST
Re: [Qemu-devel] [PATCH 4/4] hw:piix4:acpi: reuse pcihp code for legacy PCI hotplug
On Tue, Jan 21, 2014 at 03:40:06PM +0100, Igor Mammedov wrote: reduces acpi PCI hotplug code duplication by 150LOC, and makes pcihp less dependend on piix specific code. Signed-off-by: Igor Mammedov imamm...@redhat.com Actually pcihp was made separate intentionally so we can cleanup the host/guest interface without worrying about compatibility. I posted that cleanup patch - I'm not against unifying both chunks of code but could you put your patch on top? --- hw/acpi/pcihp.c | 10 +-- hw/acpi/piix4.c | 196 +-- include/hw/acpi/pcihp.h |8 ++- 3 files changed, 31 insertions(+), 183 deletions(-) diff --git a/hw/acpi/pcihp.c b/hw/acpi/pcihp.c index 76dce8d..25cc0fe 100644 --- a/hw/acpi/pcihp.c +++ b/hw/acpi/pcihp.c @@ -46,8 +46,6 @@ # define ACPI_PCIHP_DPRINTF(format, ...) do { } while (0) #endif -#define PCI_HOTPLUG_ADDR 0xae00 -#define PCI_HOTPLUG_SIZE 0x0014 #define PCI_UP_BASE 0x #define PCI_DOWN_BASE 0x0004 #define PCI_EJ_BASE 0x0008 @@ -279,14 +277,14 @@ static const MemoryRegionOps acpi_pcihp_io_ops = { }, }; -void acpi_pcihp_init(AcpiPciHpState *s, PCIBus *root_bus, - MemoryRegion *address_space_io) +void acpi_pcihp_init(AcpiPciHpState *s, PCIBus *root_bus, uint16_t io_base, + uint16_t io_size, MemoryRegion *address_space_io) { s-root= root_bus; memory_region_init_io(s-io, NULL, acpi_pcihp_io_ops, s, acpi-pci-hotplug, - PCI_HOTPLUG_SIZE); -memory_region_add_subregion(address_space_io, PCI_HOTPLUG_ADDR, s-io); + io_size); +memory_region_add_subregion(address_space_io, io_base, s-io); } const VMStateDescription vmstate_acpi_pcihp_pci_status = { diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c index 5d55a3c..f818d76 100644 --- a/hw/acpi/piix4.c +++ b/hw/acpi/piix4.c @@ -44,13 +44,6 @@ #define GPE_BASE 0xafe0 #define GPE_LEN 4 -#define PCI_HOTPLUG_ADDR 0xae00 -#define PCI_HOTPLUG_SIZE 0x000f -#define PCI_UP_BASE 0xae00 -#define PCI_DOWN_BASE 0xae04 -#define PCI_EJ_BASE 0xae08 -#define PCI_RMV_BASE 0xae0c - #define PIIX4_PCI_HOTPLUG_STATUS 2 struct pci_status { @@ -80,8 +73,8 @@ typedef struct PIIX4PMState { Notifier machine_ready; Notifier powerdown_notifier; -/* for legacy pci hotplug (compatible with qemu 1.6 and older) */ -MemoryRegion io_pci; +/* for legacy pci hotplug (compatible with qemu 1.6 and older) + * used only for migration and updated in pre_save() */ struct pci_status pci0_status; uint32_t pci0_hotplug_enable; uint32_t pci0_slot_device_present; @@ -175,16 +168,24 @@ static void vmstate_pci_status_pre_save(void *opaque) struct pci_status *pci0_status = opaque; PIIX4PMState *s = container_of(pci0_status, PIIX4PMState, pci0_status); +pci0_status-down = s-acpi_pci_hotplug.acpi_pcihp_pci_status[0].down; /* We no longer track up, so build a safe value for migrating * to a version that still does... of course these might get lost * by an old buggy implementation, but we try. */ -pci0_status-up = s-pci0_slot_device_present s-pci0_hotplug_enable; +pci0_status-up = +s-acpi_pci_hotplug.acpi_pcihp_pci_status[0].device_present +s-acpi_pci_hotplug.acpi_pcihp_pci_status[0].hotplug_enable; } static int vmstate_acpi_post_load(void *opaque, int version_id) { PIIX4PMState *s = opaque; +if (!s-use_acpi_pci_hotplug) { +s-acpi_pci_hotplug.acpi_pcihp_pci_status[0].down = +s-pci0_status.down; +} + pm_io_space_update(s); return 0; } @@ -304,60 +305,6 @@ static const VMStateDescription vmstate_acpi = { } }; -static void acpi_piix_eject_slot(PIIX4PMState *s, unsigned slots) -{ -BusChild *kid, *next; -BusState *bus = qdev_get_parent_bus(DEVICE(s)); -int slot = ffs(slots) - 1; -bool slot_free = true; - -/* Mark request as complete */ -s-pci0_status.down = ~(1U slot); - -QTAILQ_FOREACH_SAFE(kid, bus-children, sibling, next) { -DeviceState *qdev = kid-child; -PCIDevice *dev = PCI_DEVICE(qdev); -PCIDeviceClass *pc = PCI_DEVICE_GET_CLASS(dev); -if (PCI_SLOT(dev-devfn) == slot) { -if (pc-no_hotplug) { -slot_free = false; -} else { -object_unparent(OBJECT(qdev)); -} -} -} -if (slot_free) { -s-pci0_slot_device_present = ~(1U slot); -} -} - -static void piix4_update_hotplug(PIIX4PMState *s) -{ -BusState *bus = qdev_get_parent_bus(DEVICE(s)); -BusChild *kid, *next; - -/* Execute any pending removes during reset */ -while (s-pci0_status.down) { -acpi_piix_eject_slot(s, s-pci0_status.down); -} - -
[Qemu-devel] [PATCH] MAINTAINERS: add self as virtio co-maintainer
This will help make sure I get Cc'd on patches. Signed-off-by: Michael S. Tsirkin m...@redhat.com --- MAINTAINERS | 1 + 1 file changed, 1 insertion(+) diff --git a/MAINTAINERS b/MAINTAINERS index fb53242..adc5973 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -610,6 +610,7 @@ F: hw/*/*vhost* virtio M: Anthony Liguori aligu...@amazon.com +M: Michael S. Tsirkin m...@redhat.com S: Supported F: hw/*/virtio* -- MST
[Qemu-devel] Possible bug in pci slot management, migration abort after hotplug/unplug pci devices
Hi, I find a critical problem about pci devices migration when we configure a pci device not assign the devfn. Qemu will auto assign the devfn in function do_pci_register_device. At the migration src end, When we hotplug two pci devices, such as virtio-net. Qemu will assign devfn 4 (assumed the previous 3 slots and the fifth have been assigned) for the first nic, and assign devfn 6 for the second nic. After that, I unplug the first nic. At the migrate dst end, I start the vm adding a virtio-net nic. Try to execute migration, qemu report Unknown ramblock :00:06.0/virtio-net-pci.rom, cannot accept migration. qemu: warning: error while loading state for instance 0x0 of device 'ram' load of migration failed How reproducible: 100% Steps to Reproduce: 1. at src end, boot guset with: /usr/bin/qemu-kvm -enable-kvm -m 512 -smp 2 -name suse11sp3 -boot c -drive file=/home/sles11sp3.img,if=none,id=drive-virtio-disk0,format=raw,\ cache=none,aio=native -device virtio-blk-pci,scsi=off,bus=pci.0,addr=0x5,drive=drive-virtio-disk0,id=virtio-disk0,bootindex=1 -vnc 0.0.0.0:10 \ -monitor stdio -netdev type=tap,id=net0 -device virtio-net,id=nic0,netdev=net0,mac=52:54:00:12:34:57 (qemu) info pci Bus 0, device 0, function 0: Host bridge: PCI device 8086:1237 id Bus 0, device 1, function 0: ISA bridge: PCI device 8086:7000 id Bus 0, device 1, function 1: IDE controller: PCI device 8086:7010 BAR4: I/O at 0xc060 [0xc06f]. id Bus 0, device 1, function 3: Bridge: PCI device 8086:7113 IRQ 9. id Bus 0, device 2, function 0: VGA controller: PCI device 1013:00b8 BAR0: 32 bit prefetchable memory at 0xfc00 [0xfdff]. BAR1: 32 bit memory at 0xfebd [0xfebd0fff]. BAR6: 32 bit memory at 0x [0xfffe]. id Bus 0, device 3, function 0: Ethernet controller: PCI device 1af4:1000 IRQ 11. BAR0: I/O at 0xc040 [0xc05f]. BAR1: 32 bit memory at 0xfebd1000 [0xfebd1fff]. BAR6: 32 bit memory at 0x [0x0003fffe]. id nic0 Bus 0, device 5, function 0: SCSI controller: PCI device 1af4:1001 IRQ 10. BAR0: I/O at 0xc000 [0xc03f]. BAR1: 32 bit memory at 0xfebd2000 [0xfebd2fff]. id virtio-disk0 (qemu) info network nic0: index=0,type=nic,model=virtio-net-pci,macaddr=52:54:00:12:34:57 \ net0: index=0,type=tap,ifname=tap0,script=/etc/qemu-ifup,downscript=/etc/qemu-ifdown 2.hotplug two nics: (qemu) netdev_add user,id=net1 (qemu) device_add virtio-net-pci,netdev=net1,id=nic1,mac=52:54:00:12:34:58 (qemu) netdev_add user,id=net2 (qemu) device_add virtio-net-pci,netdev=net2,id=nic2,mac=52:54:00:12:34:59 (qemu) info network nic0: index=0,type=nic,model=virtio-net-pci,macaddr=52:54:00:12:34:57 \ net0: index=0,type=tap,ifname=tap0,script=/etc/qemu-ifup,downscript=/etc/qemu-ifdown nic1: index=0,type=nic,model=virtio-net-pci,macaddr=52:54:00:12:34:58 \ net1: index=0,type=user,net=10.0.2.0,restrict=off nic2: index=0,type=nic,model=virtio-net-pci,macaddr=52:54:00:12:34:59 \ net2: index=0,type=user,net=10.0.2.0,restrict=off 3. unplug the first plugged nic: (qemu) device_del nic1 (qemu) info pci Bus 0, device 0, function 0: Host bridge: PCI device 8086:1237 id Bus 0, device 1, function 0: ISA bridge: PCI device 8086:7000 id Bus 0, device 1, function 1: IDE controller: PCI device 8086:7010 BAR4: I/O at 0xc060 [0xc06f]. id Bus 0, device 1, function 3: Bridge: PCI device 8086:7113 IRQ 9. id Bus 0, device 2, function 0: VGA controller: PCI device 1013:00b8 BAR0: 32 bit prefetchable memory at 0xfc00 [0xfdff]. BAR1: 32 bit memory at 0xfebd [0xfebd0fff]. BAR6: 32 bit memory at 0x [0xfffe]. id Bus 0, device 3, function 0: Ethernet controller: PCI device 1af4:1000 IRQ 11. BAR0: I/O at 0xc040 [0xc05f]. BAR1: 32 bit memory at 0xfebd1000 [0xfebd1fff]. BAR6: 32 bit memory at 0x [0x0003fffe]. id nic0 Bus 0, device 5, function 0: SCSI controller: PCI device 1af4:1001 IRQ 10. BAR0: I/O at 0xc000 [0xc03f]. BAR1: 32 bit memory at 0xfebd2000 [0xfebd2fff]. id virtio-disk0 Bus 0, device 6, function 0: Ethernet controller: PCI device 1af4:1000 IRQ 0. BAR0: I/O at 0x1020 [0x103f]. BAR1: 32 bit memory at 0x80041000 [0x80041fff]. BAR6: 32 bit memory at 0x [0x0003fffe]. id nic2 4. at the dest end, boot guset with: /usr/bin/qemu-kvm -enable-kvm -m 512 -smp 2 -name suse11sp3 -boot c -drive file=/home/sles11sp3.img,if=none,id=drive-virtio-disk0, \ format=raw,cache=none,aio=native -device virtio-blk-pci,scsi=off,bus=pci.0,addr=0x5,drive=drive-virtio-disk0,id=virtio-disk0,\ bootindex=1 -vnc 0.0.0.0:10 -monitor stdio -netdev type=tap,id=net0 -device
[Qemu-devel] [PATCH] hw/ppc: Remove unused defines
Signed-off-by: Stefan Weil s...@weilnetz.de --- hw/ppc/ppc4xx_devs.c |2 -- 1 file changed, 2 deletions(-) diff --git a/hw/ppc/ppc4xx_devs.c b/hw/ppc/ppc4xx_devs.c index 239aada..9160ee7 100644 --- a/hw/ppc/ppc4xx_devs.c +++ b/hw/ppc/ppc4xx_devs.c @@ -27,8 +27,6 @@ #include qemu/log.h #include exec/address-spaces.h -//#define DEBUG_MMIO -//#define DEBUG_UNASSIGNED #define DEBUG_UIC -- 1.7.10.4
[Qemu-devel] [PULL v2 00/35] acpi, pci, pc, virtio fixes and enhancements
Hi Anthony, I forgot to Cc you on the previous version of this pull request. So here's v2 - it also includes some more changes that got merged since then. I also used this opportunity for smash in a compat bugfix. Please ignore the previous pull request. The following changes since commit 0169c511554cb0014a00290b0d3d26c31a49818f: Merge remote-tracking branch 'qemu-kvm/uq/master' into staging (2014-01-24 15:52:44 -0800) are available in the git repository at: git://git.kernel.org/pub/scm/virt/kvm/mst/qemu.git tags/for_anthony for you to fetch changes up to a75143eda2ddf581b51e96c000974bcdfe2cbd10: MAINTAINERS: add self as virtio co-maintainer (2014-01-26 13:11:45 +0200) acpi,pci,pc,virtio fixes and enhancements This includes new unit-tests for acpi by Marcel, hotplug for pci bridges by myself (piix only so far) and cpu hotplug for q35. And a bunch of fixes all over the place as usual. I included the patch to fix memory alignment for q35 as well - even though it limits 32 bit guests to 3G (they previously could address more memory with PAE). To remove the limit, this will have to be fixed in seabios. I also added self as virtio co-maintainer so I don't need to troll the list for patches to review. Signed-off-by: Michael S. Tsirkin m...@redhat.com Alexey Kardashevskiy (1): tests: fix acpi to work on bigendian host Eduardo Habkost (2): pc: Save size of RAM below 4GB acpi: Fix PCI hole handling on build_srat() Gabriel L. Somlo (2): Add DSDT node for AppleSMC ACPI: Fix AppleSMC _STA size Gerd Hoffmann (1): q35: gigabyte alignment for ram Igor Mammedov (9): pc: make: fix dependencies: rebuild when included file is changed acpi: factor out common cpu hotplug code for PIIX4/Q35 acpi: ich9: add CPU hotplug handling to Q35 machine pc: set PRST base in DSDT depending on chipset pc: PIIX DSDT: exclude CPU/PCI hotplug GPE0 IO range from PCI bus resources pc: Q35 DSDT: exclude CPU hotplug IO range from PCI bus resources pc: ACPI: expose PRST IO range via _CRS pc: ACPI: unify source of CPU hotplug IO base/len pc: ACPI: update acpi-dsdt.hex.generated q35-acpi-dsdt.hex.generated Laszlo Ersek (1): Python-lang gdb script to extract x86_64 guest vmcore from qemu coredump Marcel Apfelbaum (11): acpi unit-test: add test files configure: added acpi unit-test files acpi unit-test: compare DSDT and SSDT tables against expected values configure: add CONFIG_IASL to config-host.h acpi unit-test: extract iasl executable from configuration acpi unit-test: added script to rebuild the expected aml files acpi unit-test: hook to rebuild expected aml files acpi unit-test: renamed ssdt_tables to tables acpi unit-test: resolved iasl crash acpi unit-test: do not fail on asl mismatch hw/pci: fix error flow in pci multifunction init Michael S. Tsirkin (7): pci: add pci_for_each_bus_depth_first pcihp: generalization of piix4 acpi piix4: add acpi pci hotplug support acpi-build: enable hotplug for PCI bridges acpi-test: update expected AML since recent changes q35: document gigabyte_align MAINTAINERS: add self as virtio co-maintainer Stefan Weil (1): virtio: Fix return value for dummy function vhost_net_virtqueue_pending configure| 4 + include/hw/acpi/cpu_hotplug.h| 27 ++ include/hw/acpi/cpu_hotplug_defs.h | 24 ++ include/hw/acpi/ich9.h | 4 + include/hw/acpi/pcihp.h | 72 ++ include/hw/i386/pc.h | 7 +- include/hw/isa/isa.h | 7 + include/hw/pci/pci.h | 14 ++ hw/acpi/cpu_hotplug.c| 64 + hw/acpi/ich9.c | 14 ++ hw/acpi/pcihp.c | 316 +++ hw/acpi/piix4.c | 155 ++-- hw/i386/acpi-build.c | 364 +-- hw/i386/pc.c | 1 + hw/i386/pc_q35.c | 20 +- hw/misc/applesmc.c | 1 - hw/net/vhost_net.c | 2 +- hw/pci/pci.c | 48 +++- tests/acpi-test.c| 305 +++--- MAINTAINERS | 1 + docs/specs/acpi_cpu_hotplug.txt | 4 +- hw/acpi/Makefile.objs| 3 +- hw/i386/Makefile.objs| 2 +- hw/i386/acpi-dsdt-cpu-hotplug.dsl| 14 +- hw/i386/acpi-dsdt-isa.dsl| 11 + hw/i386/acpi-dsdt-pci-crs.dsl
[Qemu-devel] [PULL v2 03/35] ACPI: Fix AppleSMC _STA size
From: Gabriel L. Somlo gso...@gmail.com Minimize the storage used for AppleSMC's _STA (8bit), relying on ASL to implicitly convert it to the officially specified 32bit value. Signed-off-by: Gabriel Somlo so...@cmu.edu Signed-off-by: Michael S. Tsirkin m...@redhat.com --- hw/i386/acpi-build.c | 11 +-- hw/i386/acpi-dsdt-isa.dsl | 4 ++-- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c index 30bfcd2..1d62866 100644 --- a/hw/i386/acpi-build.c +++ b/hw/i386/acpi-build.c @@ -81,7 +81,7 @@ typedef struct AcpiMiscInfo { static void acpi_get_dsdt(AcpiMiscInfo *info) { -unsigned short applesmc_sta_val, *applesmc_sta_off; +uint16_t *applesmc_sta; Object *piix = piix4_pm_find(); Object *lpc = ich9_lpc_find(); assert(!!piix != !!lpc); @@ -89,18 +89,17 @@ static void acpi_get_dsdt(AcpiMiscInfo *info) if (piix) { info-dsdt_code = AcpiDsdtAmlCode; info-dsdt_size = sizeof AcpiDsdtAmlCode; -applesmc_sta_off = piix_dsdt_applesmc_sta; +applesmc_sta = piix_dsdt_applesmc_sta; } if (lpc) { info-dsdt_code = Q35AcpiDsdtAmlCode; info-dsdt_size = sizeof Q35AcpiDsdtAmlCode; -applesmc_sta_off = q35_dsdt_applesmc_sta; +applesmc_sta = q35_dsdt_applesmc_sta; } /* Patch in appropriate value for AppleSMC _STA */ -applesmc_sta_val = applesmc_find() ? 0x0b : 0x00; -*(uint16_t *)(info-dsdt_code + *applesmc_sta_off) = -cpu_to_le16(applesmc_sta_val); +*(uint8_t *)(info-dsdt_code + *applesmc_sta) = +applesmc_find() ? 0x0b : 0x00; } static diff --git a/hw/i386/acpi-dsdt-isa.dsl b/hw/i386/acpi-dsdt-isa.dsl index 46942c1..deb37de 100644 --- a/hw/i386/acpi-dsdt-isa.dsl +++ b/hw/i386/acpi-dsdt-isa.dsl @@ -19,8 +19,8 @@ Scope(\_SB.PCI0.ISA) { Device (SMC) { Name(_HID, EisaId(APP0001)) /* _STA will be patched to 0x0B if AppleSMC is present */ -ACPI_EXTRACT_NAME_WORD_CONST DSDT_APPLESMC_STA -Name(_STA, 0xFF00) +ACPI_EXTRACT_NAME_BYTE_CONST DSDT_APPLESMC_STA +Name(_STA, 0xF0) Name(_CRS, ResourceTemplate () { IO (Decode16, 0x0300, 0x0300, 0x01, 0x20) IRQNoFlags() { 6 } -- MST
[Qemu-devel] [PULL v2 06/35] configure: added acpi unit-test files
From: Marcel Apfelbaum marce...@redhat.com Ensure configure will set-up links for the files if the build is created in other directory. Signed-off-by: Marcel Apfelbaum marce...@redhat.com Signed-off-by: Michael S. Tsirkin m...@redhat.com --- configure | 4 1 file changed, 4 insertions(+) diff --git a/configure b/configure index b472694..236764a 100755 --- a/configure +++ b/configure @@ -4774,6 +4774,10 @@ for bios_file in \ do FILES=$FILES pc-bios/`basename $bios_file` done +for test_file in `find $source_path/tests/acpi-test-data -type f` +do +FILES=$FILES tests/acpi-test-data`echo $test_file | sed -e 's/.*acpi-test-data//'` +done mkdir -p $DIRS for f in $FILES ; do if [ -e $source_path/$f ] [ $source_path != `pwd` ]; then -- MST
[Qemu-devel] [PULL v2 01/35] Python-lang gdb script to extract x86_64 guest vmcore from qemu coredump
From: Laszlo Ersek ler...@redhat.com When qemu dies unexpectedly, for example in response to an explicit abort() call, or (more importantly) when an external signal is delivered to it that results in a coredump, sometimes it is useful to extract the guest vmcore from the qemu process' memory image. The guest vmcore might help understand an emulation problem in qemu, or help debug the guest. This script reimplements (and cuts many features of) the qmp_dump_guest_memory() command in gdb/Python, https://sourceware.org/gdb/current/onlinedocs/gdb/Python-API.html working off the saved memory image of the qemu process. The docstring in the patch (serving as gdb help text) describes the limitations relative to the QMP command. Dependencies of qmp_dump_guest_memory() have been reimplemented as needed. I sought to follow the general structure, sticking to original function names where possible. However, keeping it simple prevailed in some places. The patch has been tested with a 4 VCPU, 768 MB, RHEL-6.4 (2.6.32-358.el6.x86_64) guest: - The script printed guest RAM blocks: target_start target_end host_addrmessage count --- - 000a 7f95d000 added 1 000a 000b 7f960ac0 added 2 000c 000ca000 7f95d00c added 3 000ca000 000cd000 7f95d00ca000 joined 3 000cd000 000d 7f95d00cd000 joined 3 000d 000f 7f95d00d joined 3 000f 0010 7f95d00f joined 3 0010 3000 7f95d010 joined 3 fc00 fc80 7f960ac0 added 4 fffe 0001 7f961880 added 5 dumping range at 7f95d000 for length 000a dumping range at 7f960ac0 for length 0001 dumping range at 7f95d00c for length 2ff4 dumping range at 7f960ac0 for length 0080 dumping range at 7f961880 for length 0002 - The vmcore was checked with readelf, comparing the results against a vmcore written by qmp_dump_guest_memory(): --- theirs 2013-09-12 17:38:59.797289404 +0200 +++ mine2013-09-12 17:39:03.820289404 +0200 @@ -27,16 +27,16 @@ Type Offset VirtAddr PhysAddr FileSizMemSiz Flags Align NOTE 0x0190 0x 0x - 0x0ca0 0x0ca0 0 - LOAD 0x0e30 0x 0x + 0x001c 0x001c 0 + LOAD 0x01ac 0x 0x 0x000a 0x000a 0 - LOAD 0x000a0e30 0x 0x000a + LOAD 0x000a01ac 0x 0x000a 0x0001 0x0001 0 - LOAD 0x000b0e30 0x 0x000c + LOAD 0x000b01ac 0x 0x000c 0x2ff4 0x2ff4 0 - LOAD 0x2fff0e30 0x 0xfc00 + LOAD 0x2fff01ac 0x 0xfc00 0x0080 0x0080 0 - LOAD 0x307f0e30 0x 0xfffe + LOAD 0x307f01ac 0x 0xfffe 0x0002 0x0002 0 There is no dynamic section in this file. @@ -47,13 +47,6 @@ No version information found in this file. -Notes at offset 0x0190 with length 0x0ca0: +Notes at offset 0x0190 with length 0x001c: OwnerData size Description - CORE 0x0150 NT_PRSTATUS (prstatus structure) - CORE 0x0150 NT_PRSTATUS (prstatus structure) - CORE 0x0150 NT_PRSTATUS (prstatus structure) - CORE 0x0150 NT_PRSTATUS (prstatus structure) - QEMU 0x01b0 Unknown note type: (0x) - QEMU 0x01b0 Unknown note type: (0x) - QEMU 0x01b0 Unknown note type: (0x) - QEMU 0x01b0 Unknown note type: (0x) + NONE 0x0005 Unknown note type: (0x) - The vmcore was checked with crash too, again comparing the results against a vmcore written by qmp_dump_guest_memory(): --- guest.vmcore.log2 2013-09-12 17:52:27.074289201 +0200 +++ example.dump.log2 2013-09-12 17:52:15.904289203 +0200 @@
[Qemu-devel] [PULL v2 02/35] Add DSDT node for AppleSMC
From: Gabriel L. Somlo gso...@gmail.com AppleSMC (-device isa-applesmc) is required to boot OS X guests. OS X expects a SMC node to be present in the ACPI DSDT. This patch adds a SMC node to the DSDT, and dynamically patches the return value of SMC._STA to either 0x0B if the chip is present, or otherwise to 0x00, before booting the guest. Signed-off-by: Gabriel Somlo so...@cmu.edu Signed-off-by: Michael S. Tsirkin m...@redhat.com --- include/hw/isa/isa.h | 7 +++ hw/i386/acpi-build.c | 9 + hw/misc/applesmc.c| 1 - hw/i386/acpi-dsdt-isa.dsl | 11 +++ hw/i386/acpi-dsdt.dsl | 1 + hw/i386/q35-acpi-dsdt.dsl | 1 + 6 files changed, 29 insertions(+), 1 deletion(-) diff --git a/include/hw/isa/isa.h b/include/hw/isa/isa.h index fa45a5b..e0c749f 100644 --- a/include/hw/isa/isa.h +++ b/include/hw/isa/isa.h @@ -20,6 +20,13 @@ #define TYPE_ISA_BUS ISA #define ISA_BUS(obj) OBJECT_CHECK(ISABus, (obj), TYPE_ISA_BUS) +#define TYPE_APPLE_SMC isa-applesmc + +static inline bool applesmc_find(void) +{ +return object_resolve_path_type(, TYPE_APPLE_SMC, NULL); +} + typedef struct ISADeviceClass { DeviceClass parent_class; } ISADeviceClass; diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c index 48312f5..30bfcd2 100644 --- a/hw/i386/acpi-build.c +++ b/hw/i386/acpi-build.c @@ -36,6 +36,7 @@ #include hw/nvram/fw_cfg.h #include bios-linker-loader.h #include hw/loader.h +#include hw/isa/isa.h /* Supported chipsets: */ #include hw/acpi/piix4.h @@ -80,6 +81,7 @@ typedef struct AcpiMiscInfo { static void acpi_get_dsdt(AcpiMiscInfo *info) { +unsigned short applesmc_sta_val, *applesmc_sta_off; Object *piix = piix4_pm_find(); Object *lpc = ich9_lpc_find(); assert(!!piix != !!lpc); @@ -87,11 +89,18 @@ static void acpi_get_dsdt(AcpiMiscInfo *info) if (piix) { info-dsdt_code = AcpiDsdtAmlCode; info-dsdt_size = sizeof AcpiDsdtAmlCode; +applesmc_sta_off = piix_dsdt_applesmc_sta; } if (lpc) { info-dsdt_code = Q35AcpiDsdtAmlCode; info-dsdt_size = sizeof Q35AcpiDsdtAmlCode; +applesmc_sta_off = q35_dsdt_applesmc_sta; } + +/* Patch in appropriate value for AppleSMC _STA */ +applesmc_sta_val = applesmc_find() ? 0x0b : 0x00; +*(uint16_t *)(info-dsdt_code + *applesmc_sta_off) = +cpu_to_le16(applesmc_sta_val); } static diff --git a/hw/misc/applesmc.c b/hw/misc/applesmc.c index 1e8d183..627adb9 100644 --- a/hw/misc/applesmc.c +++ b/hw/misc/applesmc.c @@ -66,7 +66,6 @@ struct AppleSMCData { QLIST_ENTRY(AppleSMCData) node; }; -#define TYPE_APPLE_SMC isa-applesmc #define APPLE_SMC(obj) OBJECT_CHECK(AppleSMCState, (obj), TYPE_APPLE_SMC) typedef struct AppleSMCState AppleSMCState; diff --git a/hw/i386/acpi-dsdt-isa.dsl b/hw/i386/acpi-dsdt-isa.dsl index 89caa16..46942c1 100644 --- a/hw/i386/acpi-dsdt-isa.dsl +++ b/hw/i386/acpi-dsdt-isa.dsl @@ -16,6 +16,17 @@ /* Common legacy ISA style devices. */ Scope(\_SB.PCI0.ISA) { +Device (SMC) { +Name(_HID, EisaId(APP0001)) +/* _STA will be patched to 0x0B if AppleSMC is present */ +ACPI_EXTRACT_NAME_WORD_CONST DSDT_APPLESMC_STA +Name(_STA, 0xFF00) +Name(_CRS, ResourceTemplate () { +IO (Decode16, 0x0300, 0x0300, 0x01, 0x20) +IRQNoFlags() { 6 } +}) +} + Device(RTC) { Name(_HID, EisaId(PNP0B00)) Name(_CRS, ResourceTemplate() { diff --git a/hw/i386/acpi-dsdt.dsl b/hw/i386/acpi-dsdt.dsl index a377424..b87c6e0 100644 --- a/hw/i386/acpi-dsdt.dsl +++ b/hw/i386/acpi-dsdt.dsl @@ -114,6 +114,7 @@ DefinitionBlock ( } } +#define DSDT_APPLESMC_STA piix_dsdt_applesmc_sta #include acpi-dsdt-isa.dsl diff --git a/hw/i386/q35-acpi-dsdt.dsl b/hw/i386/q35-acpi-dsdt.dsl index 7934a9d..ee38fd6 100644 --- a/hw/i386/q35-acpi-dsdt.dsl +++ b/hw/i386/q35-acpi-dsdt.dsl @@ -171,6 +171,7 @@ DefinitionBlock ( } } +#define DSDT_APPLESMC_STA q35_dsdt_applesmc_sta #include acpi-dsdt-isa.dsl -- MST
[Qemu-devel] [PULL v2 10/35] acpi unit-test: added script to rebuild the expected aml files
From: Marcel Apfelbaum marce...@redhat.com Acpi unit-test will fail every time the acpi tables change. This script rebuild the expected aml files, so the test will pass. It also validates the modifications. Signed-off-by: Marcel Apfelbaum marce...@redhat.com Signed-off-by: Michael S. Tsirkin m...@redhat.com --- tests/acpi-test-data/rebuild-expected-aml.sh | 36 1 file changed, 36 insertions(+) create mode 100755 tests/acpi-test-data/rebuild-expected-aml.sh diff --git a/tests/acpi-test-data/rebuild-expected-aml.sh b/tests/acpi-test-data/rebuild-expected-aml.sh new file mode 100755 index 000..ab98498 --- /dev/null +++ b/tests/acpi-test-data/rebuild-expected-aml.sh @@ -0,0 +1,36 @@ +#! /bin/bash + +# +# Rebuild expected AML files for acpi unit-test +# +# Copyright (c) 2013 Red Hat Inc. +# +# Authors: +# Marcel Apfelbaum marce...@redhat.com +# +# This work is licensed under the terms of the GNU GPLv2. +# See the COPYING.LIB file in the top-level directory. + +qemu= + +if [ -e x86_64-softmmu/qemu-system-x86_64 ]; then +qemu=x86_64-softmmu/qemu-system-x86_64 +elif [ -e i386-softmmu/qemu-system-i386 ]; then +qemu=i386-softmmu/qemu-system-i386 +else +echo Run 'make' to build the qemu exectutable! +echo Run this script from the build directory. +exit 1; +fi + +if [ ! -e tests/acpi-test ]; then +echo Test: acpi-test is required! Run make check before this script. +echo Run this script from the build directory. +exit 1; +fi + +TEST_ACPI_REBUILD_AML=y QTEST_QEMU_BINARY=$qemu tests/acpi-test + +echo The files were rebuilt and can be added to git. +echo However, if new files were created, please copy them manually \ + to tests/acpi-test-data/pc/ or tests/acpi-test-data/q35/ . -- MST
[Qemu-devel] [PULL v2 11/35] acpi unit-test: hook to rebuild expected aml files
From: Marcel Apfelbaum marce...@redhat.com When running the test with TEST_ACPI_REBUILD_AML=y environment variable, the test will rebuild and validate the expected aml files. Signed-off-by: Marcel Apfelbaum marce...@redhat.com Signed-off-by: Michael S. Tsirkin m...@redhat.com --- tests/acpi-test.c | 30 +- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/tests/acpi-test.c b/tests/acpi-test.c index 83e5aed..89c4b81 100644 --- a/tests/acpi-test.c +++ b/tests/acpi-test.c @@ -13,6 +13,7 @@ #include string.h #include stdio.h #include glib.h +#include glib/gstdio.h #include qemu-common.h #include libqtest.h #include qemu/compiler.h @@ -21,6 +22,8 @@ #define MACHINE_PC pc #define MACHINE_Q35 q35 +#define ACPI_REBUILD_EXPECTED_AML TEST_ACPI_REBUILD_AML + /* DSDT and SSDTs format */ typedef struct { AcpiTableHeader header; @@ -363,10 +366,11 @@ static void test_acpi_ssdt_tables(test_data *data) } } -static void dump_aml_files(test_data *data) +static void dump_aml_files(test_data *data, bool rebuild) { AcpiSdtTable *sdt; GError *error = NULL; +gchar *aml_file = NULL; gint fd; ssize_t ret; int i; @@ -375,8 +379,16 @@ static void dump_aml_files(test_data *data) sdt = g_array_index(data-ssdt_tables, AcpiSdtTable, i); g_assert(sdt-aml); -fd = g_file_open_tmp(aml-XX, sdt-aml_file, error); -g_assert_no_error(error); +if (rebuild) { +aml_file = g_strdup_printf(%s/%s/%.4s, data_dir, data-machine, + (gchar *)sdt-header.signature); +fd = g_open(aml_file, O_WRONLY|O_TRUNC|O_CREAT, +S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH); +} else { +fd = g_file_open_tmp(aml-XX, sdt-aml_file, error); +g_assert_no_error(error); +} +g_assert(fd = 0); ret = qemu_write_full(fd, sdt, sizeof(AcpiTableHeader)); g_assert(ret == sizeof(AcpiTableHeader)); @@ -384,6 +396,10 @@ static void dump_aml_files(test_data *data) g_assert(ret == sdt-aml_len); close(fd); + +if (aml_file) { +g_free(aml_file); +} } } @@ -491,7 +507,7 @@ static void test_acpi_asl(test_data *data) memset(exp_data, 0, sizeof(exp_data)); exp_data.ssdt_tables = load_expected_aml(data); -dump_aml_files(data); +dump_aml_files(data, false); for (i = 0; i data-ssdt_tables-len; ++i) { GString *asl, *exp_asl; @@ -557,7 +573,11 @@ static void test_acpi_one(const char *params, test_data *data) test_acpi_ssdt_tables(data); if (iasl) { -test_acpi_asl(data); +if (getenv(ACPI_REBUILD_EXPECTED_AML)) { +dump_aml_files(data, true); +} else { +test_acpi_asl(data); +} } qtest_quit(global_qtest); -- MST
[Qemu-devel] [PULL v2 13/35] acpi unit-test: renamed ssdt_tables to tables
From: Marcel Apfelbaum marce...@redhat.com Just a refactoring, ssdt_tables name was confusing as it included other tables as well. Signed-off-by: Marcel Apfelbaum marce...@redhat.com Reviewed-by: Michael S. Tsirkin m...@redhat.com Signed-off-by: Michael S. Tsirkin m...@redhat.com --- tests/acpi-test.c | 48 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/tests/acpi-test.c b/tests/acpi-test.c index b5ab70a..a3d2b34 100644 --- a/tests/acpi-test.c +++ b/tests/acpi-test.c @@ -44,7 +44,7 @@ typedef struct { AcpiFacsDescriptorRev1 facs_table; uint32_t *rsdt_tables_addr; int rsdt_tables_nr; -GArray *ssdt_tables; /* first is DSDT */ +GArray *tables; } test_data; #define LOW(x) ((x) 0xff) @@ -145,8 +145,8 @@ static void free_test_data(test_data *data) g_free(data-rsdt_tables_addr); } -for (i = 0; i data-ssdt_tables-len; ++i) { -temp = g_array_index(data-ssdt_tables, AcpiSdtTable, i); +for (i = 0; i data-tables-len; ++i) { +temp = g_array_index(data-tables, AcpiSdtTable, i); if (temp-aml) { g_free(temp-aml); } @@ -167,7 +167,7 @@ static void free_test_data(test_data *data) } } -g_array_free(data-ssdt_tables, false); +g_array_free(data-tables, false); } static uint8_t acpi_checksum(const uint8_t *data, int len) @@ -342,27 +342,27 @@ static void test_acpi_dsdt_table(test_data *data) uint32_t addr = data-fadt_table.dsdt; memset(dsdt_table, 0, sizeof(dsdt_table)); -data-ssdt_tables = g_array_new(false, true, sizeof(AcpiSdtTable)); +data-tables = g_array_new(false, true, sizeof(AcpiSdtTable)); test_dst_table(dsdt_table, addr); g_assert_cmphex(dsdt_table.header.signature, ==, ACPI_DSDT_SIGNATURE); /* Place DSDT first */ -g_array_append_val(data-ssdt_tables, dsdt_table); +g_array_append_val(data-tables, dsdt_table); } -static void test_acpi_ssdt_tables(test_data *data) +static void test_acpi_tables(test_data *data) { -int ssdt_tables_nr = data-rsdt_tables_nr - 1; /* fadt is first */ +int tables_nr = data-rsdt_tables_nr - 1; /* fadt is first */ int i; -for (i = 0; i ssdt_tables_nr; i++) { +for (i = 0; i tables_nr; i++) { AcpiSdtTable ssdt_table; memset(ssdt_table, 0 , sizeof(ssdt_table)); uint32_t addr = data-rsdt_tables_addr[i + 1]; /* fadt is first */ test_dst_table(ssdt_table, addr); -g_array_append_val(data-ssdt_tables, ssdt_table); +g_array_append_val(data-tables, ssdt_table); } } @@ -375,8 +375,8 @@ static void dump_aml_files(test_data *data, bool rebuild) ssize_t ret; int i; -for (i = 0; i data-ssdt_tables-len; ++i) { -sdt = g_array_index(data-ssdt_tables, AcpiSdtTable, i); +for (i = 0; i data-tables-len; ++i) { +sdt = g_array_index(data-tables, AcpiSdtTable, i); g_assert(sdt-aml); if (rebuild) { @@ -474,10 +474,10 @@ static GArray *load_expected_aml(test_data *data) GError *error = NULL; gboolean ret; -GArray *exp_ssdt_tables = g_array_new(false, true, sizeof(AcpiSdtTable)); -for (i = 0; i data-ssdt_tables-len; ++i) { +GArray *exp_tables = g_array_new(false, true, sizeof(AcpiSdtTable)); +for (i = 0; i data-tables-len; ++i) { AcpiSdtTable exp_sdt; -sdt = g_array_index(data-ssdt_tables, AcpiSdtTable, i); +sdt = g_array_index(data-tables, AcpiSdtTable, i); memset(exp_sdt, 0, sizeof(exp_sdt)); exp_sdt.header.signature = sdt-header.signature; @@ -493,10 +493,10 @@ static GArray *load_expected_aml(test_data *data) g_assert(exp_sdt.aml); g_assert(exp_sdt.aml_len); -g_array_append_val(exp_ssdt_tables, exp_sdt); +g_array_append_val(exp_tables, exp_sdt); } -return exp_ssdt_tables; +return exp_tables; } static void test_acpi_asl(test_data *data) @@ -506,18 +506,18 @@ static void test_acpi_asl(test_data *data) test_data exp_data; memset(exp_data, 0, sizeof(exp_data)); -exp_data.ssdt_tables = load_expected_aml(data); +exp_data.tables = load_expected_aml(data); dump_aml_files(data, false); -for (i = 0; i data-ssdt_tables-len; ++i) { +for (i = 0; i data-tables-len; ++i) { GString *asl, *exp_asl; -sdt = g_array_index(data-ssdt_tables, AcpiSdtTable, i); -exp_sdt = g_array_index(exp_data.ssdt_tables, AcpiSdtTable, i); +sdt = g_array_index(data-tables, AcpiSdtTable, i); +exp_sdt = g_array_index(exp_data.tables, AcpiSdtTable, i); -load_asl(data-ssdt_tables, sdt); +load_asl(data-tables, sdt); asl = normalize_asl(sdt-asl); -load_asl(exp_data.ssdt_tables, exp_sdt); +load_asl(exp_data.tables, exp_sdt); exp_asl = normalize_asl(exp_sdt-asl); g_assert(!g_strcmp0(asl-str, exp_asl-str)); @@
[Qemu-devel] [PULL v2 08/35] configure: add CONFIG_IASL to config-host.h
From: Marcel Apfelbaum marce...@redhat.com Acpi unit-tests will extract iasl executable from CONFIG_IASL define. Signed-off-by: Marcel Apfelbaum marce...@redhat.com Signed-off-by: Michael S. Tsirkin m...@redhat.com --- scripts/create_config | 4 1 file changed, 4 insertions(+) diff --git a/scripts/create_config b/scripts/create_config index b1adbf5..06f5316 100755 --- a/scripts/create_config +++ b/scripts/create_config @@ -26,6 +26,10 @@ case $line in # save for the next definitions prefix=${line#*=} ;; + IASL=*) # iasl executable +value=${line#*=} +echo #define CONFIG_IASL $value +;; CONFIG_AUDIO_DRIVERS=*) drivers=${line#*=} echo #define CONFIG_AUDIO_DRIVERS \\ -- MST
[Qemu-devel] [PULL v2 29/35] acpi-test: update expected AML since recent changes
Signed-off-by: Michael S. Tsirkin m...@redhat.com --- tests/acpi-test-data/pc/DSDT | Bin 4407 - 4582 bytes tests/acpi-test-data/pc/SSDT | Bin 2104 - 2200 bytes tests/acpi-test-data/q35/DSDT | Bin 7344 - 7438 bytes tests/acpi-test-data/q35/SSDT | Bin 2104 - 475 bytes 4 files changed, 0 insertions(+), 0 deletions(-) diff --git a/tests/acpi-test-data/pc/DSDT b/tests/acpi-test-data/pc/DSDT index b12e5eb85bb22f27fe10ce0fcf1d9a71f38360eb..fbf1c3e6e8f791f8e7bae95ad43ea11d0be64c72 100644 GIT binary patch delta 402 zcmdn4^h}w{CDk8nIHoLHm_xogxx?@xe~0nVNV9L_m!Gca)T=OO_H#S|%z`(Gu zgO`Dkhnazaf8GCe3=AI`V0?x3_t!Hp9DwtmtpER?fk7r;{96jo`7Iuqb`tHToVFZ zVayquiy2=r+Ih+8GsEoj40eoZqf%bltV_waP#VH03rcJRrapYp)h6SO78Ky( zb!TK?W?*JiP;y|XWZ0a`yq1yCW3n`qg!-?lb%8Be%dhE|%yZV=W$uHDbA)3+2 z$Jv`fL^Z(K)r%=w8N~blzaRr7Sy0KC$3z*J_aH5?;cvc_}L|7o*_hHPV|qnqs zfUX9+h1bzJz|+9Mzy#_NUM?=6OV$ISLM2cLVJ1*C!Wc(1*9!46R958KRYA5MG1W Vi6ju=zQPjwAq5G5NGW4gkajYjFSo delta 249 zcmaE+yj_XQCDjzT#$i*(Q6`Cr--Ote6Uk|fU~CohjWl?u%Ht=SKh?s#;pGt7#KcJ z=4Y%Gj|m7iHtGUNawP~!k8JG7c;(M6!4MOXNDQz8SEIp`84xdMn+m8_1QB7yV zu3n4m5dn-P6n=COBh7V0-XKa7z!8?7U@h);F2#*SRhypv^%ttF@brCN5zxIhRb z;(`$2V25Y%f-kynNQ%Uv49_EynBEvN4$rp3$LSdfTw|hff7cTfC2f0fUHWysLpB PLkz-6AnPVq3FZI*Bg{dn diff --git a/tests/acpi-test-data/pc/SSDT b/tests/acpi-test-data/pc/SSDT index 5ab1b96af004737738f3386e73e4dc1d425ab77e..a51c68e21b7f1556009331966c56eb7a563dd51e 100644 GIT binary patch literal 2200 zcmZ{lNl)8A738$Fm^(mVDFnPIbzDi#Li9ai$rEQUzp4C)1`r;1BTRW3bp5)qL zAN^;g-{%Xq3Yz4dHp_m#^YryM3DT{8Pkrvj(;W^-WB%+9Mc$MIL3d=D_%35J3^Kr z=`adq`T6xADuTZr2$n_$eL+@X7Ymr;lBqiULCM@!6?O^td|NJ%mL$lS=S3jd8d z02{Pft@8DoycC|~ej^LmHqp+!Nbc$muFEc^|fWj^i}pEJBf(jP*x6~u9uTK}t= z1)k{ksuYRKZm}6Wl^zFd%zhQdM%7;E20X!nCxh|8E`R9qM7teg)}`MSwTfZ9!z;lw z?F;*Xhm2g*X~ac0ftv#kK$-z$10r$3+wx5hNs{E`sSJIH-XoMuEgjm#)F}c?4@X zVs=%w-GqO-gXgyjHe7)Bv}s69nI(AImV$~kCW4nxhL~+Xs`#g-{?N?#PtBq)VlbD zmrVCWc)|MjyP|n4;X3zXBd$0=)%p+GrKO)$o=pfIjj+Vttww(1HrYmv~R3f`X ziO`Y~CFlab1HP7tU95(5+Aq4OAfUE|gh7u*KNvNqp56N04w5wQS|PNeLXXJ0 zKI)JC2N(?stP?Ot3{}#M9Eqsw5CE$XX|~u0+YYNapb;)WIYAaE)E)lwLOrrB z6S}NK$+|-5iVF3~x=QG(5+;zp=BMAnQ7zq?ZY8-#AC(2%T~gl;NPvThNr9w~1 zx=rY|5+;np*#OW?bb$c87H}?^4$==Ll3yu-K4S0K3^FG%!%pfe?xq#0qrrgAql znFa~Al`Q2jO}hdl*c`GB=Q@~nI2pX+S%S7PCJ|qUev6^`HrR?g9NWz)}`rH2QSS` zcYB@ZU`H=g)BV$lpAS06lLF{XZ$=9fNQDLjzWGhC}b)8lI4(VF(S-e9K36~jX^ n?Hib9`W9rk-P3-A8G3t%`!RfTnHTrkcbO()zh*;VC4S-yyE{5 literal 2104 zcmZvc%TC)s6o$vSVVs*23wHDs@$dJG(lzDW**_#D-D@X|kyVi%M*}qf}+Xk{6- z-lK0;dL}vlf_AdWcV2v|DK#onnu}yErext2jOx0s(T^Bl-4XEgl7Hic8iz7mVT-# zRNWHAs`C8`;RR=gOh2PO2JZhuX|Ov=INh@bSfh`-VEIbXzq`1f|RyrY_S!O1zf zX|=0bT{{1??M_rClY%#81*djqZAmjL$P$9Vb!sH13`GzTcq~ahjEd7~RTvFtl`K zjlP$;keThZRhk9jM(QDN{?eP5x)u(r|#8;k9dl%*KkSNSxQnRRoeYgiGv{7}O z_xdF0n7)Yzz2xMQL9ai0^tR9Px{HMyWW~UMsK)3zX~0H^rKr0rSI!D^omKO^wCY zAqZtc@31ety6Od)n1r$yXn|@Snds-IzI8OP{t^yz)Y;pB;V9J(VA?9C5GPU)!M^ z^qUbybsxS6eQ2Y**Qwu8bjD|W$Ffxr4e5up=xNkUSrZw?Cwgz{ZLybwmot0Y?B(I* zb$XrdWxpNv3h)YMZoCyyrS9LW3L3SWcK#in}auJ_72#y;n`;IkiB_$^JXt#w=Nd zy)JuYcxAH}vR8puF?$hvRd`ji7qeG`S2KG@?A77bjb6uRxPljJMMNUcBR{+jTb zW)JhX0B^zUVg5XLp4r3vEy7zgdzil^cuQsv^VfpcGJBZ6HoUgk!~8A7TQ+-`zZG~Z zW)JhX3UAfyVgAOt(iT{-#WZ?vxoWHfVW}xFn^oyHvjXy4=ow?v)S!u-RnEdU_M) zh_{Y#M{gT;vME9@h)?Tc#nCGc%RuOK46|FK4f-?1LiVum$^b5GFOQs{EL#Tqiza zcJEXA|I9Ksh^cZjQk74$nOy{~|H+FA*buix~Oa#K^x)jQlIa$iGUA{ALzfO$ M8^p-JNlf|w0)H3)9{OV diff --git a/tests/acpi-test-data/q35/DSDT b/tests/acpi-test-data/q35/DSDT index 59243b952d78c465298e0a2ec05a52f480dd92fb..5086b839a6e11ee819af91e72f71efb3e8d97fe2 100644 GIT binary patch delta 192 zcmdmB*=NP66_MfC(FRV=)aL`8YAm9tMURo0l@CGTC{_=`+U%JH-b$dm4BKJH|h z=+a$8*Gcc)IYg2{15n#0Q5saxrkkI|l^|3UKkdGcqtUFf%GBIWSZ*Y?fkC5N8ye zY%QI^bc1K|Qt4`g=q9~@AlG290lbdR0iFg11}0GLyj)!Fj5m00@GvM;0);Zb5B-~ fkrQW_c1VJ5D|!XH85g`(E~duDA;*s7y2f2gWRa delta 97 zcmeCP+F;4$66_MPL56{Wv2Y{TG)C6%JPZs!HZNsNWfJg_)@P0nc8U*h_B8Mec8uTb y!J;6}$TvAtI)jN}{p8Ei)syRFirKyeGCj4V)VdDgMyt!*nk2?43js@L0a*c^hW{ diff --git a/tests/acpi-test-data/q35/SSDT b/tests/acpi-test-data/q35/SSDT index 186e748e6c16ffef80634be5eae9c3fa17210811..9c6cad8b0b7e009d88232166112ed8877cfe11c0 100644 GIT binary patch delta 32 ocmdlXaGRMcIM^lRHX{QALr%GkH|o?2}UqZoxIA7qpU0Grwf;{X5v literal 2104 zcmZvc%Wl^6o$vS)pc%8Ne?}6%s3)-n+xGUFt%TY3!DwRGMs%+67X#?4XEly6g)S zDenOrUW;-jIsXEfZ1SC%PshI}CzGa8c3=x({pt?FMdhgLWU`=SwaZS`rGXmFNH1r zR8^?@NffKf)6XNw(OiMhqgMYYLp#nGyBj{O`iszZTpV)KR6|s#z*n^bF!1)wBza zaHs`UyLv}=b6-_1U*=WXRWeNcBn{N)w%$BJhRnt5-#*-kIF9ZC_WSy_nDXBiKM zmaeSPmogVJv%R)Tvq0SFo$+JoVJs%%dtu_#z1lF6nck4ucrx}X?}jq7Zmx7~t8kb$ zs*dwopMciPvTxLIk{xe(8)2ctPEhelqKx2BKL8}7G{LdPF{?G{7n`??LiViGBR zbklbTLYdGzh21dO;8q3i`(pjt!I?cF_Pkbws@rf?4ywK`rNAGiw%cUr-0Ak$ zb|?q^W*il`wv1N+UWLqUR{KRI2hY!yU9`XMcP8Z}eaM27K+-kW+`?B(F)%-%M8 zd3brVx5HimUcv0`vR8yxG$pOmEe`k-adPC@aD|k0edz)+w2{(HxF;#;#O@Eo(( zWvjcZ1zI-D)1_1FJi9uWIU_G8IX77l-I=s5k-g-s@LaQp`D?ym_5v26JFEo zVg452Etoybp9jw~dzimPc#CEa^S1V$?ReNTJTzC5A)ZC*EV~Yzh!vKW)JhX0m6a zVg6R(t(rZ|-x|C%vxoUxhqrF_Fn=5HHq0L8Zxi0;f1dZICBuF;yZx*?eaBr-Z^9h$
[Qemu-devel] [PULL v2 14/35] acpi unit-test: resolved iasl crash
From: Marcel Apfelbaum marce...@redhat.com It seems that iasl has an issue when disassembles some ACPI tables using the command line: iasl -e DSDT -e SSDT -d HPET Modified the iasl command line to iasl -d HPET until the problem is solved. The command line remained the same for DSDT and SSDT tables. Reported-by: Michael S. Tsirkin m...@redhat.com Signed-off-by: Marcel Apfelbaum marce...@redhat.com Reviewed-by: Michael S. Tsirkin m...@redhat.com Signed-off-by: Michael S. Tsirkin m...@redhat.com --- tests/acpi-test.c | 18 +++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/tests/acpi-test.c b/tests/acpi-test.c index a3d2b34..6095d07 100644 --- a/tests/acpi-test.c +++ b/tests/acpi-test.c @@ -23,6 +23,7 @@ #define MACHINE_Q35 q35 #define ACPI_REBUILD_EXPECTED_AML TEST_ACPI_REBUILD_AML +#define ACPI_SSDT_SIGNATURE 0x54445353 /* SSDT */ /* DSDT and SSDTs format */ typedef struct { @@ -403,6 +404,11 @@ static void dump_aml_files(test_data *data, bool rebuild) } } +static bool compare_signature(AcpiSdtTable *sdt, uint32_t signature) +{ + return sdt-header.signature == signature; +} + static void load_asl(GArray *sdts, AcpiSdtTable *sdt) { AcpiSdtTable *temp; @@ -419,9 +425,15 @@ static void load_asl(GArray *sdts, AcpiSdtTable *sdt) /* build command line */ g_string_append_printf(command_line, -p %s , sdt-asl_file); -for (i = 0; i 2; ++i) { /* reference DSDT and SSDT */ -temp = g_array_index(sdts, AcpiSdtTable, i); -g_string_append_printf(command_line, -e %s , temp-aml_file); +if (compare_signature(sdt, ACPI_DSDT_SIGNATURE) || +compare_signature(sdt, ACPI_SSDT_SIGNATURE)) { +for (i = 0; i sdts-len; ++i) { +temp = g_array_index(sdts, AcpiSdtTable, i); +if (compare_signature(temp, ACPI_DSDT_SIGNATURE) || +compare_signature(temp, ACPI_SSDT_SIGNATURE)) { +g_string_append_printf(command_line, -e %s , temp-aml_file); +} +} } g_string_append_printf(command_line, -d %s, sdt-aml_file); -- MST
[Qemu-devel] [PULL v2 32/35] acpi: Fix PCI hole handling on build_srat()
From: Eduardo Habkost ehabk...@redhat.com The original SeaBIOS code used the RamSize variable, that was used by SeaBIOS for the size of RAM below 4GB, not for all RAM. When copied to QEMU, the code was changed to use the full RAM size, and this broke the build_srat() code that handles the PCI hole. Change build_srat() to use ram_size_below_4g instead of ram_size, to restore the original behavior from SeaBIOS. Signed-off-by: Eduardo Habkost ehabk...@redhat.com Reviewed-by: Michael S. Tsirkin m...@redhat.com Signed-off-by: Michael S. Tsirkin m...@redhat.com --- hw/i386/acpi-build.c | 10 +- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c index 9cd3d0e..50e83f3 100644 --- a/hw/i386/acpi-build.c +++ b/hw/i386/acpi-build.c @@ -1080,16 +1080,16 @@ build_srat(GArray *table_data, GArray *linker, next_base = mem_base + mem_len; /* Cut out the ACPI_PCI hole */ -if (mem_base = guest_info-ram_size -next_base guest_info-ram_size) { -mem_len -= next_base - guest_info-ram_size; +if (mem_base = guest_info-ram_size_below_4g +next_base guest_info-ram_size_below_4g) { +mem_len -= next_base - guest_info-ram_size_below_4g; if (mem_len 0) { numamem = acpi_data_push(table_data, sizeof *numamem); acpi_build_srat_memory(numamem, mem_base, mem_len, i-1, 1); } mem_base = 1ULL 32; -mem_len = next_base - guest_info-ram_size; -next_base += (1ULL 32) - guest_info-ram_size; +mem_len = next_base - guest_info-ram_size_below_4g; +next_base += (1ULL 32) - guest_info-ram_size_below_4g; } numamem = acpi_data_push(table_data, sizeof *numamem); acpi_build_srat_memory(numamem, mem_base, mem_len, i - 1, 1); -- MST
[Qemu-devel] [PULL v2 21/35] acpi: factor out common cpu hotplug code for PIIX4/Q35
From: Igor Mammedov imamm...@redhat.com .. so it could be used for adding CPU hotplug to Q35 machine Add an additional header with that will be shared between C and ASL code: include/hw/acpi/cpu_hotplug_defs.h Signed-off-by: Igor Mammedov imamm...@redhat.com Reviewed-by: Michael S. Tsirkin m...@redhat.com Signed-off-by: Michael S. Tsirkin m...@redhat.com --- include/hw/acpi/cpu_hotplug.h | 27 + include/hw/acpi/cpu_hotplug_defs.h | 22 +++ hw/acpi/cpu_hotplug.c | 64 +++ hw/acpi/piix4.c| 77 +++--- hw/acpi/Makefile.objs | 2 +- 5 files changed, 120 insertions(+), 72 deletions(-) create mode 100644 include/hw/acpi/cpu_hotplug.h create mode 100644 include/hw/acpi/cpu_hotplug_defs.h create mode 100644 hw/acpi/cpu_hotplug.c diff --git a/include/hw/acpi/cpu_hotplug.h b/include/hw/acpi/cpu_hotplug.h new file mode 100644 index 000..4576400 --- /dev/null +++ b/include/hw/acpi/cpu_hotplug.h @@ -0,0 +1,27 @@ +/* + * QEMU ACPI hotplug utilities + * + * Copyright (C) 2013 Red Hat Inc + * + * Authors: + * Igor Mammedov imamm...@redhat.com + * + * 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 ACPI_HOTPLUG_H +#define ACPI_HOTPLUG_H + +#include hw/acpi/acpi.h +#include hw/acpi/cpu_hotplug_defs.h + +typedef struct AcpiCpuHotplug { +MemoryRegion io; +uint8_t sts[ACPI_GPE_PROC_LEN]; +} AcpiCpuHotplug; + +void AcpiCpuHotplug_add(ACPIGPE *gpe, AcpiCpuHotplug *g, CPUState *cpu); + +void AcpiCpuHotplug_init(MemoryRegion *parent, Object *owner, + AcpiCpuHotplug *gpe_cpu, uint16_t base); +#endif diff --git a/include/hw/acpi/cpu_hotplug_defs.h b/include/hw/acpi/cpu_hotplug_defs.h new file mode 100644 index 000..c6c4f78 --- /dev/null +++ b/include/hw/acpi/cpu_hotplug_defs.h @@ -0,0 +1,22 @@ +/* + * QEMU ACPI hotplug utilities shared defines + * + * Copyright (C) 2013 Red Hat Inc + * + * Authors: + * Igor Mammedov imamm...@redhat.com + * + * 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 ACPI_HOTPLUG_DEFS_H +#define ACPI_HOTPLUG_DEFS_H + +/* + * ONLY DEFINEs are permited in this file since it's shared + * between C and ASL code. + */ +#define ACPI_CPU_HOTPLUG_STATUS 4 +#define ACPI_GPE_PROC_LEN 32 + +#endif diff --git a/hw/acpi/cpu_hotplug.c b/hw/acpi/cpu_hotplug.c new file mode 100644 index 000..48928dc --- /dev/null +++ b/hw/acpi/cpu_hotplug.c @@ -0,0 +1,64 @@ +/* + * QEMU ACPI hotplug utilities + * + * Copyright (C) 2013 Red Hat Inc + * + * Authors: + * Igor Mammedov imamm...@redhat.com + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + */ +#include hw/hw.h +#include hw/acpi/cpu_hotplug.h + +static uint64_t cpu_status_read(void *opaque, hwaddr addr, unsigned int size) +{ +AcpiCpuHotplug *cpus = opaque; +uint64_t val = cpus-sts[addr]; + +return val; +} + +static void cpu_status_write(void *opaque, hwaddr addr, uint64_t data, + unsigned int size) +{ +/* TODO: implement VCPU removal on guest signal that CPU can be removed */ +} + +static const MemoryRegionOps AcpiCpuHotplug_ops = { +.read = cpu_status_read, +.write = cpu_status_write, +.endianness = DEVICE_LITTLE_ENDIAN, +.valid = { +.min_access_size = 1, +.max_access_size = 1, +}, +}; + +void AcpiCpuHotplug_add(ACPIGPE *gpe, AcpiCpuHotplug *g, CPUState *cpu) +{ +CPUClass *k = CPU_GET_CLASS(cpu); +int64_t cpu_id; + +*gpe-sts = *gpe-sts | ACPI_CPU_HOTPLUG_STATUS; +cpu_id = k-get_arch_id(CPU(cpu)); +g-sts[cpu_id / 8] |= (1 (cpu_id % 8)); +} + +void AcpiCpuHotplug_init(MemoryRegion *parent, Object *owner, + AcpiCpuHotplug *gpe_cpu, uint16_t base) +{ +CPUState *cpu; + +CPU_FOREACH(cpu) { +CPUClass *cc = CPU_GET_CLASS(cpu); +int64_t id = cc-get_arch_id(cpu); + +g_assert((id / 8) ACPI_GPE_PROC_LEN); +gpe_cpu-sts[id / 8] |= (1 (id % 8)); +} +memory_region_init_io(gpe_cpu-io, owner, AcpiCpuHotplug_ops, + gpe_cpu, acpi-cpu-hotplug, ACPI_GPE_PROC_LEN); +memory_region_add_subregion(parent, base, gpe_cpu-io); +} diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c index 1aa35bc..12f8dde 100644 --- a/hw/acpi/piix4.c +++ b/hw/acpi/piix4.c @@ -31,6 +31,7 @@ #include exec/address-spaces.h #include hw/acpi/piix4.h #include hw/acpi/pcihp.h +#include hw/acpi/cpu_hotplug.h //#define DEBUG @@ -51,20 +52,14 @@ #define PCI_RMV_BASE 0xae0c #define PIIX4_PROC_BASE 0xaf00 -#define PIIX4_PROC_LEN 32 #define PIIX4_PCI_HOTPLUG_STATUS 2 -#define PIIX4_CPU_HOTPLUG_STATUS 4 struct pci_status { uint32_t up; /* deprecated, maintained for
[Qemu-devel] [PULL v2 09/35] acpi unit-test: extract iasl executable from configuration
From: Marcel Apfelbaum marce...@redhat.com The test checked if iasl is installed by running iasl and checking the error output. It is better to use the iasl executable as appears in configuration. Signed-off-by: Marcel Apfelbaum marce...@redhat.com Signed-off-by: Michael S. Tsirkin m...@redhat.com --- tests/acpi-test.c | 31 --- 1 file changed, 8 insertions(+), 23 deletions(-) diff --git a/tests/acpi-test.c b/tests/acpi-test.c index c3fc603..83e5aed 100644 --- a/tests/acpi-test.c +++ b/tests/acpi-test.c @@ -127,6 +127,11 @@ static uint8_t boot_sector[0x7e000] = { static const char *disk = tests/acpi-test-disk.raw; static const char *data_dir = tests/acpi-test-data; +#ifdef CONFIG_IASL +static const char *iasl = stringify(CONFIG_IASL); +#else +static const char *iasl; +#endif static void free_test_data(test_data *data) { @@ -358,26 +363,6 @@ static void test_acpi_ssdt_tables(test_data *data) } } -static bool iasl_installed(void) -{ -gchar *out = NULL, *out_err = NULL; -bool ret; - -/* pass 'out' and 'out_err' in order to be redirected */ -ret = g_spawn_command_line_sync(iasl, out, out_err, NULL, NULL); - -if (out_err) { -ret = ret (out_err[0] == '\0'); -g_free(out_err); -} - -if (out) { -g_free(out); -} - -return ret; -} - static void dump_aml_files(test_data *data) { AcpiSdtTable *sdt; @@ -406,7 +391,7 @@ static void load_asl(GArray *sdts, AcpiSdtTable *sdt) { AcpiSdtTable *temp; GError *error = NULL; -GString *command_line = g_string_new('iasl' ); +GString *command_line = g_string_new(iasl); gint fd; gchar *out, *out_err; gboolean ret; @@ -417,7 +402,7 @@ static void load_asl(GArray *sdts, AcpiSdtTable *sdt) close(fd); /* build command line */ -g_string_append_printf(command_line, -p %s , sdt-asl_file); +g_string_append_printf(command_line, -p %s , sdt-asl_file); for (i = 0; i 2; ++i) { /* reference DSDT and SSDT */ temp = g_array_index(sdts, AcpiSdtTable, i); g_string_append_printf(command_line, -e %s , temp-aml_file); @@ -571,7 +556,7 @@ static void test_acpi_one(const char *params, test_data *data) test_acpi_dsdt_table(data); test_acpi_ssdt_tables(data); -if (iasl_installed()) { +if (iasl) { test_acpi_asl(data); } -- MST
[Qemu-devel] [PULL v2 19/35] piix4: add acpi pci hotplug support
Add support for acpi pci hotplug using the new infrastructure. PIIX4 legacy interface is maintained as is for machine types 1.7 and older. Signed-off-by: Michael S. Tsirkin m...@redhat.com --- include/hw/i386/pc.h | 5 hw/acpi/piix4.c | 75 +--- 2 files changed, 70 insertions(+), 10 deletions(-) diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h index 7fe2bd1..92eabeb 100644 --- a/include/hw/i386/pc.h +++ b/include/hw/i386/pc.h @@ -265,6 +265,11 @@ int e820_add_entry(uint64_t, uint64_t, uint32_t); .driver = TYPE_USB_DEVICE,\ .property = msos-desc,\ .value= no,\ +},\ +{\ +.driver = PIIX4_PM,\ +.property = acpi-pci-hotplug-with-bridge-support,\ +.value= off,\ } #define PC_COMPAT_1_6 \ diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c index 20353b9..1aa35bc 100644 --- a/hw/acpi/piix4.c +++ b/hw/acpi/piix4.c @@ -30,6 +30,7 @@ #include hw/nvram/fw_cfg.h #include exec/address-spaces.h #include hw/acpi/piix4.h +#include hw/acpi/pcihp.h //#define DEBUG @@ -73,7 +74,6 @@ typedef struct PIIX4PMState { uint32_t io_base; MemoryRegion io_gpe; -MemoryRegion io_pci; MemoryRegion io_cpu; ACPIREGS ar; @@ -88,11 +88,16 @@ typedef struct PIIX4PMState { Notifier machine_ready; Notifier powerdown_notifier; -/* for pci hotplug */ +/* for legacy pci hotplug (compatible with qemu 1.6 and older) */ +MemoryRegion io_pci; struct pci_status pci0_status; uint32_t pci0_hotplug_enable; uint32_t pci0_slot_device_present; +/* for new pci hotplug (with PCI2PCI bridge support) */ +AcpiPciHpState acpi_pci_hotplug; +bool use_acpi_pci_hotplug; + uint8_t disable_s3; uint8_t disable_s4; uint8_t s4_val; @@ -263,6 +268,18 @@ static int acpi_load_old(QEMUFile *f, void *opaque, int version_id) return ret; } +static bool vmstate_test_use_acpi_pci_hotplug(void *opaque, int version_id) +{ +PIIX4PMState *s = opaque; +return s-use_acpi_pci_hotplug; +} + +static bool vmstate_test_no_use_acpi_pci_hotplug(void *opaque, int version_id) +{ +PIIX4PMState *s = opaque; +return !s-use_acpi_pci_hotplug; +} + /* qemu-kvm 1.2 uses version 3 but advertised as 2 * To support incoming qemu-kvm 1.2 migration, change version_id * and minimum_version_id to 2 below (which breaks migration from @@ -285,8 +302,12 @@ static const VMStateDescription vmstate_acpi = { VMSTATE_TIMER(ar.tmr.timer, PIIX4PMState), VMSTATE_INT64(ar.tmr.overflow_time, PIIX4PMState), VMSTATE_STRUCT(ar.gpe, PIIX4PMState, 2, vmstate_gpe, ACPIGPE), -VMSTATE_STRUCT(pci0_status, PIIX4PMState, 2, vmstate_pci_status, - struct pci_status), +VMSTATE_STRUCT_TEST(pci0_status, PIIX4PMState, +vmstate_test_no_use_acpi_pci_hotplug, +2, vmstate_pci_status, +struct pci_status), +VMSTATE_PCI_HOTPLUG(acpi_pci_hotplug, PIIX4PMState, +vmstate_test_use_acpi_pci_hotplug), VMSTATE_END_OF_LIST() } }; @@ -364,7 +385,11 @@ static void piix4_reset(void *opaque) pci_conf[0x5B] = 0x02; } pm_io_space_update(s); -piix4_update_hotplug(s); +if (s-use_acpi_pci_hotplug) { +acpi_pcihp_reset(s-acpi_pci_hotplug); +} else { +piix4_update_hotplug(s); +} } static void piix4_pm_powerdown_req(Notifier *n, void *opaque) @@ -375,6 +400,26 @@ static void piix4_pm_powerdown_req(Notifier *n, void *opaque) acpi_pm1_evt_power_down(s-ar); } +static int piix4_acpi_pci_hotplug(DeviceState *qdev, PCIDevice *dev, + PCIHotplugState state) +{ +PIIX4PMState *s = PIIX4_PM(qdev); +int ret = acpi_pcihp_device_hotplug(s-acpi_pci_hotplug, dev, state); +if (ret 0) { +return ret; +} +s-ar.gpe.sts[0] |= PIIX4_PCI_HOTPLUG_STATUS; + +acpi_update_sci(s-ar, s-irq); +return 0; +} + +static void piix4_update_bus_hotplug(PCIBus *bus, void *opaque) +{ +PIIX4PMState *s = opaque; +pci_bus_hotplug(bus, piix4_acpi_pci_hotplug, DEVICE(s)); +} + static void piix4_pm_machine_ready(Notifier *n, void *opaque) { PIIX4PMState *s = container_of(n, PIIX4PMState, machine_ready); @@ -388,6 +433,10 @@ static void piix4_pm_machine_ready(Notifier *n, void *opaque) pci_conf[0x63] = 0x60; pci_conf[0x67] = (memory_region_present(io_as, 0x3f8) ? 0x08 : 0) | (memory_region_present(io_as, 0x2f8) ? 0x90 : 0); + +if (s-use_acpi_pci_hotplug) { +pci_for_each_bus(d-bus, piix4_update_bus_hotplug, s); +} } static void piix4_pm_add_propeties(PIIX4PMState *s) @@ -509,6 +558,8 @@ static Property piix4_pm_properties[] = { DEFINE_PROP_UINT8(ACPI_PM_PROP_S3_DISABLED, PIIX4PMState, disable_s3, 0),
[Qemu-devel] [PULL v2 22/35] acpi: ich9: add CPU hotplug handling to Q35 machine
From: Igor Mammedov imamm...@redhat.com .. use IO port 0cd8-0xcf7 range for CPU present bitmap Signed-off-by: Igor Mammedov imamm...@redhat.com Reviewed-by: Michael S. Tsirkin m...@redhat.com Signed-off-by: Michael S. Tsirkin m...@redhat.com --- include/hw/acpi/cpu_hotplug_defs.h | 1 + include/hw/acpi/ich9.h | 4 hw/acpi/ich9.c | 14 ++ docs/specs/acpi_cpu_hotplug.txt| 4 +++- 4 files changed, 22 insertions(+), 1 deletion(-) diff --git a/include/hw/acpi/cpu_hotplug_defs.h b/include/hw/acpi/cpu_hotplug_defs.h index c6c4f78..47a35e3 100644 --- a/include/hw/acpi/cpu_hotplug_defs.h +++ b/include/hw/acpi/cpu_hotplug_defs.h @@ -18,5 +18,6 @@ */ #define ACPI_CPU_HOTPLUG_STATUS 4 #define ACPI_GPE_PROC_LEN 32 +#define ICH9_CPU_HOTPLUG_IO_BASE 0x0CD8 #endif diff --git a/include/hw/acpi/ich9.h b/include/hw/acpi/ich9.h index 82fcf9f..104f419 100644 --- a/include/hw/acpi/ich9.h +++ b/include/hw/acpi/ich9.h @@ -22,6 +22,7 @@ #define HW_ACPI_ICH9_H #include hw/acpi/acpi.h +#include hw/acpi/cpu_hotplug.h typedef struct ICH9LPCPMRegs { /* @@ -42,6 +43,9 @@ typedef struct ICH9LPCPMRegs { uint32_t pm_io_base; Notifier powerdown_notifier; + +AcpiCpuHotplug gpe_cpu; +Notifier cpu_added_notifier; } ICH9LPCPMRegs; void ich9_pm_init(PCIDevice *lpc_pci, ICH9LPCPMRegs *pm, diff --git a/hw/acpi/ich9.c b/hw/acpi/ich9.c index 30f0df8..0afac42 100644 --- a/hw/acpi/ich9.c +++ b/hw/acpi/ich9.c @@ -185,6 +185,15 @@ static void pm_powerdown_req(Notifier *n, void *opaque) acpi_pm1_evt_power_down(pm-acpi_regs); } +static void ich9_cpu_added_req(Notifier *n, void *opaque) +{ +ICH9LPCPMRegs *pm = container_of(n, ICH9LPCPMRegs, cpu_added_notifier); + +assert(pm != NULL); +AcpiCpuHotplug_add(pm-acpi_regs.gpe, pm-gpe_cpu, CPU(opaque)); +acpi_update_sci(pm-acpi_regs, pm-irq); +} + void ich9_pm_init(PCIDevice *lpc_pci, ICH9LPCPMRegs *pm, qemu_irq sci_irq) { @@ -210,6 +219,11 @@ void ich9_pm_init(PCIDevice *lpc_pci, ICH9LPCPMRegs *pm, qemu_register_reset(pm_reset, pm); pm-powerdown_notifier.notify = pm_powerdown_req; qemu_register_powerdown_notifier(pm-powerdown_notifier); + +AcpiCpuHotplug_init(pci_address_space_io(lpc_pci), OBJECT(lpc_pci), +pm-gpe_cpu, ICH9_CPU_HOTPLUG_IO_BASE); +pm-cpu_added_notifier.notify = ich9_cpu_added_req; +qemu_register_cpu_added_notifier(pm-cpu_added_notifier); } static void ich9_pm_get_gpe0_blk(Object *obj, Visitor *v, diff --git a/docs/specs/acpi_cpu_hotplug.txt b/docs/specs/acpi_cpu_hotplug.txt index f6f5774..340b751 100644 --- a/docs/specs/acpi_cpu_hotplug.txt +++ b/docs/specs/acpi_cpu_hotplug.txt @@ -10,7 +10,9 @@ ACPI GPE block (IO ports 0xafe0-0xafe3, byte access): Generic ACPI GPE block. Bit 2 (GPE.2) used to notify CPU hot-add/remove event to ACPI BIOS, via SCI interrupt. -CPU present bitmap (IO port 0xaf00-0xaf1f, 1-byte access): +CPU present bitmap for: + ICH9-LPC (IO port 0x0cd8-0xcf7, 1-byte access) + PIIX-PM (IO port 0xaf00-0xaf1f, 1-byte access) --- One bit per CPU. Bit position reflects corresponding CPU APIC ID. Read-only. -- MST
[Qemu-devel] [PULL v2 15/35] acpi unit-test: do not fail on asl mismatch
From: Marcel Apfelbaum marce...@redhat.com The asl comparison will break every time the ACPI tables are updated. This may break the git bisect. Instead of failing print a warning on stderr including the retained asl files, so they can be compared offline. Signed-off-by: Marcel Apfelbaum marce...@redhat.com Reviewed-by: Michael S. Tsirkin m...@redhat.com Signed-off-by: Michael S. Tsirkin m...@redhat.com --- tests/acpi-test.c | 13 +++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/tests/acpi-test.c b/tests/acpi-test.c index 6095d07..31f5359 100644 --- a/tests/acpi-test.c +++ b/tests/acpi-test.c @@ -34,6 +34,7 @@ typedef struct { gchar *asl;/* asl code generated from aml */ gsize asl_len; gchar *asl_file; +bool asl_file_retain; /* do not delete the temp asl */ } QEMU_PACKED AcpiSdtTable; typedef struct { @@ -161,7 +162,7 @@ static void free_test_data(test_data *data) g_free(temp-asl); } if (temp-asl_file) { -if (g_strstr_len(temp-asl_file, -1, asl-)) { +if (!temp-asl_file_retain) { unlink(temp-asl_file); } g_free(temp-asl_file); @@ -532,7 +533,15 @@ static void test_acpi_asl(test_data *data) load_asl(exp_data.tables, exp_sdt); exp_asl = normalize_asl(exp_sdt-asl); -g_assert(!g_strcmp0(asl-str, exp_asl-str)); +if (g_strcmp0(asl-str, exp_asl-str)) { +sdt-asl_file_retain = true; +exp_sdt-asl_file_retain = true; +fprintf(stderr, +acpi-test: Warning! %.4s mismatch. +Orig asl: %s, expected asl %s.\n, +(gchar *)exp_sdt-header.signature, +sdt-asl_file, exp_sdt-asl_file); +} g_string_free(asl, true); g_string_free(exp_asl, true); } -- MST
[Qemu-devel] [PULL v2 17/35] pci: add pci_for_each_bus_depth_first
Useful for ACPI hotplug. Signed-off-by: Michael S. Tsirkin m...@redhat.com --- include/hw/pci/pci.h | 14 ++ hw/pci/pci.c | 28 2 files changed, 42 insertions(+) diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h index 754b82d..5252346 100644 --- a/include/hw/pci/pci.h +++ b/include/hw/pci/pci.h @@ -387,6 +387,20 @@ int pci_bus_num(PCIBus *s); void pci_for_each_device(PCIBus *bus, int bus_num, void (*fn)(PCIBus *bus, PCIDevice *d, void *opaque), void *opaque); +void pci_for_each_bus_depth_first(PCIBus *bus, + void *(*begin)(PCIBus *bus, void *parent_state), + void (*end)(PCIBus *bus, void *state), + void *parent_state); + +/* Use this wrapper when specific scan order is not required. */ +static inline +void pci_for_each_bus(PCIBus *bus, + void (*fn)(PCIBus *bus, void *opaque), + void *opaque) +{ +pci_for_each_bus_depth_first(bus, NULL, fn, opaque); +} + PCIBus *pci_find_primary_bus(void); PCIBus *pci_device_root_bus(const PCIDevice *d); const char *pci_root_bus_path(PCIDevice *dev); diff --git a/hw/pci/pci.c b/hw/pci/pci.c index aa2a395..2aca8a4 100644 --- a/hw/pci/pci.c +++ b/hw/pci/pci.c @@ -1704,6 +1704,34 @@ static PCIBus *pci_find_bus_nr(PCIBus *bus, int bus_num) return NULL; } +void pci_for_each_bus_depth_first(PCIBus *bus, + void *(*begin)(PCIBus *bus, void *parent_state), + void (*end)(PCIBus *bus, void *state), + void *parent_state) +{ +PCIBus *sec; +void *state; + +if (!bus) { +return; +} + +if (begin) { +state = begin(bus, parent_state); +} else { +state = parent_state; +} + +QLIST_FOREACH(sec, bus-child, sibling) { +pci_for_each_bus_depth_first(sec, begin, end, state); +} + +if (end) { +end(bus, state); +} +} + + PCIDevice *pci_find_device(PCIBus *bus, int bus_num, uint8_t devfn) { bus = pci_find_bus_nr(bus, bus_num); -- MST
[Qemu-devel] [PULL v2 20/35] acpi-build: enable hotplug for PCI bridges
This enables support for device hotplug behind pci bridges. Bridge devices themselves need to be pre-configured on qemu command line. Design: - at machine init time, assign bsel property to bridges with hotplug support - dynamically (At ACPI table read) generate ACPI code to handle hotplug events for each bridge with bsel property Note: ACPI doesn't support adding or removing bridges by hotplug. We detect and prevent removal of bridges by hotplug, unless they were added by hotplug previously (and so, are not described by ACPI). Signed-off-by: Michael S. Tsirkin m...@redhat.com --- hw/i386/acpi-build.c | 346 +++-- hw/i386/acpi-dsdt.dsl | 34 +++-- hw/i386/ssdt-pcihp.dsl | 11 +- 3 files changed, 297 insertions(+), 94 deletions(-) diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c index 1d62866..9cd3d0e 100644 --- a/hw/i386/acpi-build.c +++ b/hw/i386/acpi-build.c @@ -40,6 +40,7 @@ /* Supported chipsets: */ #include hw/acpi/piix4.h +#include hw/acpi/pcihp.h #include hw/i386/ich9.h #include hw/pci/pci_bus.h #include hw/pci-host/q35.h @@ -79,6 +80,12 @@ typedef struct AcpiMiscInfo { uint16_t pvpanic_port; } AcpiMiscInfo; +typedef struct AcpiBuildPciBusHotplugState { +GArray *device_table; +GArray *notify_table; +struct AcpiBuildPciBusHotplugState *parent; +} AcpiBuildPciBusHotplugState; + static void acpi_get_dsdt(AcpiMiscInfo *info) { uint16_t *applesmc_sta; @@ -179,38 +186,6 @@ static void acpi_get_pm_info(AcpiPmInfo *pm) NULL); } -static void acpi_get_hotplug_info(AcpiMiscInfo *misc) -{ -int i; -PCIBus *bus = find_i440fx(); - -if (!bus) { -/* Only PIIX supports ACPI hotplug */ -memset(misc-slot_hotplug_enable, 0, sizeof misc-slot_hotplug_enable); -return; -} - -memset(misc-slot_hotplug_enable, 0xff, - DIV_ROUND_UP(PCI_SLOT_MAX, BITS_PER_BYTE)); - -for (i = 0; i ARRAY_SIZE(bus-devices); ++i) { -PCIDeviceClass *pc; -PCIDevice *pdev = bus-devices[i]; - -if (!pdev) { -continue; -} - -pc = PCI_DEVICE_GET_CLASS(pdev); - -if (pc-no_hotplug) { -int slot = PCI_SLOT(i); - -clear_bit(slot, misc-slot_hotplug_enable); -} -} -} - static void acpi_get_misc_info(AcpiMiscInfo *info) { info-has_hpet = hpet_find(); @@ -376,6 +351,12 @@ static void build_package(GArray *package, uint8_t op, unsigned min_bytes) build_prepend_byte(package, op); } +static void build_extop_package(GArray *package, uint8_t op) +{ +build_package(package, op, 1); +build_prepend_byte(package, 0x5B); /* ExtOpPrefix */ +} + static void build_append_value(GArray *table, uint32_t value, int size) { uint8_t prefix; @@ -402,8 +383,44 @@ static void build_append_value(GArray *table, uint32_t value, int size) } } -static void build_append_notify_target(GArray *method, GArray *target_name, - uint32_t value, int size) +static void build_append_int(GArray *table, uint32_t value) +{ +if (value == 0x00) { +build_append_byte(table, 0x00); /* ZeroOp */ +} else if (value == 0x01) { +build_append_byte(table, 0x01); /* OneOp */ +} else if (value = 0xFF) { +build_append_value(table, value, 1); +} else if (value = 0xF) { +build_append_value(table, value, 2); +} else { +build_append_value(table, value, 4); +} +} + +static GArray *build_alloc_method(const char *name, uint8_t arg_count) +{ +GArray *method = build_alloc_array(); + +build_append_nameseg(method, %s, name); +build_append_byte(method, arg_count); /* MethodFlags: ArgCount */ + +return method; +} + +static void build_append_and_cleanup_method(GArray *device, GArray *method) +{ +uint8_t op = 0x14; /* MethodOp */ + +build_package(method, op, 0); + +build_append_array(device, method); +build_free_array(method); +} + +static void build_append_notify_target_ifequal(GArray *method, + GArray *target_name, + uint32_t value, int size) { GArray *notify = build_alloc_array(); uint8_t op = 0xA0; /* IfOp */ @@ -423,6 +440,7 @@ static void build_append_notify_target(GArray *method, GArray *target_name, build_free_array(notify); } +/* End here */ #define ACPI_PORT_SMI_CMD 0x00b2 /* TODO: this is APM_CNT_IOPORT */ static inline void *acpi_data_push(GArray *table_data, unsigned size) @@ -632,44 +650,236 @@ static inline char acpi_get_hex(uint32_t val) #include hw/i386/ssdt-pcihp.hex static void -build_append_notify(GArray *device, const char *name, -const char *format, int skip, int count) +build_append_notify_method(GArray *device, const char *name, + const char
[Qemu-devel] [PULL v2 23/35] pc: set PRST base in DSDT depending on chipset
From: Igor Mammedov imamm...@redhat.com Signed-off-by: Igor Mammedov imamm...@redhat.com Reviewed-by: Michael S. Tsirkin m...@redhat.com Signed-off-by: Michael S. Tsirkin m...@redhat.com --- hw/i386/acpi-dsdt-cpu-hotplug.dsl | 2 +- hw/i386/acpi-dsdt.dsl | 1 + hw/i386/q35-acpi-dsdt.dsl | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/hw/i386/acpi-dsdt-cpu-hotplug.dsl b/hw/i386/acpi-dsdt-cpu-hotplug.dsl index 995b415..1dfbb4f 100644 --- a/hw/i386/acpi-dsdt-cpu-hotplug.dsl +++ b/hw/i386/acpi-dsdt-cpu-hotplug.dsl @@ -52,7 +52,7 @@ Scope(\_SB) { Sleep(200) } -OperationRegion(PRST, SystemIO, 0xaf00, 32) +OperationRegion(PRST, SystemIO, CPU_STATUS_BASE, 32) Field(PRST, ByteAcc, NoLock, Preserve) { PRS, 256 } diff --git a/hw/i386/acpi-dsdt.dsl b/hw/i386/acpi-dsdt.dsl index 6d76f30..3dc4789 100644 --- a/hw/i386/acpi-dsdt.dsl +++ b/hw/i386/acpi-dsdt.dsl @@ -290,6 +290,7 @@ DefinitionBlock ( } } +#define CPU_STATUS_BASE 0xaf00 #include acpi-dsdt-cpu-hotplug.dsl diff --git a/hw/i386/q35-acpi-dsdt.dsl b/hw/i386/q35-acpi-dsdt.dsl index ee38fd6..9a43947 100644 --- a/hw/i386/q35-acpi-dsdt.dsl +++ b/hw/i386/q35-acpi-dsdt.dsl @@ -405,6 +405,7 @@ DefinitionBlock ( define_gsi_link(GSIH, 0, 0x17) } +#define CPU_STATUS_BASE 0x0CD8 #include acpi-dsdt-cpu-hotplug.dsl -- MST
[Qemu-devel] [PULL v2 18/35] pcihp: generalization of piix4 acpi
Add ACPI based PCI hotplug library with bridge hotplug support. Design - each bus gets assigned bsel property. - ACPI code writes this number to a new BNUM register, then uses existing UP/DOWN registers to probe slot status; to eject, write number to BNUM register, then slot into existing EJ. The interface is actually backwards-compatible with existing PIIX4 ACPI (though not migration compatible). This is split out from PIIX4 codebase so we can reuse it for Q35 as well. Signed-off-by: Michael S. Tsirkin m...@redhat.com --- include/hw/acpi/pcihp.h | 72 +++ hw/acpi/pcihp.c | 316 hw/acpi/Makefile.objs | 3 +- 3 files changed, 389 insertions(+), 2 deletions(-) create mode 100644 include/hw/acpi/pcihp.h create mode 100644 hw/acpi/pcihp.c diff --git a/include/hw/acpi/pcihp.h b/include/hw/acpi/pcihp.h new file mode 100644 index 000..6230e60 --- /dev/null +++ b/include/hw/acpi/pcihp.h @@ -0,0 +1,72 @@ +/* + * QEMU-ACPI BIOS PCI hotplug interface + * + * QEMU supports PCI hotplug via ACPI. This module + * implements the interface between QEMU and the ACPI BIOS. + * Interface specification - see docs/specs/acpi_pci_hotplug.txt + * + * Copyright (c) 2013, Red Hat Inc, Michael S. Tsirkin (m...@redhat.com) + * Copyright (c) 2006 Fabrice Bellard + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2 as published by the Free Software Foundation. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see http://www.gnu.org/licenses/ + * + * Contributions after 2012-01-13 are licensed under the terms of the + * GNU GPL, version 2 or (at your option) any later version. + */ + +#ifndef HW_ACPI_PCIHP_H +#define HW_ACPI_PCIHP_H + +#include inttypes.h +#include qemu/typedefs.h +#include hw/pci/pci.h /* for PCIHotplugState */ + +typedef struct AcpiPciHpPciStatus { +uint32_t up; /* deprecated, maintained for migration compatibility */ +uint32_t down; +uint32_t hotplug_enable; +uint32_t device_present; +} AcpiPciHpPciStatus; + +#define ACPI_PCIHP_PROP_BSEL acpi-pcihp-bsel +#define ACPI_PCIHP_MAX_HOTPLUG_BUS 256 + +typedef struct AcpiPciHpState { +AcpiPciHpPciStatus acpi_pcihp_pci_status[ACPI_PCIHP_MAX_HOTPLUG_BUS]; +uint32_t hotplug_select; +PCIBus *root; +MemoryRegion io; +} AcpiPciHpState; + +void acpi_pcihp_init(AcpiPciHpState *, PCIBus *root, + MemoryRegion *address_space_io); + +/* Invoke on device hotplug */ +int acpi_pcihp_device_hotplug(AcpiPciHpState *, PCIDevice *, + PCIHotplugState state); + +/* Called on reset */ +void acpi_pcihp_reset(AcpiPciHpState *s); + +extern const VMStateDescription vmstate_acpi_pcihp_pci_status; + +#define VMSTATE_PCI_HOTPLUG(pcihp, state, test_pcihp) \ +VMSTATE_UINT32_TEST(pcihp.hotplug_select, state, \ +test_pcihp), \ +VMSTATE_STRUCT_ARRAY_TEST(pcihp.acpi_pcihp_pci_status, state, \ + ACPI_PCIHP_MAX_HOTPLUG_BUS, \ + test_pcihp, 1, \ + vmstate_acpi_pcihp_pci_status, \ + AcpiPciHpPciStatus) + +#endif diff --git a/hw/acpi/pcihp.c b/hw/acpi/pcihp.c new file mode 100644 index 000..3fa3d7c --- /dev/null +++ b/hw/acpi/pcihp.c @@ -0,0 +1,316 @@ +/* + * QEMU-ACPI BIOS PCI hotplug interface + * + * QEMU supports PCI hotplug via ACPI. This module + * implements the interface between QEMU and the ACPI BIOS. + * Interface specification - see docs/specs/acpi_pci_hotplug.txt + * + * Copyright (c) 2013, Red Hat Inc, Michael S. Tsirkin (m...@redhat.com) + * Copyright (c) 2006 Fabrice Bellard + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2 as published by the Free Software Foundation. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see http://www.gnu.org/licenses/ + * + * Contributions after 2012-01-13 are licensed under the terms of the + * GNU GPL, version 2 or (at your option) any later version. + */ + +#include hw/acpi/pcihp.h + +#include hw/hw.h +#include hw/i386/pc.h +#include hw/pci/pci.h
[Qemu-devel] [PULL v2 28/35] pc: ACPI: update acpi-dsdt.hex.generated q35-acpi-dsdt.hex.generated
From: Igor Mammedov imamm...@redhat.com Signed-off-by: Igor Mammedov imamm...@redhat.com Reviewed-by: Michael S. Tsirkin m...@redhat.com Signed-off-by: Michael S. Tsirkin m...@redhat.com --- hw/i386/acpi-dsdt.hex.generated | 217 +--- hw/i386/q35-acpi-dsdt.hex.generated | 74 ++-- hw/i386/ssdt-pcihp.hex.generated| 20 ++-- hw/i386/ssdt-proc.hex.generated | 6 +- 4 files changed, 225 insertions(+), 92 deletions(-) diff --git a/hw/i386/acpi-dsdt.hex.generated b/hw/i386/acpi-dsdt.hex.generated index f8bd4ea..1e58801 100644 --- a/hw/i386/acpi-dsdt.hex.generated +++ b/hw/i386/acpi-dsdt.hex.generated @@ -3,12 +3,12 @@ static unsigned char AcpiDsdtAmlCode[] = { 0x53, 0x44, 0x54, -0x37, +0x87, 0x11, 0x0, 0x0, 0x1, -0xd8, +0xb8, 0x42, 0x58, 0x50, @@ -860,8 +860,8 @@ static unsigned char AcpiDsdtAmlCode[] = { 0x4e, 0x1, 0x10, -0x4c, -0x1b, +0x4b, +0x1e, 0x2f, 0x3, 0x5f, @@ -879,6 +879,53 @@ static unsigned char AcpiDsdtAmlCode[] = { 0x5b, 0x82, 0x2d, +0x53, +0x4d, +0x43, +0x5f, +0x8, +0x5f, +0x48, +0x49, +0x44, +0xc, +0x6, +0x10, +0x0, +0x1, +0x8, +0x5f, +0x53, +0x54, +0x41, +0xb, +0x0, +0xff, +0x8, +0x5f, +0x43, +0x52, +0x53, +0x11, +0x10, +0xa, +0xd, +0x47, +0x1, +0x0, +0x3, +0x0, +0x3, +0x1, +0x20, +0x22, +0x40, +0x0, +0x79, +0x0, +0x5b, +0x82, +0x2d, 0x52, 0x54, 0x43, @@ -1305,7 +1352,7 @@ static unsigned char AcpiDsdtAmlCode[] = { 0x79, 0x0, 0x10, -0x4b, +0x48, 0x8, 0x2e, 0x5f, @@ -1371,79 +1418,76 @@ static unsigned char AcpiDsdtAmlCode[] = { 0x45, 0x4a, 0x20, +0x5b, +0x80, +0x42, +0x4e, +0x4d, +0x52, +0x1, +0xb, +0x10, +0xae, +0xa, +0x4, +0x5b, +0x81, +0xb, +0x42, +0x4e, +0x4d, +0x52, +0x43, +0x42, +0x4e, +0x55, +0x4d, +0x20, +0x5b, +0x1, +0x42, +0x4c, +0x43, +0x4b, +0x0, 0x14, -0x11, +0x25, 0x50, 0x43, 0x45, 0x4a, -0x1, +0x2, +0x5b, +0x23, +0x42, +0x4c, +0x43, +0x4b, +0xff, +0xff, 0x70, -0x79, -0x1, 0x68, -0x0, 0x42, -0x30, -0x45, -0x4a, -0xa4, -0x0, -0x14, -0x36, -0x50, -0x43, 0x4e, -0x46, -0x0, -0x70, -0x0, -0x60, -0xa2, -0x2c, -0x95, -0x60, -0xa, -0x1f, -0x75, -0x60, -0xa0, -0x11, -0x7b, -0x50, -0x43, -0x49, 0x55, +0x4d, +0x70, 0x79, 0x1, -0x60, +0x69, 0x0, -0x0, -0x50, -0x43, -0x4e, -0x54, -0x60, -0x1, -0xa0, -0x12, -0x7b, -0x50, +0x42, +0x30, +0x45, +0x4a, +0x5b, +0x27, +0x42, +0x4c, 0x43, -0x49, -0x44, -0x79, -0x1, -0x60, -0x0, +0x4b, +0xa4, 0x0, -0x50, -0x43, -0x4e, -0x54, -0x60, -0xa, -0x3, 0x10, 0x4a, 0xa0, @@ -4248,8 +4292,8 @@ static unsigned char AcpiDsdtAmlCode[] = { 0x75, 0x60, 0x10, -0x4e, -0x9, +0x42, +0xc, 0x5f, 0x47, 0x50, @@ -4277,12 +4321,31 @@ static unsigned char AcpiDsdtAmlCode[] = { 0x30, 0x0, 0x14, -0x15, +0x39, 0x5f, 0x45, 0x30, 0x31, 0x0, +0x5b, +0x23, +0x5c, +0x2f, +0x3, +0x5f, +0x53, +0x42, +0x5f, +0x50, +0x43, +0x49, +0x30, +0x42, +0x4c, +0x43, +0x4b, +0xff, +0xff, 0x5c, 0x2f, 0x3, @@ -4297,7 +4360,24 @@ static unsigned char AcpiDsdtAmlCode[] = { 0x50, 0x43, 0x4e, -0x46, +0x54, +0x5b, +0x27, +0x5c, +0x2f, +0x3, +0x5f, +0x53, +0x42, +0x5f, +0x50, +0x43, +0x49, +0x30, +0x42, +0x4c, +0x43, +0x4b, 0x14, 0x10, 0x5f, @@ -4407,3 +4487,6 @@ static unsigned char AcpiDsdtAmlCode[] = { 0x46, 0x0 }; +static unsigned short piix_dsdt_applesmc_sta[] = { +0x384 +}; diff --git a/hw/i386/q35-acpi-dsdt.hex.generated b/hw/i386/q35-acpi-dsdt.hex.generated index 111ad3e..6d885a9 100644 --- a/hw/i386/q35-acpi-dsdt.hex.generated +++ b/hw/i386/q35-acpi-dsdt.hex.generated @@ -3,12 +3,12 @@ static unsigned char Q35AcpiDsdtAmlCode[] = { 0x53, 0x44, 0x54, -0xb0, +0xdf, 0x1c, 0x0, 0x0, 0x1, -0xfe, +0xff, 0x42, 0x58, 0x50, @@ -1033,8 +1033,8 @@ static unsigned char Q35AcpiDsdtAmlCode[] = { 0x4e, 0x1, 0x10, -0x4c, -0x1b, +0x4b, +0x1e, 0x2f, 0x3, 0x5f, @@ -1052,6 +1052,53 @@ static unsigned char Q35AcpiDsdtAmlCode[] = { 0x5b, 0x82, 0x2d, +0x53, +0x4d, +0x43, +0x5f, +0x8, +0x5f, +0x48, +0x49, +0x44, +0xc, +0x6, +0x10, +0x0, +0x1, +0x8, +0x5f, +0x53, +0x54, +0x41, +0xb, +0x0, +0xff, +0x8, +0x5f, +0x43, +0x52, +0x53, +0x11, +0x10, +0xa, +0xd, +0x47, +0x1, +0x0, +0x3, +0x0, +0x3, +0x1, +0x20, +0x22, +0x40, +0x0, +0x79, +0x0, +0x5b, +0x82, +0x2d, 0x52, 0x54, 0x43, @@ -7229,12 +7276,19 @@ static unsigned char Q35AcpiDsdtAmlCode[] = { 0x30, 0x0, 0x14, -0x10, +0x6, 0x5f, 0x4c, 0x30, 0x31, 0x0, +0x14, +0x10, +0x5f, +0x45, +0x30, +0x32, +0x0, 0x5c, 0x2e, 0x5f, @@ -7250,13 +7304,6 @@ static unsigned char Q35AcpiDsdtAmlCode[] = { 0x5f, 0x4c, 0x30, -0x32, -0x0, -0x14, -0x6, -0x5f, -0x4c, -0x30, 0x33, 0x0, 0x14, @@ -7344,3 +7391,6 @@ static unsigned char Q35AcpiDsdtAmlCode[] = { 0x46, 0x0 }; +static unsigned short q35_dsdt_applesmc_sta[] = { +0x431 +}; diff --git a/hw/i386/ssdt-pcihp.hex.generated b/hw/i386/ssdt-pcihp.hex.generated index b3c2cd5..610a631 100644 --- a/hw/i386/ssdt-pcihp.hex.generated +++ b/hw/i386/ssdt-pcihp.hex.generated @@ -5,19 +5,19 @@ static unsigned char ssdt_pcihp_adr[] = { 0x44 }; static unsigned char ssdt_pcihp_end[] = {
[Qemu-devel] [PULL v2 24/35] pc: PIIX DSDT: exclude CPU/PCI hotplug GPE0 IO range from PCI bus resources
From: Igor Mammedov imamm...@redhat.com .. so that they might not be used by PCI devices. Note: Resort to concatenating templates with preprocessor help, because 1.0b spec isn't supporting ConcatenateResTemplate, as result Windows XP fails to execute PCI0._CRS method if ConcatenateResTemplate() is used. Signed-off-by: Igor Mammedov imamm...@redhat.com Reviewed-by: Michael S. Tsirkin m...@redhat.com Signed-off-by: Michael S. Tsirkin m...@redhat.com --- hw/i386/acpi-dsdt-pci-crs.dsl | 8 +--- hw/i386/acpi-dsdt.dsl | 32 hw/i386/q35-acpi-dsdt.dsl | 8 3 files changed, 41 insertions(+), 7 deletions(-) diff --git a/hw/i386/acpi-dsdt-pci-crs.dsl b/hw/i386/acpi-dsdt-pci-crs.dsl index b375a19..8b631d1 100644 --- a/hw/i386/acpi-dsdt-pci-crs.dsl +++ b/hw/i386/acpi-dsdt-pci-crs.dsl @@ -37,13 +37,7 @@ Scope(\_SB.PCI0) { 0x, // Address Translation Offset 0x0CF8, // Address Length ,, , TypeStatic) -WordIO(ResourceProducer, MinFixed, MaxFixed, PosDecode, EntireRange, -0x, // Address Space Granularity -0x0D00, // Address Range Minimum -0x, // Address Range Maximum -0x, // Address Translation Offset -0xF300, // Address Length -,, , TypeStatic) +BOARD_SPECIFIC_PCI_RESOURSES DWordMemory(ResourceProducer, PosDecode, MinFixed, MaxFixed, Cacheable, ReadWrite, 0x, // Address Space Granularity 0x000A, // Address Range Minimum diff --git a/hw/i386/acpi-dsdt.dsl b/hw/i386/acpi-dsdt.dsl index 3dc4789..f501c8d 100644 --- a/hw/i386/acpi-dsdt.dsl +++ b/hw/i386/acpi-dsdt.dsl @@ -35,6 +35,38 @@ DefinitionBlock ( / * PCI Bus definition / +#define BOARD_SPECIFIC_PCI_RESOURSES \ + WordIO(ResourceProducer, MinFixed, MaxFixed, PosDecode, EntireRange, \ + 0x, \ + 0x0D00, \ + 0xADFF, \ + 0x, \ + 0xA100, \ + ,, , TypeStatic) \ + /* 0xae00-0xae0e hole for PCI hotplug, hw/acpi/piix4.c:PCI_HOTPLUG_ADDR */ \ + WordIO(ResourceProducer, MinFixed, MaxFixed, PosDecode, EntireRange, \ + 0x, \ + 0xAE0F, \ + 0xAEFF, \ + 0x, \ + 0x00F1, \ + ,, , TypeStatic) \ + /* 0xaf00-0xaf1f hole for CPU hotplug, hw/acpi/piix4.c:PIIX4_PROC_BASE */ \ + WordIO(ResourceProducer, MinFixed, MaxFixed, PosDecode, EntireRange, \ + 0x, \ + 0xAF20, \ + 0xAFDF, \ + 0x, \ + 0x00C0, \ + ,, , TypeStatic) \ + /* 0xafe0-0xafe3 hole for ACPI.GPE0, hw/acpi/piix4.c:GPE_BASE */ \ + WordIO(ResourceProducer, MinFixed, MaxFixed, PosDecode, EntireRange, \ + 0x, \ + 0xAFE4, \ + 0x, \ + 0x, \ + 0x501C, \ + ,, , TypeStatic) Scope(\_SB) { Device(PCI0) { diff --git a/hw/i386/q35-acpi-dsdt.dsl b/hw/i386/q35-acpi-dsdt.dsl index 9a43947..f3e5921 100644 --- a/hw/i386/q35-acpi-dsdt.dsl +++ b/hw/i386/q35-acpi-dsdt.dsl @@ -48,6 +48,14 @@ DefinitionBlock ( / * PCI Bus definition / +#define BOARD_SPECIFIC_PCI_RESOURSES \ + WordIO(ResourceProducer, MinFixed, MaxFixed, PosDecode, EntireRange, \ + 0x, \ + 0x0D00, \ + 0x, \ + 0x, \ + 0xF300, \ + ,, , TypeStatic) Scope(\_SB) { Device(PCI0) { -- MST
[Qemu-devel] [PULL v2 27/35] pc: ACPI: unify source of CPU hotplug IO base/len
From: Igor Mammedov imamm...@redhat.com use C headers defines as source of IO base/len for respective values in ASL code. Signed-off-by: Igor Mammedov imamm...@redhat.com Reviewed-by: Michael S. Tsirkin m...@redhat.com Signed-off-by: Michael S. Tsirkin m...@redhat.com --- include/hw/acpi/cpu_hotplug_defs.h | 1 + hw/acpi/piix4.c| 5 ++--- hw/i386/Makefile.objs | 2 +- hw/i386/acpi-dsdt-cpu-hotplug.dsl | 2 +- hw/i386/acpi-dsdt.dsl | 3 ++- hw/i386/q35-acpi-dsdt.dsl | 3 ++- 6 files changed, 9 insertions(+), 7 deletions(-) diff --git a/include/hw/acpi/cpu_hotplug_defs.h b/include/hw/acpi/cpu_hotplug_defs.h index 47a35e3..2725b50 100644 --- a/include/hw/acpi/cpu_hotplug_defs.h +++ b/include/hw/acpi/cpu_hotplug_defs.h @@ -19,5 +19,6 @@ #define ACPI_CPU_HOTPLUG_STATUS 4 #define ACPI_GPE_PROC_LEN 32 #define ICH9_CPU_HOTPLUG_IO_BASE 0x0CD8 +#define PIIX4_CPU_HOTPLUG_IO_BASE 0xaf00 #endif diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c index 12f8dde..5d55a3c 100644 --- a/hw/acpi/piix4.c +++ b/hw/acpi/piix4.c @@ -51,8 +51,6 @@ #define PCI_EJ_BASE 0xae08 #define PCI_RMV_BASE 0xae0c -#define PIIX4_PROC_BASE 0xaf00 - #define PIIX4_PCI_HOTPLUG_STATUS 2 struct pci_status { @@ -706,7 +704,8 @@ static void piix4_acpi_system_hot_add_init(MemoryRegion *parent, pci_bus_hotplug(bus, piix4_device_hotplug, DEVICE(s)); } -AcpiCpuHotplug_init(parent, OBJECT(s), s-gpe_cpu, PIIX4_PROC_BASE); +AcpiCpuHotplug_init(parent, OBJECT(s), s-gpe_cpu, +PIIX4_CPU_HOTPLUG_IO_BASE); s-cpu_added_notifier.notify = piix4_cpu_added_req; qemu_register_cpu_added_notifier(s-cpu_added_notifier); } diff --git a/hw/i386/Makefile.objs b/hw/i386/Makefile.objs index d58a103..3df1612 100644 --- a/hw/i386/Makefile.objs +++ b/hw/i386/Makefile.objs @@ -17,7 +17,7 @@ iasl-option=$(shell if test -z `$(1) $(2) 21 /dev/null` \ ifdef IASL #IASL Present. Generate hex files from .dsl hw/i386/%.hex: $(SRC_PATH)/hw/i386/%.dsl $(SRC_PATH)/scripts/acpi_extract_preprocess.py $(SRC_PATH)/scripts/acpi_extract.py - $(call quiet-command, cpp -P $(QEMU_DGFLAGS) $ -o $*.dsl.i.orig, CPP $(TARGET_DIR)$*.dsl.i.orig) + $(call quiet-command, cpp -P $(QEMU_DGFLAGS) $(QEMU_INCLUDES) $ -o $*.dsl.i.orig, CPP $(TARGET_DIR)$*.dsl.i.orig) $(call quiet-command, $(PYTHON) $(SRC_PATH)/scripts/acpi_extract_preprocess.py $*.dsl.i.orig $*.dsl.i, ACPI_PREPROCESS $(TARGET_DIR)$*.dsl.i) $(call quiet-command, $(IASL) $(call iasl-option,$(IASL),-Pn,) -vs -l -tc -p $* $*.dsl.i $(if $(V), , /dev/null) 21 , IASL $(TARGET_DIR)$*.dsl.i) $(call quiet-command, $(PYTHON) $(SRC_PATH)/scripts/acpi_extract.py $*.lst $*.off, ACPI_EXTRACT $(TARGET_DIR)$*.off) diff --git a/hw/i386/acpi-dsdt-cpu-hotplug.dsl b/hw/i386/acpi-dsdt-cpu-hotplug.dsl index f91eafd..dee4843 100644 --- a/hw/i386/acpi-dsdt-cpu-hotplug.dsl +++ b/hw/i386/acpi-dsdt-cpu-hotplug.dsl @@ -53,7 +53,7 @@ Scope(\_SB) { Sleep(200) } -#define CPU_STATUS_LEN 32 +#define CPU_STATUS_LEN ACPI_GPE_PROC_LEN OperationRegion(PRST, SystemIO, CPU_STATUS_BASE, CPU_STATUS_LEN) Field(PRST, ByteAcc, NoLock, Preserve) { PRS, 256 diff --git a/hw/i386/acpi-dsdt.dsl b/hw/i386/acpi-dsdt.dsl index d89dcda..b23d5e0 100644 --- a/hw/i386/acpi-dsdt.dsl +++ b/hw/i386/acpi-dsdt.dsl @@ -329,7 +329,8 @@ DefinitionBlock ( } } -#define CPU_STATUS_BASE 0xaf00 +#include hw/acpi/cpu_hotplug_defs.h +#define CPU_STATUS_BASE PIIX4_CPU_HOTPLUG_IO_BASE #include acpi-dsdt-cpu-hotplug.dsl diff --git a/hw/i386/q35-acpi-dsdt.dsl b/hw/i386/q35-acpi-dsdt.dsl index 9e070ee..d618e9e 100644 --- a/hw/i386/q35-acpi-dsdt.dsl +++ b/hw/i386/q35-acpi-dsdt.dsl @@ -421,7 +421,8 @@ DefinitionBlock ( define_gsi_link(GSIH, 0, 0x17) } -#define CPU_STATUS_BASE 0x0CD8 +#include hw/acpi/cpu_hotplug_defs.h +#define CPU_STATUS_BASE ICH9_CPU_HOTPLUG_IO_BASE #include acpi-dsdt-cpu-hotplug.dsl -- MST
[Qemu-devel] [PULL v2 30/35] hw/pci: fix error flow in pci multifunction init
From: Marcel Apfelbaum marce...@redhat.com Scenario: - There is a non multifunction pci device A on 00:0X.0. - Hot-plug another multifunction pci device B at 00:0X.1. - The operation will fail of course. - Try to hot-plug the B device 2-3 more times, qemu will crash. Reason: The error flow leaves the B's address space into global address spaces list, but the device object is freed. Fixed that. Signed-off-by: Marcel Apfelbaum marce...@redhat.com Reviewed-by: Michael S. Tsirkin m...@redhat.com Signed-off-by: Michael S. Tsirkin m...@redhat.com --- hw/pci/pci.c | 20 ++-- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/hw/pci/pci.c b/hw/pci/pci.c index 2aca8a4..1221f32 100644 --- a/hw/pci/pci.c +++ b/hw/pci/pci.c @@ -793,6 +793,15 @@ static void pci_config_free(PCIDevice *pci_dev) g_free(pci_dev-used); } +static void do_pci_unregister_device(PCIDevice *pci_dev) +{ +pci_dev-bus-devices[pci_dev-devfn] = NULL; +pci_config_free(pci_dev); + +address_space_destroy(pci_dev-bus_master_as); +memory_region_destroy(pci_dev-bus_master_enable_region); +} + /* -1 for devfn means auto assign */ static PCIDevice *do_pci_register_device(PCIDevice *pci_dev, PCIBus *bus, const char *name, int devfn) @@ -858,7 +867,7 @@ static PCIDevice *do_pci_register_device(PCIDevice *pci_dev, PCIBus *bus, pci_init_mask_bridge(pci_dev); } if (pci_init_multifunction(bus, pci_dev)) { -pci_config_free(pci_dev); +do_pci_unregister_device(pci_dev); return NULL; } @@ -873,15 +882,6 @@ static PCIDevice *do_pci_register_device(PCIDevice *pci_dev, PCIBus *bus, return pci_dev; } -static void do_pci_unregister_device(PCIDevice *pci_dev) -{ -pci_dev-bus-devices[pci_dev-devfn] = NULL; -pci_config_free(pci_dev); - -address_space_destroy(pci_dev-bus_master_as); -memory_region_destroy(pci_dev-bus_master_enable_region); -} - static void pci_unregister_io_regions(PCIDevice *pci_dev) { PCIIORegion *r; -- MST
[Qemu-devel] [PULL v2 31/35] pc: Save size of RAM below 4GB
From: Eduardo Habkost ehabk...@redhat.com The ram_below_4g value will be useful in other places, such as the ACPI table code, and other code that currently requires passing below_4g_mem_size around in function arguments. Signed-off-by: Eduardo Habkost ehabk...@redhat.com Reviewed-by: Michael S. Tsirkin m...@redhat.com Signed-off-by: Michael S. Tsirkin m...@redhat.com --- include/hw/i386/pc.h | 2 +- hw/i386/pc.c | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h index 92eabeb..3e1e81b 100644 --- a/include/hw/i386/pc.h +++ b/include/hw/i386/pc.h @@ -35,7 +35,7 @@ typedef struct PcPciInfo { struct PcGuestInfo { bool has_pci_info; bool isapc_ram_fw; -hwaddr ram_size; +hwaddr ram_size, ram_size_below_4g; unsigned apic_id_limit; bool apic_xrupt_override; uint64_t numa_nodes; diff --git a/hw/i386/pc.c b/hw/i386/pc.c index 6f0be37..348b15f 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -1072,6 +1072,7 @@ PcGuestInfo *pc_guest_info_init(ram_addr_t below_4g_mem_size, PcGuestInfo *guest_info = guest_info_state-info; int i, j; +guest_info-ram_size_below_4g = below_4g_mem_size; guest_info-ram_size = below_4g_mem_size + above_4g_mem_size; guest_info-apic_id_limit = pc_apic_id_limit(max_cpus); guest_info-apic_xrupt_override = kvm_allows_irq0_override(); -- MST
[Qemu-devel] [PULL v2 25/35] pc: Q35 DSDT: exclude CPU hotplug IO range from PCI bus resources
From: Igor Mammedov imamm...@redhat.com ... for range defined at hw/acpi/ich9.c:ICH9_PROC_BASE Signed-off-by: Igor Mammedov imamm...@redhat.com Reviewed-by: Michael S. Tsirkin m...@redhat.com Signed-off-by: Michael S. Tsirkin m...@redhat.com --- hw/i386/acpi-dsdt-pci-crs.dsl | 7 --- hw/i386/acpi-dsdt.dsl | 7 +++ hw/i386/q35-acpi-dsdt.dsl | 8 3 files changed, 15 insertions(+), 7 deletions(-) diff --git a/hw/i386/acpi-dsdt-pci-crs.dsl b/hw/i386/acpi-dsdt-pci-crs.dsl index 8b631d1..4648e90 100644 --- a/hw/i386/acpi-dsdt-pci-crs.dsl +++ b/hw/i386/acpi-dsdt-pci-crs.dsl @@ -30,13 +30,6 @@ Scope(\_SB.PCI0) { 0x01, // Address Alignment 0x08, // Address Length ) -WordIO(ResourceProducer, MinFixed, MaxFixed, PosDecode, EntireRange, -0x, // Address Space Granularity -0x, // Address Range Minimum -0x0CF7, // Address Range Maximum -0x, // Address Translation Offset -0x0CF8, // Address Length -,, , TypeStatic) BOARD_SPECIFIC_PCI_RESOURSES DWordMemory(ResourceProducer, PosDecode, MinFixed, MaxFixed, Cacheable, ReadWrite, 0x, // Address Space Granularity diff --git a/hw/i386/acpi-dsdt.dsl b/hw/i386/acpi-dsdt.dsl index f501c8d..d89dcda 100644 --- a/hw/i386/acpi-dsdt.dsl +++ b/hw/i386/acpi-dsdt.dsl @@ -38,6 +38,13 @@ DefinitionBlock ( #define BOARD_SPECIFIC_PCI_RESOURSES \ WordIO(ResourceProducer, MinFixed, MaxFixed, PosDecode, EntireRange, \ 0x, \ + 0x, \ + 0x0CF7, \ + 0x, \ + 0x0CF8, \ + ,, , TypeStatic) \ + WordIO(ResourceProducer, MinFixed, MaxFixed, PosDecode, EntireRange, \ + 0x, \ 0x0D00, \ 0xADFF, \ 0x, \ diff --git a/hw/i386/q35-acpi-dsdt.dsl b/hw/i386/q35-acpi-dsdt.dsl index f3e5921..9e070ee 100644 --- a/hw/i386/q35-acpi-dsdt.dsl +++ b/hw/i386/q35-acpi-dsdt.dsl @@ -51,6 +51,14 @@ DefinitionBlock ( #define BOARD_SPECIFIC_PCI_RESOURSES \ WordIO(ResourceProducer, MinFixed, MaxFixed, PosDecode, EntireRange, \ 0x, \ + 0x, \ + 0x0CD7, \ + 0x, \ + 0x0CD8, \ + ,, , TypeStatic) \ + /* 0xcd8-0xcf7 hole for CPU hotplug, hw/acpi/ich9.c:ICH9_PROC_BASE */ \ + WordIO(ResourceProducer, MinFixed, MaxFixed, PosDecode, EntireRange, \ + 0x, \ 0x0D00, \ 0x, \ 0x, \ -- MST
[Qemu-devel] [PULL v2 35/35] MAINTAINERS: add self as virtio co-maintainer
This will help make sure I get Cc'd on patches. Signed-off-by: Michael S. Tsirkin m...@redhat.com --- MAINTAINERS | 1 + 1 file changed, 1 insertion(+) diff --git a/MAINTAINERS b/MAINTAINERS index fb53242..adc5973 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -610,6 +610,7 @@ F: hw/*/*vhost* virtio M: Anthony Liguori aligu...@amazon.com +M: Michael S. Tsirkin m...@redhat.com S: Supported F: hw/*/virtio* -- MST
[Qemu-devel] [PULL v2 33/35] q35: gigabyte alignment for ram
From: Gerd Hoffmann kra...@redhat.com Map 2G (q35) of memory below 4G, so the RAM pieces are nicely aligned to gigabyte borders. Keep old memory layout for (a) old machine types and (b) in case all memory fits below 4G and thus we don't have to split RAM into pieces in the first place. The later makes sure this change doesn't take away memory from 32bit guests. Signed-off-by: Gerd Hoffmann kra...@redhat.com Signed-off-by: Michael S. Tsirkin m...@redhat.com --- hw/i386/pc_q35.c | 7 +-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c index 07f38ff..7104645 100644 --- a/hw/i386/pc_q35.c +++ b/hw/i386/pc_q35.c @@ -51,6 +51,7 @@ static bool has_pci_info; static bool has_acpi_build = true; static bool smbios_type1_defaults = true; +static bool gigabyte_align = true; /* PC hardware initialisation */ static void pc_q35_init(QEMUMachineInitArgs *args) @@ -93,8 +94,9 @@ static void pc_q35_init(QEMUMachineInitArgs *args) kvmclock_create(); if (args-ram_size = 0xb000) { -above_4g_mem_size = args-ram_size - 0xb000; -below_4g_mem_size = 0xb000; +ram_addr_t lowmem = gigabyte_align ? 0x8000 : 0xb000; +above_4g_mem_size = args-ram_size - lowmem; +below_4g_mem_size = lowmem; } else { above_4g_mem_size = 0; below_4g_mem_size = args-ram_size; @@ -228,6 +230,7 @@ static void pc_q35_init(QEMUMachineInitArgs *args) static void pc_compat_1_7(QEMUMachineInitArgs *args) { smbios_type1_defaults = false; +gigabyte_align = false; } static void pc_compat_1_6(QEMUMachineInitArgs *args) -- MST
[Qemu-devel] [PULL v2 34/35] q35: document gigabyte_align
Document the logic behind the below/above 4G split. Signed-off-by: Michael S. Tsirkin m...@redhat.com --- hw/i386/pc_q35.c | 13 + 1 file changed, 13 insertions(+) diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c index 7104645..a7f6260 100644 --- a/hw/i386/pc_q35.c +++ b/hw/i386/pc_q35.c @@ -51,6 +51,10 @@ static bool has_pci_info; static bool has_acpi_build = true; static bool smbios_type1_defaults = true; +/* Make sure that guest addresses aligned at 1Gbyte boundaries get mapped to + * host addresses aligned at 1Gbyte boundaries. This way we can use 1GByte + * pages in the host. + */ static bool gigabyte_align = true; /* PC hardware initialisation */ @@ -93,6 +97,15 @@ static void pc_q35_init(QEMUMachineInitArgs *args) kvmclock_create(); +/* Check whether RAM fits below 4G (leaving 1/2 GByte for IO memory + * and 256 Mbytes for PCI Express Enhanced Configuration Access Mapping + * also known as MMCFG). + * If it doesn't, we need to split it in chunks below and above 4G. + * In any case, try to make sure that guest addresses aligned at + * 1G boundaries get mapped to host addresses aligned at 1G boundaries. + * For old machine types, use whatever split we used historically to avoid + * breaking migration. + */ if (args-ram_size = 0xb000) { ram_addr_t lowmem = gigabyte_align ? 0x8000 : 0xb000; above_4g_mem_size = args-ram_size - lowmem; -- MST
[Qemu-devel] [PULL v2 26/35] pc: ACPI: expose PRST IO range via _CRS
From: Igor Mammedov imamm...@redhat.com .. so OSPM could notice resource conflict if there is any. Signed-off-by: Igor Mammedov imamm...@redhat.com Reviewed-by: Michael S. Tsirkin m...@redhat.com Signed-off-by: Michael S. Tsirkin m...@redhat.com --- hw/i386/acpi-dsdt-cpu-hotplug.dsl | 14 +- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/hw/i386/acpi-dsdt-cpu-hotplug.dsl b/hw/i386/acpi-dsdt-cpu-hotplug.dsl index 1dfbb4f..f91eafd 100644 --- a/hw/i386/acpi-dsdt-cpu-hotplug.dsl +++ b/hw/i386/acpi-dsdt-cpu-hotplug.dsl @@ -16,6 +16,7 @@ / * CPU hotplug / +#define CPU_HOTPLUG_RESOURCE_DEVICE PRES Scope(\_SB) { /* Objects filled in by run-time generated SSDT */ @@ -52,7 +53,8 @@ Scope(\_SB) { Sleep(200) } -OperationRegion(PRST, SystemIO, CPU_STATUS_BASE, 32) +#define CPU_STATUS_LEN 32 +OperationRegion(PRST, SystemIO, CPU_STATUS_BASE, CPU_STATUS_LEN) Field(PRST, ByteAcc, NoLock, Preserve) { PRS, 256 } @@ -89,4 +91,14 @@ Scope(\_SB) { Increment(Local0) } } + +Device(CPU_HOTPLUG_RESOURCE_DEVICE) { +Name(_HID, ACPI0004) + +Name(_CRS, ResourceTemplate() { +IO(Decode16, CPU_STATUS_BASE, CPU_STATUS_BASE, 0, CPU_STATUS_LEN) +}) + +Name(_STA, 0xB) /* present, functioning, decoding, not shown in UI */ +} } -- MST
[Qemu-devel] [PATCH] seccomp: add timerfd_create and timerfd_settime to the whitelist
libusb calls timerfd_create() and timerfd_settime() when it's built with timerfd support. Command to reproduce: qemu -sandbox on -monitor stdio -device piix3-usb-uhci,id=usb -device usb-host,hostbus=1,hostaddr=3,id=hostdev0 Log messages: audit(1390730418.924:135): auid=4294967295 uid=121 gid=103 ses=4294967295 pid=5232 comm=qemu-system-x86 sig=31 syscall=283 compat=0 ip=0x7f2b0f4e96a7 code=0x0 audit(1390733100.580:142): auid=4294967295 uid=121 gid=103 ses=4294967295 pid=16909 comm=qemu-system-x86 sig=31 syscall=286 compat=0 ip=0x7f03513a06da code=0x0 Signed-off-by: Felix Geyer de...@fobos.de --- qemu-seccomp.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/qemu-seccomp.c b/qemu-seccomp.c index caa926e..2705468 100644 --- a/qemu-seccomp.c +++ b/qemu-seccomp.c @@ -225,7 +225,9 @@ static const struct QemuSeccompSyscall seccomp_whitelist[] = { { SCMP_SYS(fchmod), 240 }, { SCMP_SYS(shmget), 240 }, { SCMP_SYS(shmat), 240 }, -{ SCMP_SYS(shmdt), 240 } +{ SCMP_SYS(shmdt), 240 }, +{ SCMP_SYS(timerfd_create), 240 }, +{ SCMP_SYS(timerfd_settime), 240 } }; int seccomp_start(void) -- 1.8.5.3
[Qemu-devel] [PULL v2 04/35] virtio: Fix return value for dummy function vhost_net_virtqueue_pending
From: Stefan Weil s...@weilnetz.de cgcc complains that -ENOSYS is not a good value for 'bool'. A dummy virtio will never have pending queue entries, so let us return false. Signed-off-by: Stefan Weil s...@weilnetz.de Signed-off-by: Michael S. Tsirkin m...@redhat.com --- hw/net/vhost_net.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/net/vhost_net.c b/hw/net/vhost_net.c index 006576d..854997d 100644 --- a/hw/net/vhost_net.c +++ b/hw/net/vhost_net.c @@ -321,7 +321,7 @@ void vhost_net_ack_features(struct vhost_net *net, unsigned features) bool vhost_net_virtqueue_pending(VHostNetState *net, int idx) { -return -ENOSYS; +return false; } void vhost_net_virtqueue_mask(VHostNetState *net, VirtIODevice *dev, -- MST
[Qemu-devel] [PULL v2 07/35] acpi unit-test: compare DSDT and SSDT tables against expected values
From: Marcel Apfelbaum marce...@redhat.com This test will run only if iasl is installed on the host machine. The test plan: 1. Dumps the ACPI tables as AML on the disk. 2. Runs iasl to disassembly the tables into ASL files. 3. Runs iasl to disassembly the offline AML files into ASL files. 4. Compares the ASL files. The test runs for both default machine and q35. In case the test fails, it can be easily tweaked to show the differences between the ASL files and understand the issue. Signed-off-by: Marcel Apfelbaum marce...@redhat.com Signed-off-by: Michael S. Tsirkin m...@redhat.com --- tests/acpi-test.c | 261 +- 1 file changed, 240 insertions(+), 21 deletions(-) diff --git a/tests/acpi-test.c b/tests/acpi-test.c index df1af83..c3fc603 100644 --- a/tests/acpi-test.c +++ b/tests/acpi-test.c @@ -18,14 +18,22 @@ #include qemu/compiler.h #include hw/i386/acpi-defs.h +#define MACHINE_PC pc +#define MACHINE_Q35 q35 + /* DSDT and SSDTs format */ typedef struct { AcpiTableHeader header; -uint8_t *aml; -int aml_len; -} AcpiSdtTable; +gchar *aml;/* aml bytecode from guest */ +gsize aml_len; +gchar *aml_file; +gchar *asl;/* asl code generated from aml */ +gsize asl_len; +gchar *asl_file; +} QEMU_PACKED AcpiSdtTable; typedef struct { +const char *machine; uint32_t rsdp_addr; AcpiRsdpDescriptor rsdp_table; AcpiRsdtDescriptorRev1 rsdt_table; @@ -33,8 +41,7 @@ typedef struct { AcpiFacsDescriptorRev1 facs_table; uint32_t *rsdt_tables_addr; int rsdt_tables_nr; -AcpiSdtTable dsdt_table; -GArray *ssdt_tables; +GArray *ssdt_tables; /* first is DSDT */ } test_data; #define LOW(x) ((x) 0xff) @@ -91,8 +98,10 @@ typedef struct { /* Boot sector code: write SIGNATURE into memory, * then halt. + * Q35 machine requires a minimum 0x7e000 bytes disk. + * (bug or feature?) */ -static uint8_t boot_sector[0x200] = { +static uint8_t boot_sector[0x7e000] = { /* 7c00: mov $0xdead,%ax */ [0x00] = 0xb8, [0x01] = LOW(SIGNATURE), @@ -117,17 +126,40 @@ static uint8_t boot_sector[0x200] = { }; static const char *disk = tests/acpi-test-disk.raw; +static const char *data_dir = tests/acpi-test-data; static void free_test_data(test_data *data) { +AcpiSdtTable *temp; int i; -g_free(data-rsdt_tables_addr); +if (data-rsdt_tables_addr) { +g_free(data-rsdt_tables_addr); +} + for (i = 0; i data-ssdt_tables-len; ++i) { -g_free(g_array_index(data-ssdt_tables, AcpiSdtTable, i).aml); +temp = g_array_index(data-ssdt_tables, AcpiSdtTable, i); +if (temp-aml) { +g_free(temp-aml); +} +if (temp-aml_file) { +if (g_strstr_len(temp-aml_file, -1, aml-)) { +unlink(temp-aml_file); +} +g_free(temp-aml_file); +} +if (temp-asl) { +g_free(temp-asl); +} +if (temp-asl_file) { +if (g_strstr_len(temp-asl_file, -1, asl-)) { +unlink(temp-asl_file); +} +g_free(temp-asl_file); +} } + g_array_free(data-ssdt_tables, false); -g_free(data-dsdt_table.aml); } static uint8_t acpi_checksum(const uint8_t *data, int len) @@ -292,34 +324,207 @@ static void test_dst_table(AcpiSdtTable *sdt_table, uint32_t addr) ACPI_READ_ARRAY_PTR(sdt_table-aml, sdt_table-aml_len, addr); checksum = acpi_checksum((uint8_t *)sdt_table, sizeof(AcpiTableHeader)) + - acpi_checksum(sdt_table-aml, sdt_table-aml_len); + acpi_checksum((uint8_t *)sdt_table-aml, sdt_table-aml_len); g_assert(!checksum); } static void test_acpi_dsdt_table(test_data *data) { -AcpiSdtTable *dsdt_table = data-dsdt_table; +AcpiSdtTable dsdt_table; uint32_t addr = data-fadt_table.dsdt; -test_dst_table(dsdt_table, addr); -g_assert_cmphex(dsdt_table-header.signature, ==, ACPI_DSDT_SIGNATURE); +memset(dsdt_table, 0, sizeof(dsdt_table)); +data-ssdt_tables = g_array_new(false, true, sizeof(AcpiSdtTable)); + +test_dst_table(dsdt_table, addr); +g_assert_cmphex(dsdt_table.header.signature, ==, ACPI_DSDT_SIGNATURE); + +/* Place DSDT first */ +g_array_append_val(data-ssdt_tables, dsdt_table); } static void test_acpi_ssdt_tables(test_data *data) { -GArray *ssdt_tables; int ssdt_tables_nr = data-rsdt_tables_nr - 1; /* fadt is first */ int i; -ssdt_tables = g_array_sized_new(false, true, sizeof(AcpiSdtTable), -ssdt_tables_nr); for (i = 0; i ssdt_tables_nr; i++) { AcpiSdtTable ssdt_table; + +memset(ssdt_table, 0 , sizeof(ssdt_table)); uint32_t addr = data-rsdt_tables_addr[i + 1]; /* fadt is first */ test_dst_table(ssdt_table, addr); -g_array_append_val(ssdt_tables, ssdt_table); +
[Qemu-devel] [PULL v2 05/35] acpi unit-test: add test files
From: Marcel Apfelbaum marce...@redhat.com Added unit-test's expected aml files to be compared with the actual ACPI tables. Signed-off-by: Marcel Apfelbaum marce...@redhat.com Signed-off-by: Michael S. Tsirkin m...@redhat.com --- tests/acpi-test-data/pc/APIC | Bin 0 - 120 bytes tests/acpi-test-data/pc/DSDT | Bin 0 - 4407 bytes tests/acpi-test-data/pc/FACP | Bin 0 - 116 bytes tests/acpi-test-data/pc/FACS | Bin 0 - 64 bytes tests/acpi-test-data/pc/HPET | Bin 0 - 56 bytes tests/acpi-test-data/pc/SSDT | Bin 0 - 2104 bytes tests/acpi-test-data/q35/APIC | Bin 0 - 120 bytes tests/acpi-test-data/q35/DSDT | Bin 0 - 7344 bytes tests/acpi-test-data/q35/FACP | Bin 0 - 116 bytes tests/acpi-test-data/q35/FACS | Bin 0 - 64 bytes tests/acpi-test-data/q35/HPET | Bin 0 - 56 bytes tests/acpi-test-data/q35/MCFG | Bin 0 - 60 bytes tests/acpi-test-data/q35/SSDT | Bin 0 - 2104 bytes 13 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 tests/acpi-test-data/pc/APIC create mode 100644 tests/acpi-test-data/pc/DSDT create mode 100644 tests/acpi-test-data/pc/FACP create mode 100644 tests/acpi-test-data/pc/FACS create mode 100644 tests/acpi-test-data/pc/HPET create mode 100644 tests/acpi-test-data/pc/SSDT create mode 100644 tests/acpi-test-data/q35/APIC create mode 100644 tests/acpi-test-data/q35/DSDT create mode 100644 tests/acpi-test-data/q35/FACP create mode 100644 tests/acpi-test-data/q35/FACS create mode 100644 tests/acpi-test-data/q35/HPET create mode 100644 tests/acpi-test-data/q35/MCFG create mode 100644 tests/acpi-test-data/q35/SSDT diff --git a/tests/acpi-test-data/pc/APIC b/tests/acpi-test-data/pc/APIC new file mode 100644 index ..84509e0ae4cabeb5ead3e42a4edfa50abddbc17d GIT binary patch literal 120 zcmZ^@N}+VU|?W;*Vk35v@85#a0y6k`O6f!H9Lf#JbFFwFr}2jnsGfW!{`1CdNz hKn!AlSgfo-nis_4b)ffC?aD+}vOm3)_F75db|X4FLcE literal 0 HcmV?d1 diff --git a/tests/acpi-test-data/pc/DSDT b/tests/acpi-test-data/pc/DSDT new file mode 100644 index ..b12e5eb85bb22f27fe10ce0fcf1d9a71f38360eb GIT binary patch literal 4407 zcmb7{OY~=8ONXHE~({^qL$K1mMprM3Mq+8uLYw(@SA;m!c?B(wa*fDQI+;asud7 z5UveGF$0PQ9HgAsp_IfI^a3|2+grae}wicq$sSD+2@(jQu7EgknUk;{F`^{AOl% zXZ+Cb-7Eqa+l@VMD_m=Q8hAdo82~_aDxJ1ANogrqZJvslx6gv=42gj4cqDZ`^Ge ze;f(8pn^G#l~O=``V(_Xoq@Kacl;j2`a~g`kR4io!JKVA*IcG-@$+J3(NT9|fJ z_q$+6ciX@I#pM$*FTHp60LM*QaaETr-6@UrdjFxelKg}C9wi|hqn%~!)BIG= zPRQ^-n^L|=KumGlN_1il+M=;-_Wb%)s`}lvL$JN#(J?P$}fI)?yepmVKJdg z$?2Wi55cXA$m@pif;ukl2Vt$MsUXvss}-*RviZAFrvp;X-4#L`0$aeVmlZHlzGW zP`MYun1cO@x+DrgxUsIPOF=WKeh_pv)`vlbBFYLyl$B0IkN!Xb$Uh#(W^37plNRf z0aDG2F?MFKF;!1(AxnV%hzvnVD+Cmq!;crcm1`Xql$uMilnyFr=1vNKJz;W8uW3 z{MRQjoW!}wWDKLi*Czw`%ODT`{%?8=V=-sbuoR1;@W(6-+3UAp(RewxGSkWKAA9M0 zt$HLE19l*Voxw%mr9fama#S^CKU^fJ_%H^lRApr)3Tr;5Jt2eq#wr+NVZJiQ;JmNJ zUkN^~)KqvA#~8y`Y7~CrY^F7{w$%LyCLn?%U(*v)Q=B-{SieWPk^l(Fw+T|y9Rs$ zrdOwm={2yhH+{T2oz)v=vX`k|M=(Ko`-~L;pcG4)37Xy#g;LIAvmcLE$xT!5K@^# z=pWy_-SDU8rs-zo;7`XIr!#fnJ}%XIPd}IIR8SpX}`2ojT4fTy(TWx#gxZd;qa zH+anz+G1JO91gGgL68DSJpJ+s#tCr-#i?V6}`l{KQx(k=L@C6oTL6ZED@t!XG4 zptn4h}o9$h53bP+odDv-?Y5Fok}t~X+wPwk{;3czAMbBd1``Pa%7lI3RArhMx^3 zaDv_$Cv}_I5x{ZrkT;0vBS~Gji~)u?~3;o*9`yM{M^t$!3YxADtpe=8R%39nIZ zZm+q;z-w+B!$ac$r~y~(MRvk;!MZieE2dJ*B{5D;uDH=Xv6^ctQQ-jd1~`TZHLs zk7yY=tw;C-CoAao=5PP@Xg+7*js_O+dinef%Q7f=c!$!P5)@qVQmT*2+N_|-!d zP8E5fVL?5UerTFV^2GSkGbKII_DqpyVu~*kWkgfyiIP0AH_{fr(aQErk!NCRDo-?( zo+!yP$$}pWWh*@`IAfHimhwzGk5cDMOV6YSY3Z4mrj=*Xd6YV5hH+-3XJVS+oG5k9 z8OAvyJrm9uWTdzvB((IBm{}Qs=}^DvnUXnPr?=WTdz6pT|aPQf`*YVr^#hf@M za#nJTGsihmYVs#*XA?NIP;tnrOr9aIPuSqagzC*(w#WI02sFwO$!M5%MmG0r*0 zImbCsYNVabQq_@IZ^7IxE5xvcA$oD-$aInOxf8RtCbM5%KwFwOWxxhJ5YOg) zbQ!11IZ^7Ii;Q!TaV~OBlse}U6L5#OPmvWZa$ZQWjCoRH!N}Y3=aV|5?WzLCG z=UicD~xl6bE4EaFEh@|jPo+*M5%MGGEUqOsdr9(HCH(N}clxGjK+uW(M3I_Fi! zd6jWq(w#WTEYG8sogiIZ^7I*BR$^#(AA{qEwvyr|;b`=}$^~vHsXM$o-ew((Y zTa|7#+g)hi!Jqyp`$QZa;2t(R7CCpLeaGu(V$x{7DVo=3}odQ;t*a?n@HomJ7d2 z5J$rUs*kC;f83dH#*sqZ(YtyKVZDhs7na@Kph_CjPGQi~Ms6g*1Isl6U`g1YAx zBflNO@2D=0WXqg9YmBKQeTR~ZfLwXP`$v-dACjNXW1JUvg7vZM`y2S*()-81^Y)Q zog{n3{o(AD{_zg6dl#~c)c=vbs-^W^wkULtM5o(JxlLjOpoWCA5CA=(${4A+J*GB zccicNkM}I34=*-RQhBI(V+;ZJlWpo+D%THbv!x{6ISyH2YTS50@FW9LYc*ORC zz1;(dhsB(*0rwDe4TcBL2OTsFku*@vS2)LFM9zl2t49IxO%9h6+*1mbLza;*N z=c2CM?fzY?^`GXYz*}_7akn#A@c@@r7=4cCeAuvreDU-s268pV;GFYlUU5am;1*4 zt2{P;jzh?0PYW;Kc4RQmJD;KA^L?0O6%aq_^}?QQ-lHeT7X6z1dD+090+pee^~ zw(bS(a=E+#I06`8QjIFS+2nS^V1b=t6c|Mt8ia!+p(Y0x~81gRq?SZLZ7ZJwG` TLKSsYG*scK!dFF86`Sxs!!O4 literal 0 HcmV?d1 diff --git a/tests/acpi-test-data/pc/FACP b/tests/acpi-test-data/pc/FACP new file mode 100644 index ..063ed1f748d44977f88e63d6a0ab49add040 GIT binary patch literal 116 zcmZBbPgzCU|?XpE!S15v@85#a0w6k`O6f!H9L;lclU2Owr-;AGeYbM1BBsPE~ l7#LWfGFXsWItFBVgbdO7+6?^ndU{9pknv9y7K0RZCI76AYN literal 0 HcmV?d1 diff --git a/tests/acpi-test-data/pc/FACS b/tests/acpi-test-data/pc/FACS new file mode 100644 index
[Qemu-devel] [Bug 1263318] Re: Cannot add a USB 2.0 device under QEMU when running eudev
** Changed in: qemu Status: New = Invalid -- You received this bug notification because you are a member of qemu- devel-ml, which is subscribed to QEMU. https://bugs.launchpad.net/bugs/1263318 Title: Cannot add a USB 2.0 device under QEMU when running eudev Status in QEMU: Invalid Bug description: Hello. I have a USB webcam I'm using under QEMU (version 1.6.1). The guest is Windows 7 (32-bit) while the host is Gentoo Linux (64-bit). I have been using it for several weeks without any problem, but now it doesn't work any more. I have been able to pinpoint the cause: it is because I switched from udev-208 to eudev-1.3 (which is based on udev-207). These are the command line options for QEMU: qemu-system-i386 -cpu host -m 1G -k it -drive file=Windows_7.qcow2,media=disk,index=0 -vga std -net nic -net user -enable-kvm -display sdl -soundhw ac97 -device usb-ehci,id=ehci -usb -rtc base=localtime -usbdevice tablet The relevant options are -device usb-ehci,id=ehci -usb. That is, I'm enabling both USB 2.0 (EHCI) and USB 1.1 (UHCI). I manually add the webcam using: device_add usb-host,hostbus=x,hostaddr=y,id=webcam but if I do so when running eudev it gets added as a slow USB 1.1 1.5 Mb/s device: (qemu) info usb [...] Device 1.0, Port 1, Speed 1.5 Mb/s, Product USB Host Device I also noticed that the info usbhost command works differently now, in that it doesn't display any more a description, such as the brand name (Creative): (qemu) info usbhost [...] Bus 1, Addr 3, Port 3, Speed 480 Mb/s Class ef: USB device 041e:4088 From the host system: $ lsusb | grep Creative Bus 001 Device 003: ID 041e:4088 Creative Technology, Ltd Live! Cam Chat HD [VF0700] If I turn back to udev I get the following results instead: (qemu) info usb [...] Device 1.1, Port 1, Speed 480 Mb/s, Product VF0700 Live! Cam Chat HD (qemu) info usbhost [...] Bus 1, Addr 2, Port 4, Speed 480 Mb/s Class ef: USB device 041e:4088, VF0700 Live! Cam Chat HD I don't know if this is a problem with QEMU or with eudev, so I'm also going to report this bug on the Gentoo Bugzilla (eudev is a Gentoo project). To manage notifications about this bug go to: https://bugs.launchpad.net/qemu/+bug/1263318/+subscriptions
[Qemu-devel] [PULL v2 12/35] tests: fix acpi to work on bigendian host
From: Alexey Kardashevskiy a...@ozlabs.ru Double endianness convertion make this test failing on POWERPC machine running in big-endian. This fixes the test to success on big-endian host. Signed-off-by: Alexey Kardashevskiy a...@ozlabs.ru Signed-off-by: Michael S. Tsirkin m...@redhat.com --- tests/acpi-test.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/acpi-test.c b/tests/acpi-test.c index 89c4b81..b5ab70a 100644 --- a/tests/acpi-test.c +++ b/tests/acpi-test.c @@ -61,13 +61,13 @@ typedef struct { field = readb(addr); \ break; \ case 2:\ -field = le16_to_cpu(readw(addr)); \ +field = readw(addr); \ break; \ case 4:\ -field = le32_to_cpu(readl(addr)); \ +field = readl(addr); \ break; \ case 8:\ -field = le64_to_cpu(readq(addr)); \ +field = readq(addr); \ break; \ default: \ g_assert(false); \ -- MST
[Qemu-devel] [PULL v2 16/35] pc: make: fix dependencies: rebuild when included file is changed
From: Igor Mammedov imamm...@redhat.com some *.dsl files include another *.dsl files but there weren't any dependicies and when included file changed target table wasn't rebuild. Fix this by using the same auto dependency generation as for C files. Signed-off-by: Igor Mammedov imamm...@redhat.com Reviewed-by: Michael S. Tsirkin m...@redhat.com Signed-off-by: Michael S. Tsirkin m...@redhat.com --- hw/i386/Makefile.objs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/i386/Makefile.objs b/hw/i386/Makefile.objs index 09ac433..d58a103 100644 --- a/hw/i386/Makefile.objs +++ b/hw/i386/Makefile.objs @@ -17,7 +17,7 @@ iasl-option=$(shell if test -z `$(1) $(2) 21 /dev/null` \ ifdef IASL #IASL Present. Generate hex files from .dsl hw/i386/%.hex: $(SRC_PATH)/hw/i386/%.dsl $(SRC_PATH)/scripts/acpi_extract_preprocess.py $(SRC_PATH)/scripts/acpi_extract.py - $(call quiet-command, cpp -P $ -o $*.dsl.i.orig, CPP $(TARGET_DIR)$*.dsl.i.orig) + $(call quiet-command, cpp -P $(QEMU_DGFLAGS) $ -o $*.dsl.i.orig, CPP $(TARGET_DIR)$*.dsl.i.orig) $(call quiet-command, $(PYTHON) $(SRC_PATH)/scripts/acpi_extract_preprocess.py $*.dsl.i.orig $*.dsl.i, ACPI_PREPROCESS $(TARGET_DIR)$*.dsl.i) $(call quiet-command, $(IASL) $(call iasl-option,$(IASL),-Pn,) -vs -l -tc -p $* $*.dsl.i $(if $(V), , /dev/null) 21 , IASL $(TARGET_DIR)$*.dsl.i) $(call quiet-command, $(PYTHON) $(SRC_PATH)/scripts/acpi_extract.py $*.lst $*.off, ACPI_EXTRACT $(TARGET_DIR)$*.off) -- MST
Re: [Qemu-devel] [PATCH v3] Fix QEMU build on OpenBSD on x86 archs
Il 26/01/2014 02:37, Brad Smith ha scritto: Reviewed-by: Stefan Hajnoczi stefa...@redhat.com Is there some sort of process I am missing to have build fixes commited so that QEMU actually builds? Right now we have problems getting patches committed at all. This patch and the other NetBSD patch is not lost. Paolo
[Qemu-devel] [PATCH 00/10] block: Integrate bdrv_file_open() into bdrv_open()
bdrv_file_open() is now nearly a subset of bdrv_open(), except for the fact that bdrv_file_open() is for protocols and bdrv_open() for block drivers. It is possible to use bdrv_file_open() with a block driver, but in that case that block driver must be explicitly specified. Due to these great similarities, bdrv_file_open() can be integrated and made a special case of bdrv_open(). If the flag BDRV_O_PROTOCOL is specified, bdrv_open() will now do what bdrv_file_open() used to do: Auto-detecting a protocol instead of a block driver. This series implements this and changes all calls to bdrv_file_open() to bdrv_open() calls with BDRV_O_PROTOCOL specified. Note that this flag cannot be discerned automatically since it is impossible for bdrv_open() to know by itself whether a given file should be opened with a block driver or through a protocol: Both are valid alternatives. Therefore, it still has to be specified by the user. Max Reitz (10): block: Change BDS parameter of bdrv_open() to ** block: Add reference parameter to bdrv_open() block: Make bdrv_file_open() static block: Reuse NULL options check from bdrv_open() block: Reuse reference handling from bdrv_open() block: Remove bdrv_new() from bdrv_file_open() block: Reuse fail path from bdrv_open() block: Reuse bs-options setting from bdrv_open() block: Reuse success path from bdrv_open() block: Remove bdrv_open_image()'s force_raw option block.c | 191 +++--- block/blkdebug.c | 2 +- block/blkverify.c | 4 +- block/cow.c | 6 +- block/qcow.c | 6 +- block/qcow2.c | 19 +++-- block/qed.c | 5 +- block/sheepdog.c | 8 ++- block/vhdx.c | 5 +- block/vmdk.c | 17 +++-- block/vvfat.c | 6 +- blockdev.c| 23 +++--- hw/block/xen_disk.c | 4 +- include/block/block.h | 12 ++-- qemu-img.c| 8 +-- qemu-io.c | 8 ++- qemu-nbd.c| 2 +- 17 files changed, 159 insertions(+), 167 deletions(-) -- 1.8.5.3
[Qemu-devel] [PATCH 05/10] block: Reuse reference handling from bdrv_open()
Remove the reference parameter and the related handling code from bdrv_file_open(), since it exists in bdrv_open() now as well. Signed-off-by: Max Reitz mre...@redhat.com --- block.c | 33 +++-- 1 file changed, 7 insertions(+), 26 deletions(-) diff --git a/block.c b/block.c index c7219cb..6c29115 100644 --- a/block.c +++ b/block.c @@ -948,8 +948,7 @@ free_and_fail: * dictionary, it needs to use QINCREF() before calling bdrv_file_open. */ static int bdrv_file_open(BlockDriverState **pbs, const char *filename, - const char *reference, QDict *options, int flags, - Error **errp) + QDict *options, int flags, Error **errp) { BlockDriverState *bs = NULL; BlockDriver *drv; @@ -958,24 +957,6 @@ static int bdrv_file_open(BlockDriverState **pbs, const char *filename, Error *local_err = NULL; int ret; -if (reference) { -if (filename || qdict_size(options)) { -error_setg(errp, Cannot reference an existing block device with - additional options or a new filename); -return -EINVAL; -} -QDECREF(options); - -bs = bdrv_find(reference); -if (!bs) { -error_setg(errp, Cannot find block device '%s', reference); -return -ENODEV; -} -bdrv_ref(bs); -*pbs = bs; -return 0; -} - bs = bdrv_new(); bs-options = options; options = qdict_clone_shallow(options); @@ -1228,12 +1209,6 @@ int bdrv_open(BlockDriverState **pbs, const char *filename, options = qdict_new(); } -if (flags BDRV_O_PROTOCOL) { -assert(!drv); -return bdrv_file_open(pbs, filename, reference, options, - flags ~BDRV_O_PROTOCOL, errp); -} - if (reference) { bool options_non_empty = qdict_size(options); QDECREF(options); @@ -1260,6 +1235,12 @@ int bdrv_open(BlockDriverState **pbs, const char *filename, return 0; } +if (flags BDRV_O_PROTOCOL) { +assert(!drv); +return bdrv_file_open(pbs, filename, options, flags ~BDRV_O_PROTOCOL, + errp); +} + if (*pbs) { bs = *pbs; } else { -- 1.8.5.3
[Qemu-devel] [PATCH 02/10] block: Add reference parameter to bdrv_open()
Allow bdrv_open() to handle references to existing block devices just as bdrv_file_open() is already capable of. Signed-off-by: Max Reitz mre...@redhat.com --- block.c | 41 ++--- block/qcow2.c | 4 ++-- block/vmdk.c | 3 ++- block/vvfat.c | 2 +- blockdev.c| 12 ++-- hw/block/xen_disk.c | 4 ++-- include/block/block.h | 5 +++-- qemu-img.c| 8 qemu-io.c | 4 +++- qemu-nbd.c| 2 +- 10 files changed, 58 insertions(+), 27 deletions(-) diff --git a/block.c b/block.c index c660609..f9923bb 100644 --- a/block.c +++ b/block.c @@ -1039,7 +1039,7 @@ int bdrv_file_open(BlockDriverState **pbs, const char *filename, } if (!drv-bdrv_file_open) { -ret = bdrv_open(bs, filename, options, flags, drv, local_err); +ret = bdrv_open(bs, filename, NULL, options, flags, drv, local_err); options = NULL; } else { ret = bdrv_open_common(bs, NULL, options, flags, drv, local_err); @@ -1117,7 +1117,7 @@ int bdrv_open_backing_file(BlockDriverState *bs, QDict *options, Error **errp) BDRV_O_COPY_ON_READ); ret = bdrv_open(bs-backing_hd, -*backing_filename ? backing_filename : NULL, options, +*backing_filename ? backing_filename : NULL, NULL, options, back_flags, back_drv, local_err); if (ret 0) { bs-backing_hd = NULL; @@ -1194,7 +1194,7 @@ int bdrv_open_image(BlockDriverState **pbs, const char *filename, } *pbs = NULL; -ret = bdrv_open(pbs, filename, image_options, flags, NULL, errp); +ret = bdrv_open(pbs, filename, NULL, image_options, flags, NULL, errp); } else { ret = bdrv_file_open(pbs, filename, reference, image_options, flags, errp); @@ -1216,8 +1216,9 @@ done: * If *pbs is NULL, a new BDS will be created with a pointer to it stored there. * If it is not NULL, the referenced BDS will be reused. */ -int bdrv_open(BlockDriverState **pbs, const char *filename, QDict *options, - int flags, BlockDriver *drv, Error **errp) +int bdrv_open(BlockDriverState **pbs, const char *filename, + const char *reference, QDict *options, int flags, + BlockDriver *drv, Error **errp) { int ret; /* TODO: extra byte is a hack to ensure MAX_PATH space on Windows. */ @@ -1231,6 +1232,32 @@ int bdrv_open(BlockDriverState **pbs, const char *filename, QDict *options, options = qdict_new(); } +if (reference) { +bool options_non_empty = qdict_size(options); +QDECREF(options); + +if (*pbs) { +error_setg(errp, Cannot reuse an existing BDS when referencing + another block device); +return -EINVAL; +} + +if (filename || options_non_empty) { +error_setg(errp, Cannot reference an existing block device with + additional options or a new filename); +return -EINVAL; +} + +bs = bdrv_find(reference); +if (!bs) { +error_setg(errp, Cannot find block device '%s', reference); +return -ENODEV; +} +bdrv_ref(bs); +*pbs = bs; +return 0; +} + if (*pbs) { bs = *pbs; } else { @@ -1252,7 +1279,7 @@ int bdrv_open(BlockDriverState **pbs, const char *filename, QDict *options, /* Get the required size from the image */ QINCREF(options); -ret = bdrv_open(bs1, filename, options, BDRV_O_NO_BACKING, +ret = bdrv_open(bs1, filename, NULL, options, BDRV_O_NO_BACKING, drv, local_err); if (ret 0) { goto fail; @@ -5289,7 +5316,7 @@ void bdrv_img_create(const char *filename, const char *fmt, back_flags = flags ~(BDRV_O_RDWR | BDRV_O_SNAPSHOT | BDRV_O_NO_BACKING); -ret = bdrv_open(bs, backing_file-value.s, NULL, back_flags, +ret = bdrv_open(bs, backing_file-value.s, NULL, NULL, back_flags, backing_drv, local_err); if (ret 0) { error_setg_errno(errp, -ret, Could not open '%s': %s, diff --git a/block/qcow2.c b/block/qcow2.c index 9a25fbd..7202a26 100644 --- a/block/qcow2.c +++ b/block/qcow2.c @@ -1551,7 +1551,7 @@ static int qcow2_create2(const char *filename, int64_t total_size, */ BlockDriver* drv = bdrv_find_format(qcow2); assert(drv != NULL); -ret = bdrv_open(bs, filename, NULL, +ret = bdrv_open(bs, filename, NULL, NULL, BDRV_O_RDWR | BDRV_O_CACHE_WB | BDRV_O_NO_FLUSH, drv, local_err); if (ret 0) { error_propagate(errp, local_err); @@ -1602,7 +1602,7 @@ static int qcow2_create2(const char *filename, int64_t total_size, bs = NULL;
[Qemu-devel] [PATCH 07/10] block: Reuse fail path from bdrv_open()
The fail paths of bdrv_file_open() and bdrv_open() naturally exhibit similarities, thus it is possible to reuse the one from bdrv_open() and shorten the one in bdrv_file_open() accordingly. Signed-off-by: Max Reitz mre...@redhat.com --- block.c | 17 +++-- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/block.c b/block.c index 72eddd5..0f2cd3f 100644 --- a/block.c +++ b/block.c @@ -1038,9 +1038,6 @@ static int bdrv_file_open(BlockDriverState *bs, const char *filename, fail: QDECREF(options); -if (!bs-drv) { -QDECREF(bs-options); -} return ret; } @@ -1240,17 +1237,17 @@ int bdrv_open(BlockDriverState **pbs, const char *filename, if (flags BDRV_O_PROTOCOL) { assert(!drv); ret = bdrv_file_open(bs, filename, options, flags ~BDRV_O_PROTOCOL, - errp); + local_err); +options = NULL; if (ret) { -if (*pbs) { -bdrv_close(bs); +if (bs-drv) { +goto close_and_fail; } else { -bdrv_unref(bs); +goto fail; } -} else { -*pbs = bs; } -return ret; +*pbs = bs; +return 0; } bs-options = options; -- 1.8.5.3
[Qemu-devel] [PATCH 04/10] block: Reuse NULL options check from bdrv_open()
Remove the check whether options is NULL form bdrv_file_open() and rely on the one in bdrv_open() instead. Signed-off-by: Max Reitz mre...@redhat.com --- block.c | 15 +-- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/block.c b/block.c index 0fb7892..c7219cb 100644 --- a/block.c +++ b/block.c @@ -958,11 +958,6 @@ static int bdrv_file_open(BlockDriverState **pbs, const char *filename, Error *local_err = NULL; int ret; -/* NULL means an empty set of options */ -if (options == NULL) { -options = qdict_new(); -} - if (reference) { if (filename || qdict_size(options)) { error_setg(errp, Cannot reference an existing block device with @@ -1228,17 +1223,17 @@ int bdrv_open(BlockDriverState **pbs, const char *filename, const char *drvname; Error *local_err = NULL; +/* NULL means an empty set of options */ +if (options == NULL) { +options = qdict_new(); +} + if (flags BDRV_O_PROTOCOL) { assert(!drv); return bdrv_file_open(pbs, filename, reference, options, flags ~BDRV_O_PROTOCOL, errp); } -/* NULL means an empty set of options */ -if (options == NULL) { -options = qdict_new(); -} - if (reference) { bool options_non_empty = qdict_size(options); QDECREF(options); -- 1.8.5.3
[Qemu-devel] [PATCH 10/10] block: Remove bdrv_open_image()'s force_raw option
This option is now unnecessary since specifying BDRV_O_PROTOCOL as flag will do exactly the same. Signed-off-by: Max Reitz mre...@redhat.com --- block.c | 30 +- block/blkdebug.c | 2 +- block/blkverify.c | 4 ++-- include/block/block.h | 2 +- 4 files changed, 9 insertions(+), 29 deletions(-) diff --git a/block.c b/block.c index b1bae23..7f02ff1 100644 --- a/block.c +++ b/block.c @@ -1096,10 +1096,6 @@ int bdrv_open_backing_file(BlockDriverState *bs, QDict *options, Error **errp) * Opens a disk image whose options are given as BlockdevRef in another block * device's options. * - * If force_raw is true, bdrv_file_open() will be used, thereby preventing any - * image format auto-detection. If it is false and a filename is given, - * bdrv_open() will be used for auto-detection. - * * If allow_none is true, no image will be opened if filename is false and no * BlockdevRef is given. *pbs will remain unchanged and 0 will be returned. * @@ -1112,7 +1108,7 @@ int bdrv_open_backing_file(BlockDriverState *bs, QDict *options, Error **errp) */ int bdrv_open_image(BlockDriverState **pbs, const char *filename, QDict *options, const char *bdref_key, int flags, -bool force_raw, bool allow_none, Error **errp) +bool allow_none, Error **errp) { QDict *image_options; int ret; @@ -1135,24 +1131,8 @@ int bdrv_open_image(BlockDriverState **pbs, const char *filename, goto done; } -if (filename !force_raw) { -/* If a filename is given and the block driver should be detected - automatically (instead of using none), use bdrv_open() in order to do - that auto-detection. */ -if (reference) { -error_setg(errp, Cannot reference an existing block device while - giving a filename); -ret = -EINVAL; -goto done; -} - -*pbs = NULL; -ret = bdrv_open(pbs, filename, NULL, image_options, flags, NULL, errp); -} else { -*pbs = NULL; -ret = bdrv_open(pbs, filename, reference, image_options, -flags | BDRV_O_PROTOCOL, NULL, errp); -} +*pbs = NULL; +ret = bdrv_open(pbs, filename, reference, image_options, flags, NULL, errp); done: qdict_del(options, bdref_key); @@ -1308,8 +1288,8 @@ int bdrv_open(BlockDriverState **pbs, const char *filename, } ret = bdrv_open_image(file, filename, options, file, - bdrv_open_flags(bs, flags | BDRV_O_UNMAP), true, true, - local_err); + bdrv_open_flags(bs, flags | BDRV_O_UNMAP) | + BDRV_O_PROTOCOL, true, local_err); if (ret 0) { goto fail; } diff --git a/block/blkdebug.c b/block/blkdebug.c index 56c4cd0..5696ef6 100644 --- a/block/blkdebug.c +++ b/block/blkdebug.c @@ -411,7 +411,7 @@ static int blkdebug_open(BlockDriverState *bs, QDict *options, int flags, /* Open the backing file */ ret = bdrv_open_image(bs-file, qemu_opt_get(opts, x-image), options, image, - flags, true, false, local_err); + flags | BDRV_O_PROTOCOL, false, local_err); if (ret 0) { error_propagate(errp, local_err); goto fail; diff --git a/block/blkverify.c b/block/blkverify.c index cfcbcf4..fe94b59 100644 --- a/block/blkverify.c +++ b/block/blkverify.c @@ -136,7 +136,7 @@ static int blkverify_open(BlockDriverState *bs, QDict *options, int flags, /* Open the raw file */ ret = bdrv_open_image(bs-file, qemu_opt_get(opts, x-raw), options, - raw, flags, true, false, local_err); + raw, flags | BDRV_O_PROTOCOL, false, local_err); if (ret 0) { error_propagate(errp, local_err); goto fail; @@ -144,7 +144,7 @@ static int blkverify_open(BlockDriverState *bs, QDict *options, int flags, /* Open the test file */ ret = bdrv_open_image(s-test_file, qemu_opt_get(opts, x-image), options, - test, flags, false, false, local_err); + test, flags, false, local_err); if (ret 0) { error_propagate(errp, local_err); s-test_file = NULL; diff --git a/include/block/block.h b/include/block/block.h index 396f9ed..9bf8ef1 100644 --- a/include/block/block.h +++ b/include/block/block.h @@ -187,7 +187,7 @@ int bdrv_parse_cache_flags(const char *mode, int *flags); int bdrv_parse_discard_flags(const char *mode, int *flags); int bdrv_open_image(BlockDriverState **pbs, const char *filename, QDict *options, const char *bdref_key, int flags, -bool force_raw, bool allow_none, Error **errp); +bool allow_none, Error **errp); int bdrv_open_backing_file(BlockDriverState *bs, QDict *options, Error
[Qemu-devel] [PATCH 08/10] block: Reuse bs-options setting from bdrv_open()
Setting bs-options in bdrv_file_open() is not necessary if it is already done in bdrv_open(). Signed-off-by: Max Reitz mre...@redhat.com --- block.c | 9 +++-- 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/block.c b/block.c index 0f2cd3f..f847c4b 100644 --- a/block.c +++ b/block.c @@ -956,9 +956,6 @@ static int bdrv_file_open(BlockDriverState *bs, const char *filename, Error *local_err = NULL; int ret; -bs-options = options; -options = qdict_clone_shallow(options); - /* Fetch the file name from the options QDict if necessary */ if (!filename) { filename = qdict_get_try_str(options, filename); @@ -1234,6 +1231,9 @@ int bdrv_open(BlockDriverState **pbs, const char *filename, bs = bdrv_new(); } +bs-options = options; +options = qdict_clone_shallow(options); + if (flags BDRV_O_PROTOCOL) { assert(!drv); ret = bdrv_file_open(bs, filename, options, flags ~BDRV_O_PROTOCOL, @@ -1250,9 +1250,6 @@ int bdrv_open(BlockDriverState **pbs, const char *filename, return 0; } -bs-options = options; -options = qdict_clone_shallow(options); - /* For snapshot=on, create a temporary qcow2 overlay */ if (flags BDRV_O_SNAPSHOT) { BlockDriverState *bs1 = NULL; -- 1.8.5.3
[Qemu-devel] [PATCH 09/10] block: Reuse success path from bdrv_open()
The fail and success paths of bdrv_file_open() may be further shortened by reusing code already existent in bdrv_open(). This includes bdrv_file_open() not taking the reference to options which allows the removal of QDECREF(options) in that function. Signed-off-by: Max Reitz mre...@redhat.com --- block.c | 33 - 1 file changed, 12 insertions(+), 21 deletions(-) diff --git a/block.c b/block.c index f847c4b..b1bae23 100644 --- a/block.c +++ b/block.c @@ -943,9 +943,7 @@ free_and_fail: * Opens a file using a protocol (file, host_device, nbd, ...) * * options is a QDict of options to pass to the block drivers, or NULL for an - * empty set of options. The reference to the QDict belongs to the block layer - * after the call (even on failure), so if the caller intends to reuse the - * dictionary, it needs to use QINCREF() before calling bdrv_file_open. + * empty set of options. */ static int bdrv_file_open(BlockDriverState *bs, const char *filename, QDict *options, int flags, Error **errp) @@ -1010,8 +1008,8 @@ static int bdrv_file_open(BlockDriverState *bs, const char *filename, } if (!drv-bdrv_file_open) { +QINCREF(options); ret = bdrv_open(bs, filename, NULL, options, flags, drv, local_err); -options = NULL; } else { ret = bdrv_open_common(bs, NULL, options, flags, drv, local_err); } @@ -1020,21 +1018,10 @@ static int bdrv_file_open(BlockDriverState *bs, const char *filename, goto fail; } -/* Check if any unknown options were used */ -if (options (qdict_size(options) != 0)) { -const QDictEntry *entry = qdict_first(options); -error_setg(errp, Block protocol '%s' doesn't support the option '%s', - drv-format_name, entry-key); -ret = -EINVAL; -goto fail; -} -QDECREF(options); - bs-growable = 1; return 0; fail: -QDECREF(options); return ret; } @@ -1238,7 +1225,6 @@ int bdrv_open(BlockDriverState **pbs, const char *filename, assert(!drv); ret = bdrv_file_open(bs, filename, options, flags ~BDRV_O_PROTOCOL, local_err); -options = NULL; if (ret) { if (bs-drv) { goto close_and_fail; @@ -1246,8 +1232,7 @@ int bdrv_open(BlockDriverState **pbs, const char *filename, goto fail; } } -*pbs = bs; -return 0; +goto done; } /* For snapshot=on, create a temporary qcow2 overlay */ @@ -1377,12 +1362,18 @@ int bdrv_open(BlockDriverState **pbs, const char *filename, } } +done: /* Check if any unknown options were used */ if (qdict_size(options) != 0) { const QDictEntry *entry = qdict_first(options); -error_setg(errp, Block format '%s' used by device '%s' doesn't - support the option '%s', drv-format_name, bs-device_name, - entry-key); +if (flags BDRV_O_PROTOCOL) { +error_setg(errp, Block protocol '%s' doesn't support the option + '%s', drv-format_name, entry-key); +} else { +error_setg(errp, Block format '%s' used by device '%s' doesn't + support the option '%s', drv-format_name, + bs-device_name, entry-key); +} ret = -EINVAL; goto close_and_fail; -- 1.8.5.3
[Qemu-devel] [PATCH 20/21] target-arm: A64: Add 2-reg-misc REV* instructions
From: Alex Bennée alex.ben...@linaro.org Add the byte-reverse operations REV64, REV32 and REV16 from the two-reg-misc group. Signed-off-by: Alex Bennée alex.ben...@linaro.org Signed-off-by: Peter Maydell peter.mayd...@linaro.org --- target-arm/translate-a64.c | 42 +- 1 file changed, 41 insertions(+), 1 deletion(-) diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c index d6979d9..db89327 100644 --- a/target-arm/translate-a64.c +++ b/target-arm/translate-a64.c @@ -7474,6 +7474,46 @@ static void handle_2misc_narrow(DisasContext *s, int opcode, bool u, bool is_q, } } +static void handle_rev(DisasContext *s, int opcode, bool u, + bool is_q, int size, int rn, int rd) +{ +int op = (opcode 1) 1 | u; +int opsz = op + size; +int ibits = 3 - opsz; +int revmask = (1 ibits) - 1; +int dsize = is_q ? 128 : 64; +int esize = 8 size; +int elements = dsize / esize; +int i; +TCGv_i64 tcg_rd_hi, tcg_rd, tcg_rn; + +if (opsz = 3) { +unallocated_encoding(s); +return; +} + +tcg_rn = tcg_temp_new_i64(); +tcg_rd = tcg_const_i64(0); +tcg_rd_hi = tcg_const_i64(0); + +for (i = 0; i elements; i++) { +int e_rev = (i 0xf) ^ revmask; +int off = e_rev * esize; +read_vec_element(s, tcg_rn, rn, i, size); +if (off = 64) { +tcg_gen_deposit_i64(tcg_rd_hi, tcg_rd_hi, tcg_rn, off - 64, esize); +} else { +tcg_gen_deposit_i64(tcg_rd, tcg_rd, tcg_rn, off, esize); +} +} +write_vec_element(s, tcg_rd, rd, 0, MO_64); +write_vec_element(s, tcg_rd_hi, rd, 1, MO_64); + +tcg_temp_free_i64(tcg_rd_hi); +tcg_temp_free_i64(tcg_rd); +tcg_temp_free_i64(tcg_rn); +} + /* C3.6.17 AdvSIMD two reg misc * 31 30 29 28 24 23 22 21 17 1612 11 10 95 40 * +---+---+---+---+--+---++-+--+--+ @@ -7492,7 +7532,7 @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn) switch (opcode) { case 0x0: /* REV64, REV32 */ case 0x1: /* REV16 */ -unsupported_encoding(s, insn); +handle_rev(s, opcode, u, is_q, size, rn, rd); return; case 0x5: /* CNT, NOT, RBIT */ if (u size == 0) { -- 1.8.5
[Qemu-devel] [PATCH 19/21] target-arm: A64: Add narrowing 2-reg-misc instructions
Add the narrowing integer instructions in the 2-reg-misc class. Signed-off-by: Peter Maydell peter.mayd...@linaro.org --- target-arm/translate-a64.c | 85 -- 1 file changed, 83 insertions(+), 2 deletions(-) diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c index 3a3489b..d6979d9 100644 --- a/target-arm/translate-a64.c +++ b/target-arm/translate-a64.c @@ -75,6 +75,8 @@ typedef struct AArch64DecodeTable { /* Function prototype for gen_ functions for calling Neon helpers */ typedef void NeonGenTwoOpFn(TCGv_i32, TCGv_i32, TCGv_i32); typedef void NeonGenTwoOpEnvFn(TCGv_i32, TCGv_ptr, TCGv_i32, TCGv_i32); +typedef void NeonGenNarrowFn(TCGv_i32, TCGv_i64); +typedef void NeonGenNarrowEnvFn(TCGv_i32, TCGv_ptr, TCGv_i64); /* initialize TCG globals. */ void a64_translate_init(void) @@ -7399,6 +7401,79 @@ static void disas_simd_three_reg_same(DisasContext *s, uint32_t insn) } } +static void handle_2misc_narrow(DisasContext *s, int opcode, bool u, bool is_q, +int size, int rn, int rd) +{ +/* Handle 2-reg-misc ops which are narrowing (so each 2*size element + * in the source becomes a size element in the destination). + */ +int pass; +TCGv_i32 tcg_res[2]; +int destelt = is_q ? 2 : 0; + +for (pass = 0; pass 2; pass++) { +TCGv_i64 tcg_op = tcg_temp_new_i64(); +NeonGenNarrowFn *genfn = NULL; +NeonGenNarrowEnvFn *genenvfn = NULL; + +read_vec_element(s, tcg_op, rn, pass, MO_64); +tcg_res[pass] = tcg_temp_new_i32(); + +switch (opcode) { +case 0x12: /* XTN, SQXTUN */ +{ +static NeonGenNarrowFn * const xtnfns[3] = { +gen_helper_neon_narrow_u8, +gen_helper_neon_narrow_u16, +tcg_gen_trunc_i64_i32, +}; +static NeonGenNarrowEnvFn * const sqxtunfns[3] = { +gen_helper_neon_unarrow_sat8, +gen_helper_neon_unarrow_sat16, +gen_helper_neon_unarrow_sat32, +}; +if (u) { +genenvfn = sqxtunfns[size]; +} else { +genfn = xtnfns[size]; +} +break; +} +case 0x14: /* SQXTN, UQXTN */ +{ +static NeonGenNarrowEnvFn * const fns[3][2] = { +{ gen_helper_neon_narrow_sat_s8, + gen_helper_neon_narrow_sat_u8 }, +{ gen_helper_neon_narrow_sat_s16, + gen_helper_neon_narrow_sat_u16 }, +{ gen_helper_neon_narrow_sat_s32, + gen_helper_neon_narrow_sat_u32 }, +}; +genenvfn = fns[size][u]; +break; +} +default: +g_assert_not_reached(); +} + +if (genfn) { +genfn(tcg_res[pass], tcg_op); +} else { +genenvfn(tcg_res[pass], cpu_env, tcg_op); +} + +tcg_temp_free_i64(tcg_op); +} + +for (pass = 0; pass 2; pass++) { +write_vec_element_i32(s, tcg_res[pass], rd, destelt + pass, MO_32); +tcg_temp_free_i32(tcg_res[pass]); +} +if (!is_q) { +clear_vec_high(s, rd); +} +} + /* C3.6.17 AdvSIMD two reg misc * 31 30 29 28 24 23 22 21 17 1612 11 10 95 40 * +---+---+---+---+--+---++-+--+--+ @@ -7433,11 +7508,17 @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn) } unallocated_encoding(s); return; +case 0x12: /* XTN, XTN2, SQXTUN, SQXTUN2 */ +case 0x14: /* SQXTN, SQXTN2, UQXTN, UQXTN2 */ +if (size == 3) { +unallocated_encoding(s); +return; +} +handle_2misc_narrow(s, opcode, u, is_q, size, rn, rd); +return; case 0x2: /* SADDLP, UADDLP */ case 0x4: /* CLS, CLZ */ case 0x6: /* SADALP, UADALP */ -case 0x12: /* XTN, XTN2, SQXTUN, SQXTUN2 */ -case 0x14: /* SQXTN, SQXTN2, UQXTN, UQXTN2 */ if (size == 3) { unallocated_encoding(s); return; -- 1.8.5
[Qemu-devel] [PATCH 17/21] target-arm: A64: Implement 2-register misc compares, ABS, NEG
Implement the simple 2-register-misc operations we can share with the scalar-two-register-misc code. (SUQADD, USQADD, SQABS, SQNEG also fall into this category, but aren't implemented in the scalar-2-register case yet either.) Signed-off-by: Peter Maydell peter.mayd...@linaro.org --- target-arm/translate-a64.c | 136 - 1 file changed, 134 insertions(+), 2 deletions(-) diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c index f03d645..d484967 100644 --- a/target-arm/translate-a64.c +++ b/target-arm/translate-a64.c @@ -7405,6 +7405,8 @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn) int opcode = extract32(insn, 12, 5); bool u = extract32(insn, 29, 1); bool is_q = extract32(insn, 30, 1); +int rn = extract32(insn, 5, 5); +int rd = extract32(insn, 0, 5); switch (opcode) { case 0x0: /* REV64, REV32 */ @@ -7443,8 +7445,6 @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn) return; } /* fall through */ -case 0x3: /* SUQADD, USQADD */ -case 0x7: /* SQABS, SQNEG */ case 0x8: /* CMGT, CMGE */ case 0x9: /* CMEQ, CMLE */ case 0xb: /* ABS, NEG */ @@ -7452,6 +7452,13 @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn) unallocated_encoding(s); return; } +break; +case 0x3: /* SUQADD, USQADD */ +case 0x7: /* SQABS, SQNEG */ +if (size == 3 !is_q) { +unallocated_encoding(s); +return; +} unsupported_encoding(s, insn); return; case 0xc ... 0xf: @@ -7510,6 +7517,131 @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn) unallocated_encoding(s); return; } + +if (size == 3) { +/* All 64-bit element operations can be shared with scalar 2misc */ +int pass; + +for (pass = 0; pass (is_q ? 2 : 1); pass++) { +TCGv_i64 tcg_op = tcg_temp_new_i64(); +TCGv_i64 tcg_res = tcg_temp_new_i64(); + +read_vec_element(s, tcg_op, rn, pass, MO_64); + +handle_2misc_64(s, opcode, u, tcg_res, tcg_op); + +write_vec_element(s, tcg_res, rd, pass, MO_64); + +tcg_temp_free_i64(tcg_res); +tcg_temp_free_i64(tcg_op); +} +} else { +int pass; + +for (pass = 0; pass (is_q ? 4 : 2); pass++) { +TCGv_i32 tcg_op = tcg_temp_new_i32(); +TCGv_i32 tcg_res = tcg_temp_new_i32(); +TCGCond cond; + +read_vec_element_i32(s, tcg_op, rn, pass, MO_32); + +if (size == 2) { +/* Special cases for 32 bit elements */ +switch (opcode) { +case 0xa: /* CMLT */ +/* 32 bit integer comparison against zero, result is + * test ? (2^32 - 1) : 0. We implement via setcond(test) + * and inverting. + */ +cond = TCG_COND_LT; +do_cmop: +tcg_gen_setcondi_i32(cond, tcg_res, tcg_op, 0); +tcg_gen_neg_i32(tcg_res, tcg_res); +break; +case 0x8: /* CMGT, CMGE */ +cond = u ? TCG_COND_GE : TCG_COND_GT; +goto do_cmop; +case 0x9: /* CMEQ, CMLE */ +cond = u ? TCG_COND_LE : TCG_COND_EQ; +goto do_cmop; +case 0xb: /* ABS, NEG */ +if (u) { +tcg_gen_neg_i32(tcg_res, tcg_op); +} else { +TCGv_i32 tcg_zero = tcg_const_i32(0); +tcg_gen_neg_i32(tcg_res, tcg_op); +tcg_gen_movcond_i32(TCG_COND_GT, tcg_res, tcg_op, +tcg_zero, tcg_op, tcg_res); +tcg_temp_free_i32(tcg_zero); +} +break; +default: +g_assert_not_reached(); +} +} else { +/* Use helpers for 8 and 16 bit elements */ +switch (opcode) { +case 0x8: /* CMGT, CMGE */ +case 0x9: /* CMEQ, CMLE */ +case 0xa: /* CMLT */ +{ +static NeonGenTwoOpFn * const fns[3][2] = { +{ gen_helper_neon_cgt_s8, gen_helper_neon_cgt_s16 }, +{ gen_helper_neon_cge_s8, gen_helper_neon_cge_s16 }, +{ gen_helper_neon_ceq_u8, gen_helper_neon_ceq_u16 }, +}; +NeonGenTwoOpFn *genfn; +int comp; +bool reverse; +TCGv_i32 tcg_zero = tcg_const_i32(0); + +/* comp = index into [CMGT, CMGE, CMEQ, CMLE,
[Qemu-devel] [PATCH 06/10] block: Remove bdrv_new() from bdrv_file_open()
Change bdrv_file_open() to take a simple pointer to an already existing BDS instead of an indirect one. The BDS will be created in bdrv_open() if necessary. Signed-off-by: Max Reitz mre...@redhat.com --- block.c | 29 ++--- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/block.c b/block.c index 6c29115..72eddd5 100644 --- a/block.c +++ b/block.c @@ -947,17 +947,15 @@ free_and_fail: * after the call (even on failure), so if the caller intends to reuse the * dictionary, it needs to use QINCREF() before calling bdrv_file_open. */ -static int bdrv_file_open(BlockDriverState **pbs, const char *filename, +static int bdrv_file_open(BlockDriverState *bs, const char *filename, QDict *options, int flags, Error **errp) { -BlockDriverState *bs = NULL; BlockDriver *drv; const char *drvname; bool allow_protocol_prefix = false; Error *local_err = NULL; int ret; -bs = bdrv_new(); bs-options = options; options = qdict_clone_shallow(options); @@ -1036,7 +1034,6 @@ static int bdrv_file_open(BlockDriverState **pbs, const char *filename, QDECREF(options); bs-growable = 1; -*pbs = bs; return 0; fail: @@ -1044,7 +1041,6 @@ fail: if (!bs-drv) { QDECREF(bs-options); } -bdrv_unref(bs); return ret; } @@ -1235,17 +1231,28 @@ int bdrv_open(BlockDriverState **pbs, const char *filename, return 0; } -if (flags BDRV_O_PROTOCOL) { -assert(!drv); -return bdrv_file_open(pbs, filename, options, flags ~BDRV_O_PROTOCOL, - errp); -} - if (*pbs) { bs = *pbs; } else { bs = bdrv_new(); } + +if (flags BDRV_O_PROTOCOL) { +assert(!drv); +ret = bdrv_file_open(bs, filename, options, flags ~BDRV_O_PROTOCOL, + errp); +if (ret) { +if (*pbs) { +bdrv_close(bs); +} else { +bdrv_unref(bs); +} +} else { +*pbs = bs; +} +return ret; +} + bs-options = options; options = qdict_clone_shallow(options); -- 1.8.5.3
[Qemu-devel] [PATCH 21/21] target-arm: A64: Add FNEG and FABS to the SIMD 2-reg-misc group
Add the SIMD FNEG and FABS instructions in the SIMD 2-reg-misc group. Signed-off-by: Peter Maydell peter.mayd...@linaro.org --- target-arm/translate-a64.c | 23 --- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c index db89327..797e364 100644 --- a/target-arm/translate-a64.c +++ b/target-arm/translate-a64.c @@ -6247,7 +6247,7 @@ static void handle_2misc_64(DisasContext *s, int opcode, bool u, { /* Handle 64-64 opcodes which are shared between the scalar and * vector 2-reg-misc groups. We cover every integer opcode where size == 3 - * is valid in either group. + * is valid in either group and also the double-precision fp ops. */ TCGCond cond; @@ -6285,6 +6285,12 @@ static void handle_2misc_64(DisasContext *s, int opcode, bool u, tcg_temp_free_i64(tcg_zero); } break; +case 0x2f: /* FABS */ +gen_helper_vfp_absd(tcg_rd, tcg_rn); +break; +case 0x6f: /* FNEG */ +gen_helper_vfp_negd(tcg_rd, tcg_rn); +break; default: g_assert_not_reached(); } @@ -7604,6 +7610,13 @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn) opcode |= (extract32(size, 1, 1) 5) | (u 6); size = extract32(size, 0, 1) ? 3 : 2; switch (opcode) { +case 0x2f: /* FABS */ +case 0x6f: /* FNEG */ +if (size == 3 !is_q) { +unallocated_encoding(s); +return; +} +break; case 0x16: /* FCVTN, FCVTN2 */ case 0x17: /* FCVTL, FCVTL2 */ case 0x18: /* FRINTN */ @@ -7615,7 +7628,6 @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn) case 0x2c: /* FCMGT (zero) */ case 0x2d: /* FCMEQ (zero) */ case 0x2e: /* FCMLT (zero) */ -case 0x2f: /* FABS */ case 0x38: /* FRINTP */ case 0x39: /* FRINTZ */ case 0x3a: /* FCVTPS */ @@ -7631,7 +7643,6 @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn) case 0x5d: /* UCVTF */ case 0x6c: /* FCMGE (zero) */ case 0x6d: /* FCMLE (zero) */ -case 0x6f: /* FNEG */ case 0x79: /* FRINTI */ case 0x7a: /* FCVTPU */ case 0x7b: /* FCVTZU */ @@ -7708,6 +7719,12 @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn) tcg_temp_free_i32(tcg_zero); } break; +case 0x2f: /* FABS */ +gen_helper_vfp_abss(tcg_res, tcg_op); +break; +case 0x6f: /* FNEG */ +gen_helper_vfp_negs(tcg_res, tcg_op); +break; default: g_assert_not_reached(); } -- 1.8.5
[Qemu-devel] [PATCH 18/21] target-arm: A64: Implement 2-reg-misc CNT, NOT and RBIT
Implement the 2-reg-misc CNT, NOT and RBIT instructions. Signed-off-by: Peter Maydell peter.mayd...@linaro.org --- target-arm/helper.h| 1 + target-arm/neon_helper.c | 12 target-arm/translate-a64.c | 34 -- 3 files changed, 41 insertions(+), 6 deletions(-) diff --git a/target-arm/helper.h b/target-arm/helper.h index 70872df..a3c507e 100644 --- a/target-arm/helper.h +++ b/target-arm/helper.h @@ -319,6 +319,7 @@ DEF_HELPER_1(neon_cls_s8, i32, i32) DEF_HELPER_1(neon_cls_s16, i32, i32) DEF_HELPER_1(neon_cls_s32, i32, i32) DEF_HELPER_1(neon_cnt_u8, i32, i32) +DEF_HELPER_FLAGS_1(neon_rbit_u8, TCG_CALL_NO_RWG_SE, i32, i32) DEF_HELPER_3(neon_qdmulh_s16, i32, env, i32, i32) DEF_HELPER_3(neon_qrdmulh_s16, i32, env, i32, i32) diff --git a/target-arm/neon_helper.c b/target-arm/neon_helper.c index be6fbd9..b4c8690 100644 --- a/target-arm/neon_helper.c +++ b/target-arm/neon_helper.c @@ -1133,6 +1133,18 @@ uint32_t HELPER(neon_cnt_u8)(uint32_t x) return x; } +/* Reverse bits in each 8 bit word */ +uint32_t HELPER(neon_rbit_u8)(uint32_t x) +{ +x = ((x 0xf0f0f0f0) 4) + | ((x 0x0f0f0f0f) 4); +x = ((x 0x) 3) + | ((x 0x) 1) + | ((x 0x) 1) + | ((x 0x) 3); +return x; +} + #define NEON_QDMULH16(dest, src1, src2, round) do { \ uint32_t tmp = (int32_t)(int16_t) src1 * (int16_t) src2; \ if ((tmp ^ (tmp 1)) SIGNBIT) { \ diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c index d484967..3a3489b 100644 --- a/target-arm/translate-a64.c +++ b/target-arm/translate-a64.c @@ -6250,6 +6250,12 @@ static void handle_2misc_64(DisasContext *s, int opcode, bool u, TCGCond cond; switch (opcode) { +case 0x5: /* NOT */ +/* This opcode is shared with CNT and RBIT but we have earlier + * enforced that size == 3 if and only if this is the NOT insn. + */ +tcg_gen_not_i64(tcg_rd, tcg_rn); +break; case 0xa: /* CMLT */ /* 64 bit integer comparison against zero, result is * test ? (2^64 - 1) : 0. We implement via setcond(!test) and @@ -7413,13 +7419,19 @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn) case 0x1: /* REV16 */ unsupported_encoding(s, insn); return; -case 0x5: /* CNT, NOT, RBIT */ -if ((u == 0 size 0) || -(u == 1 size 1)) { -unallocated_encoding(s); -return; +case 0x5: /* CNT, NOT, RBIT */ +if (u size == 0) { +/* NOT: adjust size so we can use the 64-bits-at-a-time loop. */ +size = 3; +break; +} else if (u size == 1) { +/* RBIT */ +break; +} else if (!u size == 0) { +/* CNT */ +break; } -unsupported_encoding(s, insn); +unallocated_encoding(s); return; case 0x2: /* SADDLP, UADDLP */ case 0x4: /* CLS, CLZ */ @@ -7581,6 +7593,16 @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn) } else { /* Use helpers for 8 and 16 bit elements */ switch (opcode) { +case 0x5: /* CNT, RBIT */ +/* For these two insns size is part of the opcode specifier + * (handled earlier); they always operate on byte elements. + */ +if (u) { +gen_helper_neon_rbit_u8(tcg_res, tcg_op); +} else { +gen_helper_neon_cnt_u8(tcg_res, tcg_op); +} +break; case 0x8: /* CMGT, CMGE */ case 0x9: /* CMEQ, CMLE */ case 0xa: /* CMLT */ -- 1.8.5
[Qemu-devel] [PATCH 09/21] target-arm: A64: Implement SIMD 3-reg-same shift and saturate insns
Implement the SIMD 3-reg-same instructions SQADD, UQADD, SQSUB, UQSUB, SSHL, USHL, SQSHl, UQSHL, SRSHL, URSHL, SQRSHL, UQRSHL; these are all simple calls to existing Neon helpers. We also enable SSHL, USHL, SRSHL and URSHL for the 3-reg-same-scalar category (but not the others because they can have non-size-64 operands and the scalar_3reg_same function doesn't support that yet.) Signed-off-by: Peter Maydell peter.mayd...@linaro.org --- target-arm/translate-a64.c | 134 + 1 file changed, 112 insertions(+), 22 deletions(-) diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c index 6cdb8fc..4a6886d 100644 --- a/target-arm/translate-a64.c +++ b/target-arm/translate-a64.c @@ -74,6 +74,7 @@ typedef struct AArch64DecodeTable { /* Function prototype for gen_ functions for calling Neon helpers */ typedef void NeonGenTwoOpFn(TCGv_i32, TCGv_i32, TCGv_i32); +typedef void NeonGenTwoOpEnvFn(TCGv_i32, TCGv_ptr, TCGv_i32, TCGv_i32); /* initialize TCG globals. */ void a64_translate_init(void) @@ -5766,6 +5767,20 @@ static void handle_3same_64(DisasContext *s, int opcode, bool u, TCGCond cond; switch (opcode) { +case 0x1: /* SQADD */ +if (u) { +gen_helper_neon_qadd_u64(tcg_rd, cpu_env, tcg_rn, tcg_rm); +} else { +gen_helper_neon_qadd_s64(tcg_rd, cpu_env, tcg_rn, tcg_rm); +} +break; +case 0x5: /* SQSUB */ +if (u) { +gen_helper_neon_qsub_u64(tcg_rd, cpu_env, tcg_rn, tcg_rm); +} else { +gen_helper_neon_qsub_s64(tcg_rd, cpu_env, tcg_rn, tcg_rm); +} +break; case 0x6: /* CMGT, CMHI */ /* 64 bit integer comparison, result = test ? (2^64 - 1) : 0. * We implement this using setcond (test) and then negating. @@ -5788,19 +5803,41 @@ static void handle_3same_64(DisasContext *s, int opcode, bool u, tcg_gen_setcondi_i64(TCG_COND_NE, tcg_rd, tcg_rd, 0); tcg_gen_neg_i64(tcg_rd, tcg_rd); break; -case 0x10: /* ADD, SUB */ +case 0x8: /* SSHL, USHL */ if (u) { -tcg_gen_sub_i64(tcg_rd, tcg_rn, tcg_rm); +gen_helper_neon_shl_u64(tcg_rd, tcg_rn, tcg_rm); } else { -tcg_gen_add_i64(tcg_rd, tcg_rn, tcg_rm); +gen_helper_neon_shl_s64(tcg_rd, tcg_rn, tcg_rm); } break; -case 0x1: /* SQADD */ -case 0x5: /* SQSUB */ -case 0x8: /* SSHL, USHL */ case 0x9: /* SQSHL, UQSHL */ +if (u) { +gen_helper_neon_qshl_u64(tcg_rd, cpu_env, tcg_rn, tcg_rm); +} else { +gen_helper_neon_qshl_s64(tcg_rd, cpu_env, tcg_rn, tcg_rm); +} +break; case 0xa: /* SRSHL, URSHL */ +if (u) { +gen_helper_neon_rshl_u64(tcg_rd, tcg_rn, tcg_rm); +} else { +gen_helper_neon_rshl_s64(tcg_rd, tcg_rn, tcg_rm); +} +break; case 0xb: /* SQRSHL, UQRSHL */ +if (u) { +gen_helper_neon_qrshl_u64(tcg_rd, cpu_env, tcg_rn, tcg_rm); +} else { +gen_helper_neon_qrshl_s64(tcg_rd, cpu_env, tcg_rn, tcg_rm); +} +break; +case 0x10: /* ADD, SUB */ +if (u) { +tcg_gen_sub_i64(tcg_rd, tcg_rn, tcg_rm); +} else { +tcg_gen_add_i64(tcg_rd, tcg_rn, tcg_rm); +} +break; default: g_assert_not_reached(); } @@ -5977,10 +6014,10 @@ static void disas_simd_scalar_three_reg_same(DisasContext *s, uint32_t insn) switch (opcode) { case 0x1: /* SQADD, UQADD */ case 0x5: /* SQSUB, UQSUB */ -case 0x8: /* SSHL, USHL */ -case 0xa: /* SRSHL, URSHL */ unsupported_encoding(s, insn); return; +case 0x8: /* SSHL, USHL */ +case 0xa: /* SRSHL, URSHL */ case 0x6: /* CMGT, CMHI */ case 0x7: /* CMGE, CMHS */ case 0x11: /* CMTST, CMEQ */ @@ -6649,18 +6686,6 @@ static void disas_simd_3same_int(DisasContext *s, uint32_t insn) } unsupported_encoding(s, insn); return; -case 0x1: /* SQADD */ -case 0x5: /* SQSUB */ -case 0x8: /* SSHL, USHL */ -case 0x9: /* SQSHL, UQSHL */ -case 0xa: /* SRSHL, URSHL */ -case 0xb: /* SQRSHL, UQRSHL */ -if (size == 3 !is_q) { -unallocated_encoding(s); -return; -} -unsupported_encoding(s, insn); -return; case 0x16: /* SQDMULH, SQRDMULH */ if (size == 0 || size == 3) { unallocated_encoding(s); @@ -6698,12 +6723,33 @@ static void disas_simd_3same_int(DisasContext *s, uint32_t insn) TCGv_i32 tcg_op1 = tcg_temp_new_i32(); TCGv_i32 tcg_op2 = tcg_temp_new_i32(); TCGv_i32 tcg_res = tcg_temp_new_i32(); -NeonGenTwoOpFn *genfn; +NeonGenTwoOpFn *genfn = NULL; +NeonGenTwoOpEnvFn *genenvfn = NULL; read_vec_element_i32(s, tcg_op1, rn, pass,
[Qemu-devel] [PATCH 00/21] A64: Add Neon instructions, second and third sets
This patch series is kind of in two parts. The first 8 patches are the Neon second set that's already been pretty much reviewed; I'm resending them just because there were a few minor nits that came up in the last round which have been fixed: * patch 6 added the missing SQDMULH/SQRDMULH unallocated/unimplemented case in the SIMD 3-same initial decode * patch 7 now uses the _i32 vector element accessors * patch 8 fixed a few codestyle nits (RTH: these all seemed trivial enough that I've left your reviewed-by tags in place). Patches 9..21 are new, and fill in a number of gaps that bring us up to (and past) parity with the SuSE tree for coverage: * more SIMD 3-same ops, including basically all the integer ones * the scalar pairwise instruction group * more SIMD scalar-3-same ops, including all the integer ones * some (but not all) of the 2-reg misc and scalar 2-reg misc groups (by the same rationale as with 3-same, we aim for anything implemented in the SuSE tree plus enough to make it reasonably likely we've got the general function structure correct) thanks -- PMM Alex Bennée (2): target-arm: A64: Add SIMD shift by immediate target-arm: A64: Add 2-reg-misc REV* instructions Peter Maydell (19): target-arm: A64: Add SIMD three-different multiply accumulate insns target-arm: A64: Add SIMD three-different ABDL instructions target-arm: A64: Add SIMD scalar 3 same add, sub and compare ops target-arm: A64: Add top level decode for SIMD 3-same group target-arm: A64: Add logic ops from SIMD 3 same group target-arm: A64: Add integer ops from SIMD 3-same group target-arm: A64: Add simple SIMD 3-same floating point ops target-arm: A64: Implement SIMD 3-reg-same shift and saturate insns target-arm: A64: Implement remaining non-pairwise int SIMD 3-reg-same insns target-arm: A64: Implement pairwise integer ops from 3-reg-same SIMD tcg: Add TCGV_UNUSED_PTR, TCGV_IS_UNUSED_PTR, TCGV_EQUAL_PTR target-arm: A64: Implement scalar pairwise ops target-arm: A64: Implement remaining integer scalar-3-same insns target-arm: A64: Add SIMD simple 64 bit insns from scalar 2-reg misc target-arm: A64: Add skeleton decode for SIMD 2-reg misc group target-arm: A64: Implement 2-register misc compares, ABS, NEG target-arm: A64: Implement 2-reg-misc CNT, NOT and RBIT target-arm: A64: Add narrowing 2-reg-misc instructions target-arm: A64: Add FNEG and FABS to the SIMD 2-reg-misc group target-arm/helper.h|1 + target-arm/neon_helper.c | 12 + target-arm/translate-a64.c | 2341 ++-- tcg/tcg.h |3 + 4 files changed, 2299 insertions(+), 58 deletions(-) -- 1.8.5
[Qemu-devel] [PATCH 13/21] target-arm: A64: Implement scalar pairwise ops
Implement the instructions in the scalar pairwise group (C3.6.8). Signed-off-by: Peter Maydell peter.mayd...@linaro.org --- target-arm/translate-a64.c | 114 - 1 file changed, 113 insertions(+), 1 deletion(-) diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c index 81119a0..881e9eb 100644 --- a/target-arm/translate-a64.c +++ b/target-arm/translate-a64.c @@ -5529,7 +5529,119 @@ static void disas_simd_scalar_copy(DisasContext *s, uint32_t insn) */ static void disas_simd_scalar_pairwise(DisasContext *s, uint32_t insn) { -unsupported_encoding(s, insn); +int u = extract32(insn, 29, 1); +int size = extract32(insn, 22, 2); +int opcode = extract32(insn, 12, 5); +int rn = extract32(insn, 5, 5); +int rd = extract32(insn, 0, 5); +TCGv_ptr fpst; + +/* For some ops (the FP ones), size[1] is part of the encoding. + * For ADDP strictly it is not but size[1] is always 1 for valid + * encodings. + */ +opcode |= (extract32(size, 1, 1) 5); + +switch (opcode) { +case 0x3b: /* ADDP */ +if (u || size != 3) { +unallocated_encoding(s); +return; +} +TCGV_UNUSED_PTR(fpst); +break; +case 0xc: /* FMAXNMP */ +case 0xd: /* FADDP */ +case 0xf: /* FMAXP */ +case 0x2c: /* FMINNMP */ +case 0x2f: /* FMINP */ +/* FP op, size[0] is 32 or 64 bit */ +if (!u) { +unallocated_encoding(s); +return; +} +size = extract32(size, 0, 1) ? 3 : 2; +fpst = get_fpstatus_ptr(); +break; +default: +unallocated_encoding(s); +return; +} + +if (size == 3) { +TCGv_i64 tcg_op1 = tcg_temp_new_i64(); +TCGv_i64 tcg_op2 = tcg_temp_new_i64(); +TCGv_i64 tcg_res = tcg_temp_new_i64(); + +read_vec_element(s, tcg_op1, rn, 0, MO_64); +read_vec_element(s, tcg_op2, rn, 1, MO_64); + +switch (opcode) { +case 0x3b: /* ADDP */ +tcg_gen_add_i64(tcg_res, tcg_op1, tcg_op2); +break; +case 0xc: /* FMAXNMP */ +gen_helper_vfp_maxnumd(tcg_res, tcg_op1, tcg_op2, fpst); +break; +case 0xd: /* FADDP */ +gen_helper_vfp_addd(tcg_res, tcg_op1, tcg_op2, fpst); +break; +case 0xf: /* FMAXP */ +gen_helper_vfp_maxd(tcg_res, tcg_op1, tcg_op2, fpst); +break; +case 0x2c: /* FMINNMP */ +gen_helper_vfp_minnumd(tcg_res, tcg_op1, tcg_op2, fpst); +break; +case 0x2f: /* FMINP */ +gen_helper_vfp_mind(tcg_res, tcg_op1, tcg_op2, fpst); +break; +default: +g_assert_not_reached(); +} + +write_fp_dreg(s, rd, tcg_res); + +tcg_temp_free_i64(tcg_op1); +tcg_temp_free_i64(tcg_op2); +tcg_temp_free_i64(tcg_res); +} else { +TCGv_i32 tcg_op1 = tcg_temp_new_i32(); +TCGv_i32 tcg_op2 = tcg_temp_new_i32(); +TCGv_i32 tcg_res = tcg_temp_new_i32(); + +read_vec_element_i32(s, tcg_op1, rn, 0, MO_32); +read_vec_element_i32(s, tcg_op2, rn, 1, MO_32); + +switch (opcode) { +case 0xc: /* FMAXNMP */ +gen_helper_vfp_maxnums(tcg_res, tcg_op1, tcg_op2, fpst); +break; +case 0xd: /* FADDP */ +gen_helper_vfp_adds(tcg_res, tcg_op1, tcg_op2, fpst); +break; +case 0xf: /* FMAXP */ +gen_helper_vfp_maxs(tcg_res, tcg_op1, tcg_op2, fpst); +break; +case 0x2c: /* FMINNMP */ +gen_helper_vfp_minnums(tcg_res, tcg_op1, tcg_op2, fpst); +break; +case 0x2f: /* FMINP */ +gen_helper_vfp_mins(tcg_res, tcg_op1, tcg_op2, fpst); +break; +default: +g_assert_not_reached(); +} + +write_fp_sreg(s, rd, tcg_res); + +tcg_temp_free_i32(tcg_op1); +tcg_temp_free_i32(tcg_op2); +tcg_temp_free_i32(tcg_res); +} + +if (!TCGV_IS_UNUSED_PTR(fpst)) { +tcg_temp_free_ptr(fpst); +} } /* -- 1.8.5
[Qemu-devel] [PATCH 02/21] target-arm: A64: Add SIMD three-different ABDL instructions
Implement the absolute-difference instructions in the SIMD three-different group: SABAL, SABAL2, UABAL, UABAL2, SABDL, SABDL2, UABDL, UABDL2. Signed-off-by: Peter Maydell peter.mayd...@linaro.org Reviewed-by: Richard Henderson r...@twiddle.net --- target-arm/translate-a64.c | 35 +-- 1 file changed, 33 insertions(+), 2 deletions(-) diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c index 924a539..145125e 100644 --- a/target-arm/translate-a64.c +++ b/target-arm/translate-a64.c @@ -5630,6 +5630,21 @@ static void handle_3rd_widening(DisasContext *s, int is_q, int is_u, int size, } switch (opcode) { +case 5: /* SABAL, SABAL2, UABAL, UABAL2 */ +case 7: /* SABDL, SABDL2, UABDL, UABDL2 */ +{ +TCGv_i64 tcg_tmp1 = tcg_temp_new_i64(); +TCGv_i64 tcg_tmp2 = tcg_temp_new_i64(); + +tcg_gen_sub_i64(tcg_tmp1, tcg_op1, tcg_op2); +tcg_gen_sub_i64(tcg_tmp2, tcg_op2, tcg_op1); +tcg_gen_movcond_i64(is_u ? TCG_COND_GEU : TCG_COND_GE, +tcg_passres, +tcg_op1, tcg_op2, tcg_tmp1, tcg_tmp2); +tcg_temp_free_i64(tcg_tmp1); +tcg_temp_free_i64(tcg_tmp2); +break; +} case 8: /* SMLAL, SMLAL2, UMLAL, UMLAL2 */ case 10: /* SMLSL, SMLSL2, UMLSL, UMLSL2 */ case 12: /* UMULL, UMULL2, SMULL, SMULL2 */ @@ -5668,6 +5683,22 @@ static void handle_3rd_widening(DisasContext *s, int is_q, int is_u, int size, } switch (opcode) { +case 5: /* SABAL, SABAL2, UABAL, UABAL2 */ +case 7: /* SABDL, SABDL2, UABDL, UABDL2 */ +if (size == 0) { +if (is_u) { +gen_helper_neon_abdl_u16(tcg_passres, tcg_op1, tcg_op2); +} else { +gen_helper_neon_abdl_s16(tcg_passres, tcg_op1, tcg_op2); +} +} else { +if (is_u) { +gen_helper_neon_abdl_u32(tcg_passres, tcg_op1, tcg_op2); +} else { +gen_helper_neon_abdl_s32(tcg_passres, tcg_op1, tcg_op2); +} +} +break; case 8: /* SMLAL, SMLAL2, UMLAL, UMLAL2 */ case 10: /* SMLSL, SMLSL2, UMLSL, UMLSL2 */ case 12: /* UMULL, UMULL2, SMULL, SMULL2 */ @@ -5767,10 +5798,10 @@ static void disas_simd_three_reg_diff(DisasContext *s, uint32_t insn) /* fall through */ case 0: case 2: -case 5: -case 7: unsupported_encoding(s, insn); break; +case 5: +case 7: case 8: case 10: case 12: -- 1.8.5
[Qemu-devel] [PATCH 05/21] target-arm: A64: Add logic ops from SIMD 3 same group
Add support for the logical operations (ORR, AND, BIC, ORN, EOR, BSL, BIT and BIF) from the SIMD 3 register same group (C3.6.16). Signed-off-by: Alex Bennée alex.ben...@linaro.org Signed-off-by: Peter Maydell peter.mayd...@linaro.org Reviewed-by: Richard Henderson r...@twiddle.net --- target-arm/translate-a64.c | 73 +- 1 file changed, 72 insertions(+), 1 deletion(-) diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c index 2079c96..4767cbf 100644 --- a/target-arm/translate-a64.c +++ b/target-arm/translate-a64.c @@ -5951,7 +5951,78 @@ static void disas_simd_three_reg_diff(DisasContext *s, uint32_t insn) /* Logic op (opcode == 3) subgroup of C3.6.16. */ static void disas_simd_3same_logic(DisasContext *s, uint32_t insn) { -unsupported_encoding(s, insn); +int rd = extract32(insn, 0, 5); +int rn = extract32(insn, 5, 5); +int rm = extract32(insn, 16, 5); +int size = extract32(insn, 22, 2); +bool is_u = extract32(insn, 29, 1); +bool is_q = extract32(insn, 30, 1); +TCGv_i64 tcg_op1 = tcg_temp_new_i64(); +TCGv_i64 tcg_op2 = tcg_temp_new_i64(); +TCGv_i64 tcg_res[2]; +int pass; + +tcg_res[0] = tcg_temp_new_i64(); +tcg_res[1] = tcg_temp_new_i64(); + +for (pass = 0; pass (is_q ? 2 : 1); pass++) { +read_vec_element(s, tcg_op1, rn, pass, MO_64); +read_vec_element(s, tcg_op2, rm, pass, MO_64); + +if (!is_u) { +switch (size) { +case 0: /* AND */ +tcg_gen_and_i64(tcg_res[pass], tcg_op1, tcg_op2); +break; +case 1: /* BIC */ +tcg_gen_andc_i64(tcg_res[pass], tcg_op1, tcg_op2); +break; +case 2: /* ORR */ +tcg_gen_or_i64(tcg_res[pass], tcg_op1, tcg_op2); +break; +case 3: /* ORN */ +tcg_gen_orc_i64(tcg_res[pass], tcg_op1, tcg_op2); +break; +} +} else { +if (size != 0) { +/* B* ops need res loaded to operate on */ +read_vec_element(s, tcg_res[pass], rd, pass, MO_64); +} + +switch (size) { +case 0: /* EOR */ +tcg_gen_xor_i64(tcg_res[pass], tcg_op1, tcg_op2); +break; +case 1: /* BSL bitwise select */ +tcg_gen_xor_i64(tcg_op1, tcg_op1, tcg_op2); +tcg_gen_and_i64(tcg_op1, tcg_op1, tcg_res[pass]); +tcg_gen_xor_i64(tcg_res[pass], tcg_op2, tcg_op1); +break; +case 2: /* BIT, bitwise insert if true */ +tcg_gen_xor_i64(tcg_op1, tcg_op1, tcg_res[pass]); +tcg_gen_and_i64(tcg_op1, tcg_op1, tcg_op2); +tcg_gen_xor_i64(tcg_res[pass], tcg_res[pass], tcg_op1); +break; +case 3: /* BIF, bitwise insert if false */ +tcg_gen_xor_i64(tcg_op1, tcg_op1, tcg_res[pass]); +tcg_gen_andc_i64(tcg_op1, tcg_op1, tcg_op2); +tcg_gen_xor_i64(tcg_res[pass], tcg_res[pass], tcg_op1); +break; +} +} +} + +write_vec_element(s, tcg_res[0], rd, 0, MO_64); +if (!is_q) { +tcg_gen_movi_i64(tcg_res[1], 0); +} +write_vec_element(s, tcg_res[1], rd, 1, MO_64); + +tcg_temp_free_i64(tcg_op1); +tcg_temp_free_i64(tcg_op2); +tcg_temp_free_i64(tcg_res[0]); +tcg_temp_free_i64(tcg_res[1]); } /* Pairwise op subgroup of C3.6.16. */ -- 1.8.5
[Qemu-devel] [PATCH 10/21] target-arm: A64: Implement remaining non-pairwise int SIMD 3-reg-same insns
Implement the SIMD 3-reg-same instructions where the size == 3 case is reserved: SHADD, UHADD, SRHADD, URHADD, SHSUB, UHSUB, SMAX, UMAX, SMIN, UMIN, SABD, UABD, SABA, UABA, MLA, MLS, MUL, PMUL, SQRDMULH, SQDMULH. (None of these have scalar-3-same versions.) This completes the non-pairwise integer instructions in this category. Signed-off-by: Peter Maydell peter.mayd...@linaro.org --- target-arm/translate-a64.c | 134 +++-- 1 file changed, 118 insertions(+), 16 deletions(-) diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c index 4a6886d..515c72b 100644 --- a/target-arm/translate-a64.c +++ b/target-arm/translate-a64.c @@ -6684,15 +6684,13 @@ static void disas_simd_3same_int(DisasContext *s, uint32_t insn) unallocated_encoding(s); return; } -unsupported_encoding(s, insn); -return; +break; case 0x16: /* SQDMULH, SQRDMULH */ if (size == 0 || size == 3) { unallocated_encoding(s); return; } -unsupported_encoding(s, insn); -return; +break; default: if (size == 3 !is_q) { unallocated_encoding(s); @@ -6730,6 +6728,16 @@ static void disas_simd_3same_int(DisasContext *s, uint32_t insn) read_vec_element_i32(s, tcg_op2, rm, pass, MO_32); switch (opcode) { +case 0x0: /* SHADD, UHADD */ +{ +static NeonGenTwoOpFn * const fns[3][2] = { +{ gen_helper_neon_hadd_s8, gen_helper_neon_hadd_u8 }, +{ gen_helper_neon_hadd_s16, gen_helper_neon_hadd_u16 }, +{ gen_helper_neon_hadd_s32, gen_helper_neon_hadd_u32 }, +}; +genfn = fns[size][u]; +break; +} case 0x1: /* SQADD, UQADD */ { static NeonGenTwoOpEnvFn * const fns[3][2] = { @@ -6740,6 +6748,26 @@ static void disas_simd_3same_int(DisasContext *s, uint32_t insn) genenvfn = fns[size][u]; break; } +case 0x2: /* SRHADD, URHADD */ +{ +static NeonGenTwoOpFn * const fns[3][2] = { +{ gen_helper_neon_rhadd_s8, gen_helper_neon_rhadd_u8 }, +{ gen_helper_neon_rhadd_s16, gen_helper_neon_rhadd_u16 }, +{ gen_helper_neon_rhadd_s32, gen_helper_neon_rhadd_u32 }, +}; +genfn = fns[size][u]; +break; +} +case 0x4: /* SHSUB, UHSUB */ +{ +static NeonGenTwoOpFn * const fns[3][2] = { +{ gen_helper_neon_hsub_s8, gen_helper_neon_hsub_u8 }, +{ gen_helper_neon_hsub_s16, gen_helper_neon_hsub_u16 }, +{ gen_helper_neon_hsub_s32, gen_helper_neon_hsub_u32 }, +}; +genfn = fns[size][u]; +break; +} case 0x5: /* SQSUB, UQSUB */ { static NeonGenTwoOpEnvFn * const fns[3][2] = { @@ -6773,9 +6801,9 @@ static void disas_simd_3same_int(DisasContext *s, uint32_t insn) case 0x8: /* SSHL, USHL */ { static NeonGenTwoOpFn * const fns[3][2] = { -{ gen_helper_neon_shl_u8, gen_helper_neon_shl_s8 }, -{ gen_helper_neon_shl_u16, gen_helper_neon_shl_s16 }, -{ gen_helper_neon_shl_u32, gen_helper_neon_shl_s32 }, +{ gen_helper_neon_shl_s8, gen_helper_neon_shl_u8 }, +{ gen_helper_neon_shl_s16, gen_helper_neon_shl_u16 }, +{ gen_helper_neon_shl_s32, gen_helper_neon_shl_u32 }, }; genfn = fns[size][u]; break; @@ -6783,9 +6811,9 @@ static void disas_simd_3same_int(DisasContext *s, uint32_t insn) case 0x9: /* SQSHL, UQSHL */ { static NeonGenTwoOpEnvFn * const fns[3][2] = { -{ gen_helper_neon_qshl_u8, gen_helper_neon_qshl_s8 }, -{ gen_helper_neon_qshl_u16, gen_helper_neon_qshl_s16 }, -{ gen_helper_neon_qshl_u32, gen_helper_neon_qshl_s32 }, +{ gen_helper_neon_qshl_s8, gen_helper_neon_qshl_u8 }, +{ gen_helper_neon_qshl_s16, gen_helper_neon_qshl_u16 }, +{ gen_helper_neon_qshl_s32, gen_helper_neon_qshl_u32 }, }; genenvfn = fns[size][u]; break; @@ -6793,9 +6821,9 @@ static void disas_simd_3same_int(DisasContext *s, uint32_t insn) case 0xa: /* SRSHL, URSHL */ { static NeonGenTwoOpFn * const fns[3][2] = { -{ gen_helper_neon_rshl_u8, gen_helper_neon_rshl_s8 }, -{ gen_helper_neon_rshl_u16,
[Qemu-devel] [PATCH 01/21] target-arm: A64: Add SIMD three-different multiply accumulate insns
Add support for the multiply-accumulate instructions from the SIMD three-different instructions group (C3.6.15): * skeleton decode of unallocated encodings and split of the group into its three sub-parts * framework for handling the 64x64-128 widening subpart * implementation of the multiply-accumulate instructions SMLAL, SMLAL2, UMLAL, UMLAL2, SMLSL, SMLSL2, UMLSL, UMLSL2, UMULL, UMULL2, SMULL, SMULL2 Signed-off-by: Peter Maydell peter.mayd...@linaro.org Reviewed-by: Richard Henderson r...@twiddle.net --- target-arm/translate-a64.c | 233 - 1 file changed, 232 insertions(+), 1 deletion(-) diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c index 7cfb55b..924a539 100644 --- a/target-arm/translate-a64.c +++ b/target-arm/translate-a64.c @@ -700,6 +700,9 @@ static void do_fp_ld(DisasContext *s, int destidx, TCGv_i64 tcg_addr, int size) * zero extend as we are filling a partial chunk of the vector register. * These functions don't support 128 bit loads/stores, which would be * normal load/store operations. + * + * The _i32 versions are useful when operating on 32 bit quantities + * (eg for floating point single or using Neon helper functions). */ /* Get value of an element within a vector register */ @@ -735,6 +738,32 @@ static void read_vec_element(DisasContext *s, TCGv_i64 tcg_dest, int srcidx, } } +static void read_vec_element_i32(DisasContext *s, TCGv_i32 tcg_dest, int srcidx, + int element, TCGMemOp memop) +{ +int vect_off = vec_reg_offset(srcidx, element, memop MO_SIZE); +switch (memop) { +case MO_8: +tcg_gen_ld8u_i32(tcg_dest, cpu_env, vect_off); +break; +case MO_16: +tcg_gen_ld16u_i32(tcg_dest, cpu_env, vect_off); +break; +case MO_8|MO_SIGN: +tcg_gen_ld8s_i32(tcg_dest, cpu_env, vect_off); +break; +case MO_16|MO_SIGN: +tcg_gen_ld16s_i32(tcg_dest, cpu_env, vect_off); +break; +case MO_32: +case MO_32|MO_SIGN: +tcg_gen_ld_i32(tcg_dest, cpu_env, vect_off); +break; +default: +g_assert_not_reached(); +} +} + /* Set value of an element within a vector register */ static void write_vec_element(DisasContext *s, TCGv_i64 tcg_src, int destidx, int element, TCGMemOp memop) @@ -5546,6 +5575,150 @@ static void disas_simd_shift_imm(DisasContext *s, uint32_t insn) unsupported_encoding(s, insn); } +static void handle_3rd_widening(DisasContext *s, int is_q, int is_u, int size, +int opcode, int rd, int rn, int rm) +{ +/* 3-reg-different widening insns: 64 x 64 - 128 */ +TCGv_i64 tcg_res[2]; +int pass, accop; + +tcg_res[0] = tcg_temp_new_i64(); +tcg_res[1] = tcg_temp_new_i64(); + +/* Does this op do an adding accumulate, a subtracting accumulate, + * or no accumulate at all? + */ +switch (opcode) { +case 5: +case 8: +case 9: +accop = 1; +break; +case 10: +case 11: +accop = -1; +break; +default: +accop = 0; +break; +} + +if (accop != 0) { +read_vec_element(s, tcg_res[0], rd, 0, MO_64); +read_vec_element(s, tcg_res[1], rd, 1, MO_64); +} + +/* size == 2 means two 32x32-64 operations; this is worth special + * casing because we can generally handle it inline. + */ +if (size == 2) { +for (pass = 0; pass 2; pass++) { +TCGv_i64 tcg_op1 = tcg_temp_new_i64(); +TCGv_i64 tcg_op2 = tcg_temp_new_i64(); +TCGv_i64 tcg_passres; +TCGMemOp memop = MO_32 | (is_u ? 0 : MO_SIGN); + +int elt = pass + is_q * 2; + +read_vec_element(s, tcg_op1, rn, elt, memop); +read_vec_element(s, tcg_op2, rm, elt, memop); + +if (accop == 0) { +tcg_passres = tcg_res[pass]; +} else { +tcg_passres = tcg_temp_new_i64(); +} + +switch (opcode) { +case 8: /* SMLAL, SMLAL2, UMLAL, UMLAL2 */ +case 10: /* SMLSL, SMLSL2, UMLSL, UMLSL2 */ +case 12: /* UMULL, UMULL2, SMULL, SMULL2 */ +tcg_gen_mul_i64(tcg_passres, tcg_op1, tcg_op2); +break; +default: +g_assert_not_reached(); +} + +if (accop 0) { +tcg_gen_add_i64(tcg_res[pass], tcg_res[pass], tcg_passres); +tcg_temp_free_i64(tcg_passres); +} else if (accop 0) { +tcg_gen_sub_i64(tcg_res[pass], tcg_res[pass], tcg_passres); +tcg_temp_free_i64(tcg_passres); +} + +tcg_temp_free_i64(tcg_op1); +tcg_temp_free_i64(tcg_op2); +} +} else { +/* size 0 or 1, generally helper functions */ +for (pass = 0; pass 2; pass++) { +
[Qemu-devel] [PATCH 07/21] target-arm: A64: Add simple SIMD 3-same floating point ops
Implement a simple subset of the SIMD 3-same floating point operations. This includes a common helper function used for both scalar and vector ops; FABD is the only currently implemented shared op. Signed-off-by: Peter Maydell peter.mayd...@linaro.org Reviewed-by: Richard Henderson r...@twiddle.net --- target-arm/translate-a64.c | 190 - 1 file changed, 188 insertions(+), 2 deletions(-) diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c index 3934bce..966e502 100644 --- a/target-arm/translate-a64.c +++ b/target-arm/translate-a64.c @@ -5605,6 +5605,131 @@ static void handle_3same_64(DisasContext *s, int opcode, bool u, } } +/* Handle the 3-same-operands float operations; shared by the scalar + * and vector encodings. The caller must filter out any encodings + * not allocated for the encoding it is dealing with. + */ +static void handle_3same_float(DisasContext *s, int size, int elements, + int fpopcode, int rd, int rn, int rm) +{ +int pass; +TCGv_ptr fpst = get_fpstatus_ptr(); + +for (pass = 0; pass elements; pass++) { +if (size) { +/* Double */ +TCGv_i64 tcg_op1 = tcg_temp_new_i64(); +TCGv_i64 tcg_op2 = tcg_temp_new_i64(); +TCGv_i64 tcg_res = tcg_temp_new_i64(); + +read_vec_element(s, tcg_op1, rn, pass, MO_64); +read_vec_element(s, tcg_op2, rm, pass, MO_64); + +switch (fpopcode) { +case 0x18: /* FMAXNM */ +gen_helper_vfp_maxnumd(tcg_res, tcg_op1, tcg_op2, fpst); +break; +case 0x1a: /* FADD */ +gen_helper_vfp_addd(tcg_res, tcg_op1, tcg_op2, fpst); +break; +case 0x1e: /* FMAX */ +gen_helper_vfp_maxd(tcg_res, tcg_op1, tcg_op2, fpst); +break; +case 0x38: /* FMINNM */ +gen_helper_vfp_minnumd(tcg_res, tcg_op1, tcg_op2, fpst); +break; +case 0x3a: /* FSUB */ +gen_helper_vfp_subd(tcg_res, tcg_op1, tcg_op2, fpst); +break; +case 0x3e: /* FMIN */ +gen_helper_vfp_mind(tcg_res, tcg_op1, tcg_op2, fpst); +break; +case 0x5b: /* FMUL */ +gen_helper_vfp_muld(tcg_res, tcg_op1, tcg_op2, fpst); +break; +case 0x5f: /* FDIV */ +gen_helper_vfp_divd(tcg_res, tcg_op1, tcg_op2, fpst); +break; +case 0x7a: /* FABD */ +gen_helper_vfp_subd(tcg_res, tcg_op1, tcg_op2, fpst); +gen_helper_vfp_absd(tcg_res, tcg_res); +break; +default: +g_assert_not_reached(); +} + +write_vec_element(s, tcg_res, rd, pass, MO_64); + +tcg_temp_free_i64(tcg_res); +tcg_temp_free_i64(tcg_op1); +tcg_temp_free_i64(tcg_op2); +} else { +/* Single */ +TCGv_i32 tcg_op1 = tcg_temp_new_i32(); +TCGv_i32 tcg_op2 = tcg_temp_new_i32(); +TCGv_i32 tcg_res = tcg_temp_new_i32(); + +read_vec_element_i32(s, tcg_op1, rn, pass, MO_32); +read_vec_element_i32(s, tcg_op2, rm, pass, MO_32); + +switch (fpopcode) { +case 0x1a: /* FADD */ +gen_helper_vfp_adds(tcg_res, tcg_op1, tcg_op2, fpst); +break; +case 0x1e: /* FMAX */ +gen_helper_vfp_maxs(tcg_res, tcg_op1, tcg_op2, fpst); +break; +case 0x18: /* FMAXNM */ +gen_helper_vfp_maxnums(tcg_res, tcg_op1, tcg_op2, fpst); +break; +case 0x38: /* FMINNM */ +gen_helper_vfp_minnums(tcg_res, tcg_op1, tcg_op2, fpst); +break; +case 0x3a: /* FSUB */ +gen_helper_vfp_subs(tcg_res, tcg_op1, tcg_op2, fpst); +break; +case 0x3e: /* FMIN */ +gen_helper_vfp_mins(tcg_res, tcg_op1, tcg_op2, fpst); +break; +case 0x5b: /* FMUL */ +gen_helper_vfp_muls(tcg_res, tcg_op1, tcg_op2, fpst); +break; +case 0x5f: /* FDIV */ +gen_helper_vfp_divs(tcg_res, tcg_op1, tcg_op2, fpst); +break; +case 0x7a: /* FABD */ +gen_helper_vfp_subs(tcg_res, tcg_op1, tcg_op2, fpst); +gen_helper_vfp_abss(tcg_res, tcg_res); +break; +default: +g_assert_not_reached(); +} + +if (elements == 1) { +/* scalar single so clear high part */ +TCGv_i64 tcg_tmp = tcg_temp_new_i64(); + +tcg_gen_extu_i32_i64(tcg_tmp, tcg_res); +write_vec_element(s, tcg_tmp, rd, pass, MO_64); +
[Qemu-devel] [PATCH 15/21] target-arm: A64: Add SIMD simple 64 bit insns from scalar 2-reg misc
Implement the simple 64 bit integer operations from the SIMD scalar 2-register misc group (C3.6.12): the comparisons against zero, plus ABS and NEG. Signed-off-by: Peter Maydell peter.mayd...@linaro.org --- target-arm/translate-a64.c | 87 +- 1 file changed, 86 insertions(+), 1 deletion(-) diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c index 8a2f311..f784602 100644 --- a/target-arm/translate-a64.c +++ b/target-arm/translate-a64.c @@ -6240,6 +6240,48 @@ static void disas_simd_scalar_three_reg_same(DisasContext *s, uint32_t insn) tcg_temp_free_i64(tcg_rd); } +static void handle_2misc_64(DisasContext *s, int opcode, bool u, +TCGv_i64 tcg_rd, TCGv_i64 tcg_rn) +{ +/* Handle 64-64 opcodes which are shared between the scalar and + * vector 2-reg-misc groups. We cover every integer opcode where size == 3 + * is valid in either group. + */ +TCGCond cond; + +switch (opcode) { +case 0xa: /* CMLT */ +/* 64 bit integer comparison against zero, result is + * test ? (2^64 - 1) : 0. We implement via setcond(!test) and + * subtracting 1. + */ +cond = TCG_COND_LT; +do_cmop: +tcg_gen_setcondi_i64(tcg_invert_cond(cond), tcg_rd, tcg_rn, 0); +tcg_gen_subi_i64(tcg_rd, tcg_rd, 1); +break; +case 0x8: /* CMGT, CMGE */ +cond = u ? TCG_COND_GE : TCG_COND_GT; +goto do_cmop; +case 0x9: /* CMEQ, CMLE */ +cond = u ? TCG_COND_LE : TCG_COND_EQ; +goto do_cmop; +case 0xb: /* ABS, NEG */ +if (u) { +tcg_gen_neg_i64(tcg_rd, tcg_rn); +} else { +TCGv_i64 tcg_zero = tcg_const_i64(0); +tcg_gen_neg_i64(tcg_rd, tcg_rn); +tcg_gen_movcond_i64(TCG_COND_GT, tcg_rd, tcg_rn, tcg_zero, +tcg_rn, tcg_rd); +tcg_temp_free_i64(tcg_zero); +} +break; +default: +g_assert_not_reached(); +} +} + /* C3.6.12 AdvSIMD scalar two reg misc * 31 30 29 28 24 23 22 21 17 1612 11 10 95 40 * +-+---+---+--+---++-+--+--+ @@ -6248,7 +6290,50 @@ static void disas_simd_scalar_three_reg_same(DisasContext *s, uint32_t insn) */ static void disas_simd_scalar_two_reg_misc(DisasContext *s, uint32_t insn) { -unsupported_encoding(s, insn); +int rd = extract32(insn, 0, 5); +int rn = extract32(insn, 5, 5); +int opcode = extract32(insn, 12, 5); +int size = extract32(insn, 22, 2); +bool u = extract32(insn, 29, 1); + +switch (opcode) { +case 0xa: /* CMLT */ +if (u) { +unallocated_encoding(s); +return; +} +/* fall through */ +case 0x8: /* CMGT, CMGE */ +case 0x9: /* CMEQ, CMLE */ +case 0xb: /* ABS, NEG */ +if (size != 3) { +unallocated_encoding(s); +return; +} +break; +default: +/* Other categories of encoding in this class: + * + floating point (single and double) + * + SUQADD/USQADD/SQABS/SQNEG : size 8, 16, 32 or 64 + * + SQXTN/SQXTN2/SQXTUN/SQXTUN2/UQXTN/UQXTN2: + *narrowing saturate ops: size 64/32/16 - 32/16/8 + */ +unsupported_encoding(s, insn); +return; +} + +if (size == 3) { +TCGv_i64 tcg_rn = read_fp_dreg(s, rn); +TCGv_i64 tcg_rd = tcg_temp_new_i64(); + +handle_2misc_64(s, opcode, u, tcg_rd, tcg_rn); +write_fp_dreg(s, rd, tcg_rd); +tcg_temp_free_i64(tcg_rd); +tcg_temp_free_i64(tcg_rn); +} else { +/* the 'size might not be 64' ops aren't implemented yet */ +g_assert_not_reached(); +} } /* C3.6.13 AdvSIMD scalar x indexed element -- 1.8.5
[Qemu-devel] [PATCH 11/21] target-arm: A64: Implement pairwise integer ops from 3-reg-same SIMD
Implement the pairwise integer operations in the 3-reg-same SIMD group: ADDP, SMAXP, SMINP, UMAXP and UMINP. Signed-off-by: Peter Maydell peter.mayd...@linaro.org --- target-arm/translate-a64.c | 145 - 1 file changed, 144 insertions(+), 1 deletion(-) diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c index 515c72b..81119a0 100644 --- a/target-arm/translate-a64.c +++ b/target-arm/translate-a64.c @@ -6584,10 +6584,153 @@ static void disas_simd_3same_logic(DisasContext *s, uint32_t insn) tcg_temp_free_i64(tcg_res[1]); } +/* Helper functions for pairwise 32 bit comparisons */ +static void gen_pmax_s32(TCGv_i32 res, TCGv_i32 op1, TCGv_i32 op2) +{ +tcg_gen_movcond_i32(TCG_COND_GE, res, op1, op2, op1, op2); +} + +static void gen_pmax_u32(TCGv_i32 res, TCGv_i32 op1, TCGv_i32 op2) +{ +tcg_gen_movcond_i32(TCG_COND_GEU, res, op1, op2, op1, op2); +} + +static void gen_pmin_s32(TCGv_i32 res, TCGv_i32 op1, TCGv_i32 op2) +{ +tcg_gen_movcond_i32(TCG_COND_LE, res, op1, op2, op1, op2); +} + +static void gen_pmin_u32(TCGv_i32 res, TCGv_i32 op1, TCGv_i32 op2) +{ +tcg_gen_movcond_i32(TCG_COND_LEU, res, op1, op2, op1, op2); +} + /* Pairwise op subgroup of C3.6.16. */ static void disas_simd_3same_pair(DisasContext *s, uint32_t insn) { -unsupported_encoding(s, insn); +int is_q = extract32(insn, 30, 1); +int u = extract32(insn, 29, 1); +int size = extract32(insn, 22, 2); +int opcode = extract32(insn, 11, 5); +int rm = extract32(insn, 16, 5); +int rn = extract32(insn, 5, 5); +int rd = extract32(insn, 0, 5); +int pass; + +if (size == 3 !is_q) { +unallocated_encoding(s); +return; +} + +switch (opcode) { +case 0x14: /* SMAXP, UMAXP */ +case 0x15: /* SMINP, UMINP */ +if (size == 3) { +unallocated_encoding(s); +return; +} +break; +case 0x17: +if (u) { +unallocated_encoding(s); +return; +} +break; +default: +g_assert_not_reached(); +} + +/* These operations work on the concatenated rm:rn, with each pair of + * adjacent elements being operated on to produce an element in the result. + */ +if (size == 3) { +TCGv_i64 tcg_res[2]; + +for (pass = 0; pass 2; pass++) { +TCGv_i64 tcg_op1 = tcg_temp_new_i64(); +TCGv_i64 tcg_op2 = tcg_temp_new_i64(); +int passreg = (pass == 0) ? rn : rm; + +read_vec_element(s, tcg_op1, passreg, 0, MO_64); +read_vec_element(s, tcg_op2, passreg, 1, MO_64); +tcg_res[pass] = tcg_temp_new_i64(); + +/* The only 64 bit pairwise integer op is ADDP */ +assert(opcode == 0x17); +tcg_gen_add_i64(tcg_res[pass], tcg_op1, tcg_op2); + +tcg_temp_free_i64(tcg_op1); +tcg_temp_free_i64(tcg_op2); +} + +for (pass = 0; pass 2; pass++) { +write_vec_element(s, tcg_res[pass], rd, pass, MO_64); +tcg_temp_free_i64(tcg_res[pass]); +} +} else { +int maxpass = is_q ? 4 : 2; +TCGv_i32 tcg_res[4]; + +for (pass = 0; pass maxpass; pass++) { +TCGv_i32 tcg_op1 = tcg_temp_new_i32(); +TCGv_i32 tcg_op2 = tcg_temp_new_i32(); +NeonGenTwoOpFn *genfn; +int passreg = pass (maxpass / 2) ? rn : rm; +int passelt = (is_q (pass 1)) ? 2 : 0; + +read_vec_element_i32(s, tcg_op1, passreg, passelt, MO_32); +read_vec_element_i32(s, tcg_op2, passreg, passelt + 1, MO_32); +tcg_res[pass] = tcg_temp_new_i32(); + +switch (opcode) { +case 0x17: /* ADDP */ +{ +static NeonGenTwoOpFn * const fns[3] = { +gen_helper_neon_padd_u8, +gen_helper_neon_padd_u16, +tcg_gen_add_i32, +}; +genfn = fns[size]; +break; +} +case 0x14: /* SMAXP, UMAXP */ +{ +static NeonGenTwoOpFn * const fns[3][2] = { +{ gen_helper_neon_pmax_s8, gen_helper_neon_pmax_u8 }, +{ gen_helper_neon_pmax_s16, gen_helper_neon_pmax_u16 }, +{ gen_pmax_s32, gen_pmax_u32 }, +}; +genfn = fns[size][u]; +break; +} +case 0x15: /* SMINP, UMINP */ +{ +static NeonGenTwoOpFn * const fns[3][2] = { +{ gen_helper_neon_pmin_s8, gen_helper_neon_pmin_u8 }, +{ gen_helper_neon_pmin_s16, gen_helper_neon_pmin_u16 }, +{ gen_pmin_s32, gen_pmin_u32 }, +}; +genfn = fns[size][u]; +break; +} +default: +g_assert_not_reached();
[Qemu-devel] [PATCH 06/21] target-arm: A64: Add integer ops from SIMD 3-same group
Add some of the integer operations in the SIMD 3-same group: specifically, the comparisons, addition and subtraction. Signed-off-by: Peter Maydell peter.mayd...@linaro.org Reviewed-by: Richard Henderson r...@twiddle.net --- target-arm/translate-a64.c | 165 - 1 file changed, 164 insertions(+), 1 deletion(-) diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c index 4767cbf..3934bce 100644 --- a/target-arm/translate-a64.c +++ b/target-arm/translate-a64.c @@ -72,6 +72,9 @@ typedef struct AArch64DecodeTable { AArch64DecodeFn *disas_fn; } AArch64DecodeTable; +/* Function prototype for gen_ functions for calling Neon helpers */ +typedef void NeonGenTwoOpFn(TCGv_i32, TCGv_i32, TCGv_i32); + /* initialize TCG globals. */ void a64_translate_init(void) { @@ -787,6 +790,25 @@ static void write_vec_element(DisasContext *s, TCGv_i64 tcg_src, int destidx, } } +static void write_vec_element_i32(DisasContext *s, TCGv_i32 tcg_src, + int destidx, int element, TCGMemOp memop) +{ +int vect_off = vec_reg_offset(destidx, element, memop MO_SIZE); +switch (memop) { +case MO_8: +tcg_gen_st8_i32(tcg_src, cpu_env, vect_off); +break; +case MO_16: +tcg_gen_st16_i32(tcg_src, cpu_env, vect_off); +break; +case MO_32: +tcg_gen_st_i32(tcg_src, cpu_env, vect_off); +break; +default: +g_assert_not_reached(); +} +} + /* Clear the high 64 bits of a 128 bit vector (in general non-quad * vector ops all need to do this). */ @@ -6040,7 +6062,148 @@ static void disas_simd_3same_float(DisasContext *s, uint32_t insn) /* Integer op subgroup of C3.6.16. */ static void disas_simd_3same_int(DisasContext *s, uint32_t insn) { -unsupported_encoding(s, insn); +int is_q = extract32(insn, 30, 1); +int u = extract32(insn, 29, 1); +int size = extract32(insn, 22, 2); +int opcode = extract32(insn, 11, 5); +int rm = extract32(insn, 16, 5); +int rn = extract32(insn, 5, 5); +int rd = extract32(insn, 0, 5); +int pass; + +switch (opcode) { +case 0x13: /* MUL, PMUL */ +if (u size != 0) { +unallocated_encoding(s); +return; +} +/* fall through */ +case 0x0: /* SHADD, UHADD */ +case 0x2: /* SRHADD, URHADD */ +case 0x4: /* SHSUB, UHSUB */ +case 0xc: /* SMAX, UMAX */ +case 0xd: /* SMIN, UMIN */ +case 0xe: /* SABD, UABD */ +case 0xf: /* SABA, UABA */ +case 0x12: /* MLA, MLS */ +if (size == 3) { +unallocated_encoding(s); +return; +} +unsupported_encoding(s, insn); +return; +case 0x1: /* SQADD */ +case 0x5: /* SQSUB */ +case 0x8: /* SSHL, USHL */ +case 0x9: /* SQSHL, UQSHL */ +case 0xa: /* SRSHL, URSHL */ +case 0xb: /* SQRSHL, UQRSHL */ +if (size == 3 !is_q) { +unallocated_encoding(s); +return; +} +unsupported_encoding(s, insn); +return; +case 0x16: /* SQDMULH, SQRDMULH */ +if (size == 0 || size == 3) { +unallocated_encoding(s); +return; +} +unsupported_encoding(s, insn); +return; +default: +if (size == 3 !is_q) { +unallocated_encoding(s); +return; +} +break; +} + +if (size == 3) { +for (pass = 0; pass (is_q ? 2 : 1); pass++) { +TCGv_i64 tcg_op1 = tcg_temp_new_i64(); +TCGv_i64 tcg_op2 = tcg_temp_new_i64(); +TCGv_i64 tcg_res = tcg_temp_new_i64(); + +read_vec_element(s, tcg_op1, rn, pass, MO_64); +read_vec_element(s, tcg_op2, rm, pass, MO_64); + +handle_3same_64(s, opcode, u, tcg_res, tcg_op1, tcg_op2); + +write_vec_element(s, tcg_res, rd, pass, MO_64); + +tcg_temp_free_i64(tcg_res); +tcg_temp_free_i64(tcg_op1); +tcg_temp_free_i64(tcg_op2); +} +} else { +for (pass = 0; pass (is_q ? 4 : 2); pass++) { +TCGv_i32 tcg_op1 = tcg_temp_new_i32(); +TCGv_i32 tcg_op2 = tcg_temp_new_i32(); +TCGv_i32 tcg_res = tcg_temp_new_i32(); +NeonGenTwoOpFn *genfn; + +read_vec_element_i32(s, tcg_op1, rn, pass, MO_32); +read_vec_element_i32(s, tcg_op2, rm, pass, MO_32); + +switch (opcode) { +case 0x6: /* CMGT, CMHI */ +{ +static NeonGenTwoOpFn * const fns[3][2] = { +{ gen_helper_neon_cgt_s8, gen_helper_neon_cgt_u8 }, +{ gen_helper_neon_cgt_s16, gen_helper_neon_cgt_u16 }, +{ gen_helper_neon_cgt_s32, gen_helper_neon_cgt_u32 }, +}; +genfn = fns[size][u]; +break; +} +case 0x7: /* CMGE, CMHS */ +{ +
Re: [Qemu-devel] [PATCH 00/21] A64: Add Neon instructions, second and third sets
On 26 January 2014 19:24, Peter Maydell peter.mayd...@linaro.org wrote: This patch series is kind of in two parts. The first 8 patches are the Neon second set that's already been pretty much reviewed; I'm resending them just because there were a few minor nits that came up in the last round which have been fixed: * patch 6 added the missing SQDMULH/SQRDMULH unallocated/unimplemented case in the SIMD 3-same initial decode * patch 7 now uses the _i32 vector element accessors * patch 8 fixed a few codestyle nits (RTH: these all seemed trivial enough that I've left your reviewed-by tags in place). Patches 9..21 are new, and fill in a number of gaps that bring us up to (and past) parity with the SuSE tree for coverage: * more SIMD 3-same ops, including basically all the integer ones * the scalar pairwise instruction group * more SIMD scalar-3-same ops, including all the integer ones * some (but not all) of the 2-reg misc and scalar 2-reg misc groups (by the same rationale as with 3-same, we aim for anything implemented in the SuSE tree plus enough to make it reasonably likely we've got the general function structure correct) I forgot to mention, but you can find a git tree with these in at git://git.linaro.org/people/peter.maydell/qemu-arm.git a64-neon thanks -- PMM
[Qemu-devel] [PATCH 04/21] target-arm: A64: Add top level decode for SIMD 3-same group
Add top level decode for the A64 SIMD three regs same group (C3.6.16), splitting it into the pairwise, logical, float and integer subgroups. Signed-off-by: Peter Maydell peter.mayd...@linaro.org Reviewed-by: Richard Henderson r...@twiddle.net --- target-arm/translate-a64.c | 45 - 1 file changed, 44 insertions(+), 1 deletion(-) diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c index 6ff3e43..2079c96 100644 --- a/target-arm/translate-a64.c +++ b/target-arm/translate-a64.c @@ -5948,6 +5948,30 @@ static void disas_simd_three_reg_diff(DisasContext *s, uint32_t insn) } } +/* Logic op (opcode == 3) subgroup of C3.6.16. */ +static void disas_simd_3same_logic(DisasContext *s, uint32_t insn) +{ +unsupported_encoding(s, insn); +} + +/* Pairwise op subgroup of C3.6.16. */ +static void disas_simd_3same_pair(DisasContext *s, uint32_t insn) +{ +unsupported_encoding(s, insn); +} + +/* Floating point op subgroup of C3.6.16. */ +static void disas_simd_3same_float(DisasContext *s, uint32_t insn) +{ +unsupported_encoding(s, insn); +} + +/* Integer op subgroup of C3.6.16. */ +static void disas_simd_3same_int(DisasContext *s, uint32_t insn) +{ +unsupported_encoding(s, insn); +} + /* C3.6.16 AdvSIMD three same * 31 30 29 28 24 23 22 21 20 16 1511 10 95 40 * +---+---+---+---+--+---+--++---+--+--+ @@ -5956,7 +5980,26 @@ static void disas_simd_three_reg_diff(DisasContext *s, uint32_t insn) */ static void disas_simd_three_reg_same(DisasContext *s, uint32_t insn) { -unsupported_encoding(s, insn); +int opcode = extract32(insn, 11, 5); + +switch (opcode) { +case 0x3: /* logic ops */ +disas_simd_3same_logic(s, insn); +break; +case 0x17: /* ADDP */ +case 0x14: /* SMAXP, UMAXP */ +case 0x15: /* SMINP, UMINP */ +/* Pairwise operations */ +disas_simd_3same_pair(s, insn); +break; +case 0x18 ... 0x31: +/* floating point ops, sz[1] and U are part of opcode */ +disas_simd_3same_float(s, insn); +break; +default: +disas_simd_3same_int(s, insn); +break; +} } /* C3.6.17 AdvSIMD two reg misc -- 1.8.5
[Qemu-devel] [PATCH 08/21] target-arm: A64: Add SIMD shift by immediate
From: Alex Bennée alex.ben...@linaro.org This implements a subset of the AdvSIMD shift operations (namely all the none saturating or narrowing ones). The actual shift generation code itself is common for both the scalar and vector cases but wrapped with either vector element iteration or the fp reg access. The rounding operations need to take special care to correctly reflect the result of adding rounding bits on high bits as the intermediates do not truncate. Signed-off-by: Alex Bennée alex.ben...@linaro.org Reviewed-by: Richard Henderson r...@twiddle.net --- target-arm/translate-a64.c | 375 - 1 file changed, 373 insertions(+), 2 deletions(-) diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c index 966e502..6cdb8fc 100644 --- a/target-arm/translate-a64.c +++ b/target-arm/translate-a64.c @@ -5531,15 +5531,216 @@ static void disas_simd_scalar_pairwise(DisasContext *s, uint32_t insn) unsupported_encoding(s, insn); } +/* + * Common SSHR[RA]/USHR[RA] - Shift right (optional rounding/accumulate) + * + * This code is handles the common shifting code and is used by both + * the vector and scalar code. + */ +static void handle_shri_with_rndacc(TCGv_i64 tcg_res, TCGv_i64 tcg_src, +TCGv_i64 tcg_rnd, bool accumulate, +bool is_u, int size, int shift) +{ +bool extended_result = false; +bool round = !TCGV_IS_UNUSED_I64(tcg_rnd); +int ext_lshift = 0; +TCGv_i64 tcg_src_hi; + +if (round size == 3) { +extended_result = true; +ext_lshift = 64 - shift; +tcg_src_hi = tcg_temp_new_i64(); +} else if (shift == 64) { +if (!accumulate is_u) { +/* result is zero */ +tcg_gen_movi_i64(tcg_res, 0); +return; +} +} + +/* Deal with the rounding step */ +if (round) { +if (extended_result) { +TCGv_i64 tcg_zero = tcg_const_i64(0); +if (!is_u) { +/* take care of sign extending tcg_res */ +tcg_gen_sari_i64(tcg_src_hi, tcg_src, 63); +tcg_gen_add2_i64(tcg_src, tcg_src_hi, + tcg_src, tcg_src_hi, + tcg_rnd, tcg_zero); +} else { +tcg_gen_add2_i64(tcg_src, tcg_src_hi, + tcg_src, tcg_zero, + tcg_rnd, tcg_zero); +} +tcg_temp_free_i64(tcg_zero); +} else { +tcg_gen_add_i64(tcg_src, tcg_src, tcg_rnd); +} +} + +/* Now do the shift right */ +if (round extended_result) { +/* extended case, 64 bit precision required */ +if (ext_lshift == 0) { +/* special case, only high bits matter */ +tcg_gen_mov_i64(tcg_src, tcg_src_hi); +} else { +tcg_gen_shri_i64(tcg_src, tcg_src, shift); +tcg_gen_shli_i64(tcg_src_hi, tcg_src_hi, ext_lshift); +tcg_gen_or_i64(tcg_src, tcg_src, tcg_src_hi); +} +} else { +if (is_u) { +if (shift == 64) { +/* essentially shifting in 64 zeros */ +tcg_gen_movi_i64(tcg_src, 0); +} else { +tcg_gen_shri_i64(tcg_src, tcg_src, shift); +} +} else { +if (shift == 64) { +/* effectively extending the sign-bit */ +tcg_gen_sari_i64(tcg_src, tcg_src, 63); +} else { +tcg_gen_sari_i64(tcg_src, tcg_src, shift); +} +} +} + +if (accumulate) { +tcg_gen_add_i64(tcg_res, tcg_res, tcg_src); +} else { +tcg_gen_mov_i64(tcg_res, tcg_src); +} + +if (extended_result) { +tcg_temp_free_i64(tcg_src_hi); +} +} + +/* Common SHL/SLI - Shift left with an optional insert */ +static void handle_shli_with_ins(TCGv_i64 tcg_res, TCGv_i64 tcg_src, + bool insert, int shift) +{ +if (insert) { /* SLI */ +tcg_gen_deposit_i64(tcg_res, tcg_res, tcg_src, shift, 64 - shift); +} else { /* SHL */ +tcg_gen_shli_i64(tcg_res, tcg_src, shift); +} +} + +/* SSHR[RA]/USHR[RA] - Scalar shift right (optional rounding/accumulate) */ +static void handle_scalar_simd_shri(DisasContext *s, +bool is_u, int immh, int immb, +int opcode, int rn, int rd) +{ +const int size = 3; +int immhb = immh 3 | immb; +int shift = 2 * (8 size) - immhb; +bool accumulate = false; +bool round = false; +TCGv_i64 tcg_rn; +TCGv_i64 tcg_rd; +TCGv_i64 tcg_round; + +if (!extract32(immh, 3, 1)) { +unallocated_encoding(s); +return; +} + +switch (opcode) { +case 0x02: /* SSRA / USRA (accumulate) */ +accumulate = true; +break; +case 0x04:
[Qemu-devel] [PATCH 12/21] tcg: Add TCGV_UNUSED_PTR, TCGV_IS_UNUSED_PTR, TCGV_EQUAL_PTR
We have macros for marking TCGv values as unused, checking if they are unused and comparing them to each other. However these only exist for TCGv_i32 and TCGv_i64; add them for TCGv_ptr as well. Signed-off-by: Peter Maydell peter.mayd...@linaro.org --- tcg/tcg.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tcg/tcg.h b/tcg/tcg.h index c72af6c..f7efcb4 100644 --- a/tcg/tcg.h +++ b/tcg/tcg.h @@ -324,13 +324,16 @@ typedef int TCGv_i64; #define TCGV_EQUAL_I32(a, b) (GET_TCGV_I32(a) == GET_TCGV_I32(b)) #define TCGV_EQUAL_I64(a, b) (GET_TCGV_I64(a) == GET_TCGV_I64(b)) +#define TCGV_EQUAL_PTR(a, b) (GET_TCGV_PTR(a) == GET_TCGV_PTR(b)) /* Dummy definition to avoid compiler warnings. */ #define TCGV_UNUSED_I32(x) x = MAKE_TCGV_I32(-1) #define TCGV_UNUSED_I64(x) x = MAKE_TCGV_I64(-1) +#define TCGV_UNUSED_PTR(x) x = MAKE_TCGV_PTR(-1) #define TCGV_IS_UNUSED_I32(x) (GET_TCGV_I32(x) == -1) #define TCGV_IS_UNUSED_I64(x) (GET_TCGV_I64(x) == -1) +#define TCGV_IS_UNUSED_PTR(x) (GET_TCGV_PTR(x) == -1) /* call flags */ /* Helper does not read globals (either directly or through an exception). It -- 1.8.5
[Qemu-devel] [PATCH 03/21] target-arm: A64: Add SIMD scalar 3 same add, sub and compare ops
Implement the add, sub and compare ops from the SIMD scalar three same group. Signed-off-by: Peter Maydell peter.mayd...@linaro.org Reviewed-by: Richard Henderson r...@twiddle.net --- target-arm/translate-a64.c | 131 - 1 file changed, 130 insertions(+), 1 deletion(-) diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c index 145125e..6ff3e43 100644 --- a/target-arm/translate-a64.c +++ b/target-arm/translate-a64.c @@ -5531,6 +5531,58 @@ static void disas_simd_scalar_three_reg_diff(DisasContext *s, uint32_t insn) unsupported_encoding(s, insn); } +static void handle_3same_64(DisasContext *s, int opcode, bool u, +TCGv_i64 tcg_rd, TCGv_i64 tcg_rn, TCGv_i64 tcg_rm) +{ +/* Handle 64x64-64 opcodes which are shared between the scalar + * and vector 3-same groups. We cover every opcode where size == 3 + * is valid in either the three-reg-same (integer, not pairwise) + * or scalar-three-reg-same groups. (Some opcodes are not yet + * implemented.) + */ +TCGCond cond; + +switch (opcode) { +case 0x6: /* CMGT, CMHI */ +/* 64 bit integer comparison, result = test ? (2^64 - 1) : 0. + * We implement this using setcond (test) and then negating. + */ +cond = u ? TCG_COND_GTU : TCG_COND_GT; +do_cmop: +tcg_gen_setcond_i64(cond, tcg_rd, tcg_rn, tcg_rm); +tcg_gen_neg_i64(tcg_rd, tcg_rd); +break; +case 0x7: /* CMGE, CMHS */ +cond = u ? TCG_COND_GEU : TCG_COND_GE; +goto do_cmop; +case 0x11: /* CMTST, CMEQ */ +if (u) { +cond = TCG_COND_EQ; +goto do_cmop; +} +/* CMTST : test is if (X Y != 0). */ +tcg_gen_and_i64(tcg_rd, tcg_rn, tcg_rm); +tcg_gen_setcondi_i64(TCG_COND_NE, tcg_rd, tcg_rd, 0); +tcg_gen_neg_i64(tcg_rd, tcg_rd); +break; +case 0x10: /* ADD, SUB */ +if (u) { +tcg_gen_sub_i64(tcg_rd, tcg_rn, tcg_rm); +} else { +tcg_gen_add_i64(tcg_rd, tcg_rn, tcg_rm); +} +break; +case 0x1: /* SQADD */ +case 0x5: /* SQSUB */ +case 0x8: /* SSHL, USHL */ +case 0x9: /* SQSHL, UQSHL */ +case 0xa: /* SRSHL, URSHL */ +case 0xb: /* SQRSHL, UQRSHL */ +default: +g_assert_not_reached(); +} +} + /* C3.6.11 AdvSIMD scalar three same * 31 30 29 28 24 23 22 21 20 16 1511 10 95 40 * +-+---+---+--+---+--++---+--+--+ @@ -5539,7 +5591,84 @@ static void disas_simd_scalar_three_reg_diff(DisasContext *s, uint32_t insn) */ static void disas_simd_scalar_three_reg_same(DisasContext *s, uint32_t insn) { -unsupported_encoding(s, insn); +int rd = extract32(insn, 0, 5); +int rn = extract32(insn, 5, 5); +int opcode = extract32(insn, 11, 5); +int rm = extract32(insn, 16, 5); +int size = extract32(insn, 22, 2); +bool u = extract32(insn, 29, 1); +TCGv_i64 tcg_rn; +TCGv_i64 tcg_rm; +TCGv_i64 tcg_rd; + +if (opcode = 0x18) { +/* Floating point: U, size[1] and opcode indicate operation */ +int fpopcode = opcode | (extract32(size, 1, 1) 5) | (u 6); +switch (fpopcode) { +case 0x1b: /* FMULX */ +case 0x1c: /* FCMEQ */ +case 0x1f: /* FRECPS */ +case 0x3f: /* FRSQRTS */ +case 0x5c: /* FCMGE */ +case 0x5d: /* FACGE */ +case 0x7a: /* FABD */ +case 0x7c: /* FCMGT */ +case 0x7d: /* FACGT */ +unsupported_encoding(s, insn); +return; +default: +unallocated_encoding(s); +return; +} +} + +switch (opcode) { +case 0x1: /* SQADD, UQADD */ +case 0x5: /* SQSUB, UQSUB */ +case 0x8: /* SSHL, USHL */ +case 0xa: /* SRSHL, URSHL */ +unsupported_encoding(s, insn); +return; +case 0x6: /* CMGT, CMHI */ +case 0x7: /* CMGE, CMHS */ +case 0x11: /* CMTST, CMEQ */ +case 0x10: /* ADD, SUB (vector) */ +if (size != 3) { +unallocated_encoding(s); +return; +} +break; +case 0x9: /* SQSHL, UQSHL */ +case 0xb: /* SQRSHL, UQRSHL */ +unsupported_encoding(s, insn); +return; +case 0x16: /* SQDMULH, SQRDMULH (vector) */ +if (size != 1 size != 2) { +unallocated_encoding(s); +return; +} +unsupported_encoding(s, insn); +return; +default: +unallocated_encoding(s); +return; +} + +tcg_rn = read_fp_dreg(s, rn); /* op1 */ +tcg_rm = read_fp_dreg(s, rm); /* op2 */ +tcg_rd = tcg_temp_new_i64(); + +/* For the moment we only support the opcodes which are + * 64-bit-width only. The size != 3 cases will + * be handled later when the relevant ops are implemented. + */ +handle_3same_64(s, opcode, u, tcg_rd, tcg_rn,
[Qemu-devel] [PATCH 14/21] target-arm: A64: Implement remaining integer scalar-3-same insns
Implement the remaining integer instructions in the scalar-three-reg-same group: SQADD, UQADD, SQSUB, UQSUB, SQSHL, UQSHL, SQRSHL, UQRSHL, SQDMULH, SQRDMULH. Signed-off-by: Peter Maydell peter.mayd...@linaro.org --- target-arm/translate-a64.c | 106 + 1 file changed, 87 insertions(+), 19 deletions(-) diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c index 881e9eb..8a2f311 100644 --- a/target-arm/translate-a64.c +++ b/target-arm/translate-a64.c @@ -6094,8 +6094,6 @@ static void disas_simd_scalar_three_reg_same(DisasContext *s, uint32_t insn) int rm = extract32(insn, 16, 5); int size = extract32(insn, 22, 2); bool u = extract32(insn, 29, 1); -TCGv_i64 tcg_rn; -TCGv_i64 tcg_rm; TCGv_i64 tcg_rd; if (opcode = 0x18) { @@ -6126,8 +6124,9 @@ static void disas_simd_scalar_three_reg_same(DisasContext *s, uint32_t insn) switch (opcode) { case 0x1: /* SQADD, UQADD */ case 0x5: /* SQSUB, UQSUB */ -unsupported_encoding(s, insn); -return; +case 0x9: /* SQSHL, UQSHL */ +case 0xb: /* SQRSHL, UQRSHL */ +break; case 0x8: /* SSHL, USHL */ case 0xa: /* SRSHL, URSHL */ case 0x6: /* CMGT, CMHI */ @@ -6139,36 +6138,105 @@ static void disas_simd_scalar_three_reg_same(DisasContext *s, uint32_t insn) return; } break; -case 0x9: /* SQSHL, UQSHL */ -case 0xb: /* SQRSHL, UQRSHL */ -unsupported_encoding(s, insn); -return; case 0x16: /* SQDMULH, SQRDMULH (vector) */ if (size != 1 size != 2) { unallocated_encoding(s); return; } -unsupported_encoding(s, insn); -return; +break; default: unallocated_encoding(s); return; } -tcg_rn = read_fp_dreg(s, rn); /* op1 */ -tcg_rm = read_fp_dreg(s, rm); /* op2 */ tcg_rd = tcg_temp_new_i64(); -/* For the moment we only support the opcodes which are - * 64-bit-width only. The size != 3 cases will - * be handled later when the relevant ops are implemented. - */ -handle_3same_64(s, opcode, u, tcg_rd, tcg_rn, tcg_rm); +if (size == 3) { +TCGv_i64 tcg_rn = read_fp_dreg(s, rn); +TCGv_i64 tcg_rm = read_fp_dreg(s, rm); + +handle_3same_64(s, opcode, u, tcg_rd, tcg_rn, tcg_rm); +tcg_temp_free_i64(tcg_rn); +tcg_temp_free_i64(tcg_rm); +} else { +/* Do a single operation on the lowest element in the vector. + * We use the standard Neon helpers and rely on 0 OP 0 == 0 with + * no side effects for all these operations. + * OPTME: special-purpose helpers would avoid doing some + * unnecessary work in the helper for the 8 and 16 bit cases. + */ +NeonGenTwoOpEnvFn *genenvfn; +TCGv_i32 tcg_rn = tcg_temp_new_i32(); +TCGv_i32 tcg_rm = tcg_temp_new_i32(); +TCGv_i32 tcg_rd32 = tcg_temp_new_i32(); + +read_vec_element_i32(s, tcg_rn, rn, 0, size); +read_vec_element_i32(s, tcg_rm, rm, 0, size); + +switch (opcode) { +case 0x1: /* SQADD, UQADD */ +{ +static NeonGenTwoOpEnvFn * const fns[3][2] = { +{ gen_helper_neon_qadd_s8, gen_helper_neon_qadd_u8 }, +{ gen_helper_neon_qadd_s16, gen_helper_neon_qadd_u16 }, +{ gen_helper_neon_qadd_s32, gen_helper_neon_qadd_u32 }, +}; +genenvfn = fns[size][u]; +break; +} +case 0x5: /* SQSUB, UQSUB */ +{ +static NeonGenTwoOpEnvFn * const fns[3][2] = { +{ gen_helper_neon_qsub_s8, gen_helper_neon_qsub_u8 }, +{ gen_helper_neon_qsub_s16, gen_helper_neon_qsub_u16 }, +{ gen_helper_neon_qsub_s32, gen_helper_neon_qsub_u32 }, +}; +genenvfn = fns[size][u]; +break; +} +case 0x9: /* SQSHL, UQSHL */ +{ +static NeonGenTwoOpEnvFn * const fns[3][2] = { +{ gen_helper_neon_qshl_s8, gen_helper_neon_qshl_u8 }, +{ gen_helper_neon_qshl_s16, gen_helper_neon_qshl_u16 }, +{ gen_helper_neon_qshl_s32, gen_helper_neon_qshl_u32 }, +}; +genenvfn = fns[size][u]; +break; +} +case 0xb: /* SQRSHL, UQRSHL */ +{ +static NeonGenTwoOpEnvFn * const fns[3][2] = { +{ gen_helper_neon_qrshl_s8, gen_helper_neon_qrshl_u8 }, +{ gen_helper_neon_qrshl_s16, gen_helper_neon_qrshl_u16 }, +{ gen_helper_neon_qrshl_s32, gen_helper_neon_qrshl_u32 }, +}; +genenvfn = fns[size][u]; +break; +} +case 0x16: /* SQDMULH, SQRDMULH */ +{ +static NeonGenTwoOpEnvFn * const fns[2][2] = { +{ gen_helper_neon_qdmulh_s16,
[Qemu-devel] [PATCH 03/10] block: Make bdrv_file_open() static
Add the bdrv_open() option BDRV_O_PROTOCOL which results in passing the call to bdrv_file_open(). Additionally, make bdrv_file_open() static and therefore bdrv_open() the only way to call it. Consequently, all existing calls to bdrv_file_open() have to be adjusted to use bdrv_open() with the BDRV_O_PROTOCOL flag instead. Signed-off-by: Max Reitz mre...@redhat.com --- block.c | 17 - block/cow.c | 6 +++--- block/qcow.c | 6 +++--- block/qcow2.c | 5 +++-- block/qed.c | 5 +++-- block/sheepdog.c | 8 +--- block/vhdx.c | 5 +++-- block/vmdk.c | 11 +++ include/block/block.h | 5 ++--- qemu-io.c | 4 +++- 10 files changed, 44 insertions(+), 28 deletions(-) diff --git a/block.c b/block.c index f9923bb..0fb7892 100644 --- a/block.c +++ b/block.c @@ -947,9 +947,9 @@ free_and_fail: * after the call (even on failure), so if the caller intends to reuse the * dictionary, it needs to use QINCREF() before calling bdrv_file_open. */ -int bdrv_file_open(BlockDriverState **pbs, const char *filename, - const char *reference, QDict *options, int flags, - Error **errp) +static int bdrv_file_open(BlockDriverState **pbs, const char *filename, + const char *reference, QDict *options, int flags, + Error **errp) { BlockDriverState *bs = NULL; BlockDriver *drv; @@ -1196,8 +1196,9 @@ int bdrv_open_image(BlockDriverState **pbs, const char *filename, *pbs = NULL; ret = bdrv_open(pbs, filename, NULL, image_options, flags, NULL, errp); } else { -ret = bdrv_file_open(pbs, filename, reference, image_options, flags, - errp); +*pbs = NULL; +ret = bdrv_open(pbs, filename, reference, image_options, +flags | BDRV_O_PROTOCOL, NULL, errp); } done: @@ -1227,6 +1228,12 @@ int bdrv_open(BlockDriverState **pbs, const char *filename, const char *drvname; Error *local_err = NULL; +if (flags BDRV_O_PROTOCOL) { +assert(!drv); +return bdrv_file_open(pbs, filename, reference, options, + flags ~BDRV_O_PROTOCOL, errp); +} + /* NULL means an empty set of options */ if (options == NULL) { options = qdict_new(); diff --git a/block/cow.c b/block/cow.c index 7fc0b12..f0748a2 100644 --- a/block/cow.c +++ b/block/cow.c @@ -332,7 +332,7 @@ static int cow_create(const char *filename, QEMUOptionParameter *options, const char *image_filename = NULL; Error *local_err = NULL; int ret; -BlockDriverState *cow_bs; +BlockDriverState *cow_bs = NULL; /* Read out options */ while (options options-name) { @@ -351,8 +351,8 @@ static int cow_create(const char *filename, QEMUOptionParameter *options, return ret; } -ret = bdrv_file_open(cow_bs, filename, NULL, NULL, BDRV_O_RDWR, - local_err); +ret = bdrv_open(cow_bs, filename, NULL, NULL, +BDRV_O_RDWR | BDRV_O_PROTOCOL, NULL, local_err); if (ret 0) { qerror_report_err(local_err); error_free(local_err); diff --git a/block/qcow.c b/block/qcow.c index 948b0c5..4881d84 100644 --- a/block/qcow.c +++ b/block/qcow.c @@ -670,7 +670,7 @@ static int qcow_create(const char *filename, QEMUOptionParameter *options, int flags = 0; Error *local_err = NULL; int ret; -BlockDriverState *qcow_bs; +BlockDriverState *qcow_bs = NULL; /* Read out options */ while (options options-name) { @@ -691,8 +691,8 @@ static int qcow_create(const char *filename, QEMUOptionParameter *options, return ret; } -ret = bdrv_file_open(qcow_bs, filename, NULL, NULL, BDRV_O_RDWR, - local_err); +ret = bdrv_open(qcow_bs, filename, NULL, NULL, +BDRV_O_RDWR | BDRV_O_PROTOCOL, NULL, local_err); if (ret 0) { qerror_report_err(local_err); error_free(local_err); diff --git a/block/qcow2.c b/block/qcow2.c index 7202a26..40b957b 100644 --- a/block/qcow2.c +++ b/block/qcow2.c @@ -1479,7 +1479,7 @@ static int qcow2_create2(const char *filename, int64_t total_size, * 2 GB for 64k clusters, and we don't want to have a 2 GB initial file * size for any qcow2 image. */ -BlockDriverState* bs; +BlockDriverState *bs = NULL; QCowHeader *header; uint8_t* refcount_table; Error *local_err = NULL; @@ -1491,7 +1491,8 @@ static int qcow2_create2(const char *filename, int64_t total_size, return ret; } -ret = bdrv_file_open(bs, filename, NULL, NULL, BDRV_O_RDWR, local_err); +ret = bdrv_open(bs, filename, NULL, NULL, BDRV_O_RDWR | BDRV_O_PROTOCOL, +NULL, local_err); if (ret 0) { error_propagate(errp, local_err); return
[Qemu-devel] [PATCH 01/10] block: Change BDS parameter of bdrv_open() to **
Make bdrv_open() take a pointer to a BDS pointer, similarly to bdrv_file_open(). If a pointer to a NULL pointer is given, bdrv_open() will create a new BDS with an empty name; if the BDS pointer is not NULL, that existing BDS will be reused (in the same way as bdrv_open() already did). Signed-off-by: Max Reitz mre...@redhat.com --- block.c | 53 ++- block/qcow2.c | 14 +- block/vmdk.c | 5 ++--- block/vvfat.c | 6 ++ blockdev.c| 21 hw/block/xen_disk.c | 2 +- include/block/block.h | 2 +- qemu-img.c| 6 +++--- qemu-io.c | 2 +- qemu-nbd.c| 2 +- 10 files changed, 55 insertions(+), 58 deletions(-) diff --git a/block.c b/block.c index cb21a5f..c660609 100644 --- a/block.c +++ b/block.c @@ -1039,7 +1039,7 @@ int bdrv_file_open(BlockDriverState **pbs, const char *filename, } if (!drv-bdrv_file_open) { -ret = bdrv_open(bs, filename, options, flags, drv, local_err); +ret = bdrv_open(bs, filename, options, flags, drv, local_err); options = NULL; } else { ret = bdrv_open_common(bs, NULL, options, flags, drv, local_err); @@ -1108,8 +1108,6 @@ int bdrv_open_backing_file(BlockDriverState *bs, QDict *options, Error **errp) sizeof(backing_filename)); } -bs-backing_hd = bdrv_new(); - if (bs-backing_format[0] != '\0') { back_drv = bdrv_find_format(bs-backing_format); } @@ -1118,11 +1116,10 @@ int bdrv_open_backing_file(BlockDriverState *bs, QDict *options, Error **errp) back_flags = bs-open_flags ~(BDRV_O_RDWR | BDRV_O_SNAPSHOT | BDRV_O_COPY_ON_READ); -ret = bdrv_open(bs-backing_hd, +ret = bdrv_open(bs-backing_hd, *backing_filename ? backing_filename : NULL, options, back_flags, back_drv, local_err); if (ret 0) { -bdrv_unref(bs-backing_hd); bs-backing_hd = NULL; bs-open_flags |= BDRV_O_NO_BACKING; error_setg(errp, Could not open backing file: %s, @@ -1189,8 +1186,6 @@ int bdrv_open_image(BlockDriverState **pbs, const char *filename, /* If a filename is given and the block driver should be detected automatically (instead of using none), use bdrv_open() in order to do that auto-detection. */ -BlockDriverState *bs; - if (reference) { error_setg(errp, Cannot reference an existing block device while giving a filename); @@ -1198,13 +1193,8 @@ int bdrv_open_image(BlockDriverState **pbs, const char *filename, goto done; } -bs = bdrv_new(); -ret = bdrv_open(bs, filename, image_options, flags, NULL, errp); -if (ret 0) { -bdrv_unref(bs); -} else { -*pbs = bs; -} +*pbs = NULL; +ret = bdrv_open(pbs, filename, image_options, flags, NULL, errp); } else { ret = bdrv_file_open(pbs, filename, reference, image_options, flags, errp); @@ -1222,14 +1212,17 @@ done: * empty set of options. The reference to the QDict belongs to the block layer * after the call (even on failure), so if the caller intends to reuse the * dictionary, it needs to use QINCREF() before calling bdrv_open. + * + * If *pbs is NULL, a new BDS will be created with a pointer to it stored there. + * If it is not NULL, the referenced BDS will be reused. */ -int bdrv_open(BlockDriverState *bs, const char *filename, QDict *options, +int bdrv_open(BlockDriverState **pbs, const char *filename, QDict *options, int flags, BlockDriver *drv, Error **errp) { int ret; /* TODO: extra byte is a hack to ensure MAX_PATH space on Windows. */ char tmp_filename[PATH_MAX + 1]; -BlockDriverState *file = NULL; +BlockDriverState *file = NULL, *bs = NULL; const char *drvname; Error *local_err = NULL; @@ -1238,12 +1231,17 @@ int bdrv_open(BlockDriverState *bs, const char *filename, QDict *options, options = qdict_new(); } +if (*pbs) { +bs = *pbs; +} else { +bs = bdrv_new(); +} bs-options = options; options = qdict_clone_shallow(options); /* For snapshot=on, create a temporary qcow2 overlay */ if (flags BDRV_O_SNAPSHOT) { -BlockDriverState *bs1; +BlockDriverState *bs1 = NULL; int64_t total_size; BlockDriver *bdrv_qcow2; QEMUOptionParameter *create_options; @@ -1253,12 +1251,10 @@ int bdrv_open(BlockDriverState *bs, const char *filename, QDict *options, instead of opening 'filename' directly */ /* Get the required size from the image */ -bs1 = bdrv_new(); QINCREF(options); -ret = bdrv_open(bs1, filename,
[Qemu-devel] [PATCH 16/21] target-arm: A64: Add skeleton decode for SIMD 2-reg misc group
Add a skeleton decode for the SIMD 2-reg misc group. Signed-off-by: Peter Maydell peter.mayd...@linaro.org --- target-arm/translate-a64.c | 110 - 1 file changed, 109 insertions(+), 1 deletion(-) diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c index f784602..f03d645 100644 --- a/target-arm/translate-a64.c +++ b/target-arm/translate-a64.c @@ -7401,7 +7401,115 @@ static void disas_simd_three_reg_same(DisasContext *s, uint32_t insn) */ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn) { -unsupported_encoding(s, insn); +int size = extract32(insn, 22, 2); +int opcode = extract32(insn, 12, 5); +bool u = extract32(insn, 29, 1); +bool is_q = extract32(insn, 30, 1); + +switch (opcode) { +case 0x0: /* REV64, REV32 */ +case 0x1: /* REV16 */ +unsupported_encoding(s, insn); +return; +case 0x5: /* CNT, NOT, RBIT */ +if ((u == 0 size 0) || +(u == 1 size 1)) { +unallocated_encoding(s); +return; +} +unsupported_encoding(s, insn); +return; +case 0x2: /* SADDLP, UADDLP */ +case 0x4: /* CLS, CLZ */ +case 0x6: /* SADALP, UADALP */ +case 0x12: /* XTN, XTN2, SQXTUN, SQXTUN2 */ +case 0x14: /* SQXTN, SQXTN2, UQXTN, UQXTN2 */ +if (size == 3) { +unallocated_encoding(s); +return; +} +unsupported_encoding(s, insn); +return; +case 0x13: /* SHLL, SHLL2 */ +if (u == 0 || size == 3) { +unallocated_encoding(s); +return; +} +unsupported_encoding(s, insn); +return; +case 0xa: /* CMLT */ +if (u == 1) { +unallocated_encoding(s); +return; +} +/* fall through */ +case 0x3: /* SUQADD, USQADD */ +case 0x7: /* SQABS, SQNEG */ +case 0x8: /* CMGT, CMGE */ +case 0x9: /* CMEQ, CMLE */ +case 0xb: /* ABS, NEG */ +if (size == 3 !is_q) { +unallocated_encoding(s); +return; +} +unsupported_encoding(s, insn); +return; +case 0xc ... 0xf: +case 0x16 ... 0x1d: +case 0x1f: +{ +/* Floating point: U, size[1] and opcode indicate operation; + * size[0] indicates single or double precision. + */ +opcode |= (extract32(size, 1, 1) 5) | (u 6); +size = extract32(size, 0, 1) ? 3 : 2; +switch (opcode) { +case 0x16: /* FCVTN, FCVTN2 */ +case 0x17: /* FCVTL, FCVTL2 */ +case 0x18: /* FRINTN */ +case 0x19: /* FRINTM */ +case 0x1a: /* FCVTNS */ +case 0x1b: /* FCVTMS */ +case 0x1c: /* FCVTAS */ +case 0x1d: /* SCVTF */ +case 0x2c: /* FCMGT (zero) */ +case 0x2d: /* FCMEQ (zero) */ +case 0x2e: /* FCMLT (zero) */ +case 0x2f: /* FABS */ +case 0x38: /* FRINTP */ +case 0x39: /* FRINTZ */ +case 0x3a: /* FCVTPS */ +case 0x3b: /* FCVTZS */ +case 0x3c: /* URECPE */ +case 0x3d: /* FRECPE */ +case 0x56: /* FCVTXN, FCVTXN2 */ +case 0x58: /* FRINTA */ +case 0x59: /* FRINTX */ +case 0x5a: /* FCVTNU */ +case 0x5b: /* FCVTMU */ +case 0x5c: /* FCVTAU */ +case 0x5d: /* UCVTF */ +case 0x6c: /* FCMGE (zero) */ +case 0x6d: /* FCMLE (zero) */ +case 0x6f: /* FNEG */ +case 0x79: /* FRINTI */ +case 0x7a: /* FCVTPU */ +case 0x7b: /* FCVTZU */ +case 0x7c: /* URSQRTE */ +case 0x7d: /* FRSQRTE */ +case 0x7f: /* FSQRT */ +unsupported_encoding(s, insn); +return; +default: +unallocated_encoding(s); +return; +} +break; +} +default: +unallocated_encoding(s); +return; +} } /* C3.6.18 AdvSIMD vector x indexed element -- 1.8.5
Re: [Qemu-devel] [PULL] Update OpenBIOS images to r1246
On 12/01/14 15:25, Mark Cave-Ayland wrote: Hi Anthony, Please pull the latest OpenBIOS binary images. In particular, these images fix the following two bugs in SPARC32: - Booting with OBP instead of OpenBIOS - Booting from hard disk instead of CDROM (https://bugs.launchpad.net/qemu/+bug/1262081) CC to -stable because these binaries also need to be updated in 1.7 branch too. Many thanks, Mark. Ping? Looks like another set of PULL requests have been processed, but this wasn't included - was there a problem with the PULL request itself? ATB, Mark.
Re: [Qemu-devel] [PATCH v3 2/2] hw/arm/allwinner-a10: initialize EMAC
On Sun, Jan 26, 2014 at 12:42:59AM +0100, Andreas Färber wrote: Am 20.01.2014 00:25, schrieb Beniamino Galvani: Signed-off-by: Beniamino Galvani b.galv...@gmail.com --- hw/arm/allwinner-a10.c | 16 hw/arm/cubieboard.c|7 +++ include/hw/arm/allwinner-a10.h |3 +++ 3 files changed, 26 insertions(+) diff --git a/hw/arm/allwinner-a10.c b/hw/arm/allwinner-a10.c index 4658e19..416cd49 100644 --- a/hw/arm/allwinner-a10.c +++ b/hw/arm/allwinner-a10.c @@ -31,6 +31,13 @@ static void aw_a10_init(Object *obj) object_initialize(s-timer, sizeof(s-timer), TYPE_AW_A10_PIT); qdev_set_parent_bus(DEVICE(s-timer), sysbus_get_default()); + +object_initialize(s-emac, sizeof(s-emac), TYPE_AW_EMAC); +qdev_set_parent_bus(DEVICE(s-emac), sysbus_get_default()); +if (nd_table[0].used) { +qemu_check_nic_model(nd_table[0], allwinner_emac); Please adopt new-style names with dashes, i.e. allwinner-emac. Peter C.'s comment wrt TYPE_* still applies though. Ok. +qdev_set_nic_properties(DEVICE(s-emac), nd_table[0]); Since you're using DEVICE() twice, you should consider using a local variable like you did for sysbusdev below. It's a one-time initialization though, so not mandatory. For readability and also, as suggested by Peter in a previous review, consistency with nearby code I'd prefer to keep the two casts. +} } static void aw_a10_realize(DeviceState *dev, Error **errp) @@ -76,6 +83,15 @@ static void aw_a10_realize(DeviceState *dev, Error **errp) sysbus_connect_irq(sysbusdev, 4, s-irq[67]); sysbus_connect_irq(sysbusdev, 5, s-irq[68]); +object_property_set_bool(OBJECT(s-emac), true, realized, err); +if (err != NULL) { +error_propagate(errp, err); +return; +} +sysbusdev = SYS_BUS_DEVICE(s-emac); +sysbus_mmio_map(sysbusdev, 0, AW_A10_EMAC_BASE); +sysbus_connect_irq(sysbusdev, 0, s-irq[55]); + serial_mm_init(get_system_memory(), AW_A10_UART0_REG_BASE, 2, s-irq[1], 115200, serial_hds[0], DEVICE_NATIVE_ENDIAN); } diff --git a/hw/arm/cubieboard.c b/hw/arm/cubieboard.c index 3fcb6d2..b3f8f51 100644 --- a/hw/arm/cubieboard.c +++ b/hw/arm/cubieboard.c @@ -36,6 +36,13 @@ static void cubieboard_init(QEMUMachineInitArgs *args) Error *err = NULL; s-a10 = AW_A10(object_new(TYPE_AW_A10)); + +object_property_set_int(OBJECT(s-a10-emac), 1, phyaddr, err); phy-addr? Other network adapters are using phyaddr so I simply copied that. But I agree, phy-addr sounds better. I will change it in v4. +if (err != NULL) { +error_report(Couldn't set phy address: %s\n, error_get_pretty(err)); error_report() always without trailing \n. +exit(1); +} + object_property_set_bool(OBJECT(s-a10), true, realized, err); if (err != NULL) { error_report(Couldn't realize Allwinner A10: %s\n, Bad example. ;) Fixes welcome. I will fix both. Beniamino Cheers, Andreas diff --git a/include/hw/arm/allwinner-a10.h b/include/hw/arm/allwinner-a10.h index da36647..01a189b 100644 --- a/include/hw/arm/allwinner-a10.h +++ b/include/hw/arm/allwinner-a10.h @@ -6,6 +6,7 @@ #include hw/arm/arm.h #include hw/timer/allwinner-a10-pit.h #include hw/intc/allwinner-a10-pic.h +#include hw/net/allwinner_emac.h #include sysemu/sysemu.h #include exec/address-spaces.h @@ -14,6 +15,7 @@ #define AW_A10_PIC_REG_BASE 0x01c20400 #define AW_A10_PIT_REG_BASE 0x01c20c00 #define AW_A10_UART0_REG_BASE 0x01c28000 +#define AW_A10_EMAC_BASE0x01c0b000 #define AW_A10_SDRAM_BASE 0x4000 @@ -29,6 +31,7 @@ typedef struct AwA10State { qemu_irq irq[AW_A10_PIC_INT_NR]; AwA10PITState timer; AwA10PICState intc; +AwEmacState emac; } AwA10State; #define ALLWINNER_H_ -- SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg
Re: [Qemu-devel] [PATCH v3] Fix QEMU build on OpenBSD on x86 archs
On 26/01/14 1:06 PM, Paolo Bonzini wrote: Il 26/01/2014 02:37, Brad Smith ha scritto: Reviewed-by: Stefan Hajnoczi stefa...@redhat.com Is there some sort of process I am missing to have build fixes commited so that QEMU actually builds? Right now we have problems getting patches committed at all. This patch and the other NetBSD patch is not lost. I know it is not literally lost. I don't follow the list that closely.. what was the reason for there being two incidents over the last 2 months of there being no commits for over a week (at least from the perspective of git.qemu.org)? -- This message has been scanned for viruses and dangerous content by MailScanner, and is believed to be clean.
[Qemu-devel] [PATCH v4 2/3] hw/net: add support for Allwinner EMAC Fast Ethernet controller
This patch adds support for the Fast Ethernet MAC found on Allwinner SoCs, together with a basic emulation of Realtek RTL8201CP PHY. Since there is no public documentation of the Allwinner controller, the implementation is based on Linux kernel driver. Signed-off-by: Beniamino Galvani b.galv...@gmail.com --- default-configs/arm-softmmu.mak |1 + hw/net/Makefile.objs|1 + hw/net/allwinner_emac.c | 532 +++ include/hw/net/allwinner_emac.h | 211 4 files changed, 745 insertions(+) create mode 100644 hw/net/allwinner_emac.c create mode 100644 include/hw/net/allwinner_emac.h diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak index ce1d620..f3513fa 100644 --- a/default-configs/arm-softmmu.mak +++ b/default-configs/arm-softmmu.mak @@ -27,6 +27,7 @@ CONFIG_SSI_SD=y CONFIG_SSI_M25P80=y CONFIG_LAN9118=y CONFIG_SMC91C111=y +CONFIG_ALLWINNER_EMAC=y CONFIG_DS1338=y CONFIG_PFLASH_CFI01=y CONFIG_PFLASH_CFI02=y diff --git a/hw/net/Makefile.objs b/hw/net/Makefile.objs index 951cca3..75e80c2 100644 --- a/hw/net/Makefile.objs +++ b/hw/net/Makefile.objs @@ -18,6 +18,7 @@ common-obj-$(CONFIG_OPENCORES_ETH) += opencores_eth.o common-obj-$(CONFIG_XGMAC) += xgmac.o common-obj-$(CONFIG_MIPSNET) += mipsnet.o common-obj-$(CONFIG_XILINX_AXI) += xilinx_axienet.o +common-obj-$(CONFIG_ALLWINNER_EMAC) += allwinner_emac.o common-obj-$(CONFIG_CADENCE) += cadence_gem.o common-obj-$(CONFIG_STELLARIS_ENET) += stellaris_enet.o diff --git a/hw/net/allwinner_emac.c b/hw/net/allwinner_emac.c new file mode 100644 index 000..93bad58 --- /dev/null +++ b/hw/net/allwinner_emac.c @@ -0,0 +1,532 @@ +/* + * Emulation of Allwinner EMAC Fast Ethernet controller and + * Realtek RTL8201CP PHY + * + * Copyright (C) 2014 Beniamino Galvani b.galv...@gmail.com + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; 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. + * + */ +#include hw/sysbus.h +#include net/net.h +#include qemu/fifo8.h +#include hw/net/allwinner_emac.h +#include zlib.h + +static uint8_t padding[60]; + +static void mii_set_link(RTL8201CPState *mii, bool link_ok) +{ +if (link_ok) { +mii-bmsr |= MII_BMSR_LINK_ST; +mii-anlpar |= MII_ANAR_TXFD | MII_ANAR_10FD | MII_ANAR_10 | + MII_ANAR_CSMACD; +} else { +mii-bmsr = ~MII_BMSR_LINK_ST; +mii-anlpar = MII_ANAR_TX; +} +} + +static void mii_reset(RTL8201CPState *mii, bool link_ok) +{ +mii-bmcr = MII_BMCR_FD | MII_BMCR_AUTOEN | MII_BMCR_SPEED; +mii-bmsr = MII_BMSR_100TX_FD | MII_BMSR_100TX_HD | MII_BMSR_10T_FD | +MII_BMSR_10T_HD | MII_BMSR_MFPS | MII_BMSR_AUTONEG; +mii-anar = MII_ANAR_TXFD | MII_ANAR_TX | MII_ANAR_10FD | MII_ANAR_10 | +MII_ANAR_CSMACD; +mii-anlpar = MII_ANAR_TX; + +mii_set_link(mii, link_ok); +} + +static uint16_t RTL8201CP_mdio_read(AwEmacState *s, uint8_t addr, uint8_t reg) +{ +RTL8201CPState *mii = s-mii; +uint16_t ret = 0x; + +if (addr == s-phy_addr) { +switch (reg) { +case MII_BMCR: +return mii-bmcr; +case MII_BMSR: +return mii-bmsr; +case MII_PHYID1: +return RTL8201CP_PHYID1; +case MII_PHYID2: +return RTL8201CP_PHYID2; +case MII_ANAR: +return mii-anar; +case MII_ANLPAR: +return mii-anlpar; +case MII_ANER: +case MII_NSR: +case MII_LBREMR: +case MII_REC: +case MII_SNRDR: +case MII_TEST: +qemu_log_mask(LOG_UNIMP, + allwinner_emac: read from unimpl. mii reg 0x%x\n, + reg); +return 0; +default: +qemu_log_mask(LOG_GUEST_ERROR, + allwinner_emac: read from invalid mii reg 0x%x\n, + reg); +return 0; +} +} +return ret; +} + +static void RTL8201CP_mdio_write(AwEmacState *s, uint8_t addr, uint8_t reg, + uint16_t value) +{ +RTL8201CPState *mii = s-mii; +NetClientState *nc; + +if (addr == s-phy_addr) { +switch (reg) { +case MII_BMCR: +if (value MII_BMCR_RESET) { +nc = qemu_get_queue(s-nic); +mii_reset(mii, !nc-link_down); +} else { +mii-bmcr = value; +} +break; +case MII_ANAR: +mii-anar = value; +break; +
[Qemu-devel] [PATCH v4 0/3] hw/arm: add ethernet support to Allwinner A10
This patch series adds support for the EMAC Fast Ethernet controller found on Allwinner SoCs to the Allwinner A10. Changelog: v4: Address comments from Peter Crosthwaite and Andreas Färber: * Add functions for multiple bytes push/pop to Fifo8 * Get rid of custom fifo implementation and use generic one for both tx and rx * Rename aw_emac_mdio_read - RTL8201CP_mdio_read * Allow reception of new packets from net layer only when there is space for a full size frame * Change TYPE_AW_EMAC from allwinner_emac to allwinner-emac * Property phyaddr - phy-addr * Remove trailing newlines from error_report() messages v3: Address comments from Peter Crosthwaite and Stefan Hajnoczi: * Use a single, big rx fifo instead of per-packet fifo * Remove link_ok field from PHY state * Call set_link() on post_load * Add missing PHY registers * Implement reset() method * Rename AwEmacMii - RTL8201CPState * Rename mii_{read,write} - aw_emac_mdio_{read,write} v2: Address Peter Crosthwaite's comments: * Make phy address customizable through a property * Call qemu_flush_queued_packets() when rx becomes possible * Always create EMAC instance in SoC * Use uint8 arrays for fifos * Minor cleanups Beniamino Galvani (3): util/fifo8: implement push/pop of multiple bytes hw/net: add support for Allwinner EMAC Fast Ethernet controller hw/arm/allwinner-a10: initialize EMAC default-configs/arm-softmmu.mak |1 + hw/arm/allwinner-a10.c | 16 ++ hw/arm/cubieboard.c | 11 +- hw/net/Makefile.objs|1 + hw/net/allwinner_emac.c | 532 +++ include/hw/arm/allwinner-a10.h |3 + include/hw/net/allwinner_emac.h | 211 include/qemu/fifo8.h| 43 util/fifo8.c| 44 9 files changed, 860 insertions(+), 2 deletions(-) create mode 100644 hw/net/allwinner_emac.c create mode 100644 include/hw/net/allwinner_emac.h -- 1.7.10.4
[Qemu-devel] [PATCH v4 1/3] util/fifo8: implement push/pop of multiple bytes
In some circumstances it is useful to be able to push the entire content of a memory buffer to the fifo or to pop multiple bytes with a single operation. The functions fifo8_has_space() and fifo8_push_all() added by this patch allow to perform the first kind of operation efficiently. The function fifo8_pop_buf() can be used instead to pop multiple bytes from the fifo, returning a pointer to the backing buffer. Signed-off-by: Beniamino Galvani b.galv...@gmail.com --- include/qemu/fifo8.h | 43 +++ util/fifo8.c | 44 2 files changed, 87 insertions(+) diff --git a/include/qemu/fifo8.h b/include/qemu/fifo8.h index d318f71..ea6e9f6 100644 --- a/include/qemu/fifo8.h +++ b/include/qemu/fifo8.h @@ -44,6 +44,19 @@ void fifo8_destroy(Fifo8 *fifo); void fifo8_push(Fifo8 *fifo, uint8_t data); /** + * fifo8_push_all: + * @fifo: FIFO to push to + * @data: data to push + * @size: number of bytes to push + * + * Push a byte array to the FIFO. Behaviour is undefined is the FIFO is + * full. Clients are responsible for checking the space left in the FIFO using + * fifo8_has_space(). + */ + +void fifo8_push_all(Fifo8 *fifo, const uint8_t *data, uint32_t num); + +/** * fifo8_pop: * @fifo: fifo to pop from * @@ -56,6 +69,24 @@ void fifo8_push(Fifo8 *fifo, uint8_t data); uint8_t fifo8_pop(Fifo8 *fifo); /** + * fifo8_pop_buf: + * @fifo: FIFO to pop from + * @max: maximum number of bytes to pop + * @num: actual number of returned bytes + * + * Pop a number of elements from the FIFO up to a maximum of max. The buffer + * containing the popped data is returned. This buffer points directly into + * the FIFO backing store and data is invalidated once any of the fifo8_* APIs + * are called on the FIFO. + * + * May short return, the number of valid bytes returned is populated in + * *num. Will always return at least 1 byte. + * + * Behavior is undefined if max == 0. + */ +const uint8_t *fifo8_pop_buf(Fifo8 *fifo, uint32_t max, uint32_t *num); + +/** * fifo8_reset: * @fifo: FIFO to reset * @@ -86,6 +117,18 @@ bool fifo8_is_empty(Fifo8 *fifo); bool fifo8_is_full(Fifo8 *fifo); +/** + * fifo8_has_space: + * @fifo: FIFO to check + * @num: number of bytes + * + * Check if a given number of bytes can be pushed to a FIFO. + * + * Returns: True if the fifo can hold the given elements, false otherwise. + */ + +bool fifo8_has_space(Fifo8 *fifo, uint32_t num); + extern const VMStateDescription vmstate_fifo8; #define VMSTATE_FIFO8(_field, _state) { \ diff --git a/util/fifo8.c b/util/fifo8.c index 013e903..2808169 100644 --- a/util/fifo8.c +++ b/util/fifo8.c @@ -15,6 +15,8 @@ #include qemu-common.h #include qemu/fifo8.h +#define min(a, b) ((a) (b) ? (a) : (b)) + void fifo8_create(Fifo8 *fifo, uint32_t capacity) { fifo-data = g_new(uint8_t, capacity); @@ -37,6 +39,27 @@ void fifo8_push(Fifo8 *fifo, uint8_t data) fifo-num++; } +void fifo8_push_all(Fifo8 *fifo, const uint8_t *data, uint32_t num) +{ +uint32_t start, avail; + +if (fifo-num + num fifo-capacity) { +abort(); +} + +start = (fifo-head + fifo-num) % fifo-capacity; + +if (start + num = fifo-capacity) { +memcpy(fifo-data[start], data, num); +} else { +avail = fifo-capacity - start; +memcpy(fifo-data[start], data, avail); +memcpy(fifo-data[0], data[avail], num - avail); +} + +fifo-num += num; +} + uint8_t fifo8_pop(Fifo8 *fifo) { uint8_t ret; @@ -50,9 +73,25 @@ uint8_t fifo8_pop(Fifo8 *fifo) return ret; } +const uint8_t *fifo8_pop_buf(Fifo8 *fifo, uint32_t max, uint32_t *num) +{ +uint8_t *ret; + +*num = min(fifo-capacity - fifo-head, max); +*num = min(*num, fifo-num); + +ret = fifo-data[fifo-head]; + +fifo-head += *num; +fifo-head %= fifo-capacity; + +return ret; +} + void fifo8_reset(Fifo8 *fifo) { fifo-num = 0; +fifo-head = 0; } bool fifo8_is_empty(Fifo8 *fifo) @@ -65,6 +104,11 @@ bool fifo8_is_full(Fifo8 *fifo) return (fifo-num == fifo-capacity); } +bool fifo8_has_space(Fifo8 *fifo, uint32_t num) +{ +return (fifo-num + num = fifo-capacity); +} + const VMStateDescription vmstate_fifo8 = { .name = Fifo8, .version_id = 1, -- 1.7.10.4
[Qemu-devel] [PATCH v4 3/3] hw/arm/allwinner-a10: initialize EMAC
Signed-off-by: Beniamino Galvani b.galv...@gmail.com --- hw/arm/allwinner-a10.c | 16 hw/arm/cubieboard.c| 11 +-- include/hw/arm/allwinner-a10.h |3 +++ 3 files changed, 28 insertions(+), 2 deletions(-) diff --git a/hw/arm/allwinner-a10.c b/hw/arm/allwinner-a10.c index 4658e19..01206f2 100644 --- a/hw/arm/allwinner-a10.c +++ b/hw/arm/allwinner-a10.c @@ -31,6 +31,13 @@ static void aw_a10_init(Object *obj) object_initialize(s-timer, sizeof(s-timer), TYPE_AW_A10_PIT); qdev_set_parent_bus(DEVICE(s-timer), sysbus_get_default()); + +object_initialize(s-emac, sizeof(s-emac), TYPE_AW_EMAC); +qdev_set_parent_bus(DEVICE(s-emac), sysbus_get_default()); +if (nd_table[0].used) { +qemu_check_nic_model(nd_table[0], TYPE_AW_EMAC); +qdev_set_nic_properties(DEVICE(s-emac), nd_table[0]); +} } static void aw_a10_realize(DeviceState *dev, Error **errp) @@ -76,6 +83,15 @@ static void aw_a10_realize(DeviceState *dev, Error **errp) sysbus_connect_irq(sysbusdev, 4, s-irq[67]); sysbus_connect_irq(sysbusdev, 5, s-irq[68]); +object_property_set_bool(OBJECT(s-emac), true, realized, err); +if (err != NULL) { +error_propagate(errp, err); +return; +} +sysbusdev = SYS_BUS_DEVICE(s-emac); +sysbus_mmio_map(sysbusdev, 0, AW_A10_EMAC_BASE); +sysbus_connect_irq(sysbusdev, 0, s-irq[55]); + serial_mm_init(get_system_memory(), AW_A10_UART0_REG_BASE, 2, s-irq[1], 115200, serial_hds[0], DEVICE_NATIVE_ENDIAN); } diff --git a/hw/arm/cubieboard.c b/hw/arm/cubieboard.c index 3fcb6d2..d95a7f3 100644 --- a/hw/arm/cubieboard.c +++ b/hw/arm/cubieboard.c @@ -36,10 +36,17 @@ static void cubieboard_init(QEMUMachineInitArgs *args) Error *err = NULL; s-a10 = AW_A10(object_new(TYPE_AW_A10)); + +object_property_set_int(OBJECT(s-a10-emac), 1, phy-addr, err); +if (err != NULL) { +error_report(Couldn't set phy address: %s, error_get_pretty(err)); +exit(1); +} + object_property_set_bool(OBJECT(s-a10), true, realized, err); if (err != NULL) { -error_report(Couldn't realize Allwinner A10: %s\n, -error_get_pretty(err)); +error_report(Couldn't realize Allwinner A10: %s, + error_get_pretty(err)); exit(1); } diff --git a/include/hw/arm/allwinner-a10.h b/include/hw/arm/allwinner-a10.h index da36647..01a189b 100644 --- a/include/hw/arm/allwinner-a10.h +++ b/include/hw/arm/allwinner-a10.h @@ -6,6 +6,7 @@ #include hw/arm/arm.h #include hw/timer/allwinner-a10-pit.h #include hw/intc/allwinner-a10-pic.h +#include hw/net/allwinner_emac.h #include sysemu/sysemu.h #include exec/address-spaces.h @@ -14,6 +15,7 @@ #define AW_A10_PIC_REG_BASE 0x01c20400 #define AW_A10_PIT_REG_BASE 0x01c20c00 #define AW_A10_UART0_REG_BASE 0x01c28000 +#define AW_A10_EMAC_BASE0x01c0b000 #define AW_A10_SDRAM_BASE 0x4000 @@ -29,6 +31,7 @@ typedef struct AwA10State { qemu_irq irq[AW_A10_PIC_INT_NR]; AwA10PITState timer; AwA10PICState intc; +AwEmacState emac; } AwA10State; #define ALLWINNER_H_ -- 1.7.10.4
[Qemu-devel] [Bug 1272796] Re: Windows 98 First Edition emulation problems
Even with Windows 98 SE (English and Italian) still not working. Got some ideas? -- You received this bug notification because you are a member of qemu- devel-ml, which is subscribed to QEMU. https://bugs.launchpad.net/bugs/1272796 Title: Windows 98 First Edition emulation problems Status in QEMU: New Bug description: System: Debian SID x86 with latest updates 1) QEMU compiled from latest main GIT branch(at the time of writing, 1.7.50) (and 1.7 stable version) ./configure options: ./configure --enable-sdl --target-list=i386-softmmu --cpu=i686 --audio-drv-list=alsa When you try to boot Windows 98 First Edition (Italian), it does not simply boot. It stays on booting screen. If you try to install, the installation goes flawless, but when it boots it freeze. I am launching VM with this: qemu-system-i386 -hda main.img -cpu pentium -m 256 -fda floppy1.img -boot c -soundhw gus -vga cirrus I have tried with -M option pc-i440fx-1.6 since 1.6 have no problems with the booting of Win98, but nothing. No fix found. 2) QEMU 1.6.2 (same compile and launching options) gus soundboard seems not recognized even with real dos drivers (tried to install theme into real dos mode). with SoundBlaster 16 i have following error: WARNING: I/O thread spun for 1000 iterations, making the emulation impossible (too slow, and sound is stuttering) . Tried to compile with oss and sdl option on audio-drv-list but no fix found. Any ideas? thank you To manage notifications about this bug go to: https://bugs.launchpad.net/qemu/+bug/1272796/+subscriptions
Re: [Qemu-devel] [PATCH v3] Fix QEMU build on OpenBSD on x86 archs
On Sun, Jan 26, 2014 at 1:40 PM, Brad Smith b...@comstyle.com wrote: On 26/01/14 1:06 PM, Paolo Bonzini wrote: Il 26/01/2014 02:37, Brad Smith ha scritto: Reviewed-by: Stefan Hajnoczi stefa...@redhat.com Is there some sort of process I am missing to have build fixes commited so that QEMU actually builds? Right now we have problems getting patches committed at all. This patch and the other NetBSD patch is not lost. I know it is not literally lost. I don't follow the list that closely.. what was the reason for there being two incidents over the last 2 months of there being no commits for over a week (at least from the perspective of git.qemu.org)? Historically, having multiple committers has avoided this problem because when one person gets bogged down, there's someone else to step up. Right now, it seems all current committers are in a bogged down state. I've added another committer, Peter Maydell, to try to break the log jam. I'll try to devote more time to applying patches but hopefully with Peter's help too, we can get things moving at the appropriate speed again. Regards, Anthony Liguori -- This message has been scanned for viruses and dangerous content by MailScanner, and is believed to be clean.
[Qemu-devel] Additional QEMU committer
Hi, Things have been moving a bit more slowly upstream than the should recently. I'm happy to announce though that Peter Maydell has agreed to take on the responsibility of being a committer and will now be able to apply pull requests and push patches. I will continue to apply pull requests and patches when I can but Peter will also be doing the same to make sure things move at a more constant pace. Big thanks to Peter for volunteering and for everyone for having patience over the last couple months. Regards, Anthony Liguori
Re: [Qemu-devel] [PATCH v3] Fix QEMU build on OpenBSD on x86 archs
On 26/01/14 5:12 PM, Anthony Liguori wrote: On Sun, Jan 26, 2014 at 1:40 PM, Brad Smith b...@comstyle.com wrote: On 26/01/14 1:06 PM, Paolo Bonzini wrote: Il 26/01/2014 02:37, Brad Smith ha scritto: Reviewed-by: Stefan Hajnoczi stefa...@redhat.com Is there some sort of process I am missing to have build fixes commited so that QEMU actually builds? Right now we have problems getting patches committed at all. This patch and the other NetBSD patch is not lost. I know it is not literally lost. I don't follow the list that closely.. what was the reason for there being two incidents over the last 2 months of there being no commits for over a week (at least from the perspective of git.qemu.org)? Historically, having multiple committers has avoided this problem because when one person gets bogged down, there's someone else to step up. Right now, it seems all current committers are in a bogged down state. I've added another committer, Peter Maydell, to try to break the log jam. I'll try to devote more time to applying patches but hopefully with Peter's help too, we can get things moving at the appropriate speed again. Ok, I see. Thank you for the response. -- This message has been scanned for viruses and dangerous content by MailScanner, and is believed to be clean.
Re: [Qemu-devel] [PATCH 01/10] block: Change BDS parameter of bdrv_open() to **
Le Sunday 26 Jan 2014 à 20:02:34 (+0100), Max Reitz a écrit : Make bdrv_open() take a pointer to a BDS pointer, similarly to bdrv_file_open(). If a pointer to a NULL pointer is given, bdrv_open() will create a new BDS with an empty name; if the BDS pointer is not NULL, that existing BDS will be reused (in the same way as bdrv_open() already did). Signed-off-by: Max Reitz mre...@redhat.com --- block.c | 53 ++- block/qcow2.c | 14 +- block/vmdk.c | 5 ++--- block/vvfat.c | 6 ++ blockdev.c| 21 hw/block/xen_disk.c | 2 +- include/block/block.h | 2 +- qemu-img.c| 6 +++--- qemu-io.c | 2 +- qemu-nbd.c| 2 +- 10 files changed, 55 insertions(+), 58 deletions(-) diff --git a/block.c b/block.c index cb21a5f..c660609 100644 --- a/block.c +++ b/block.c @@ -1039,7 +1039,7 @@ int bdrv_file_open(BlockDriverState **pbs, const char *filename, } if (!drv-bdrv_file_open) { -ret = bdrv_open(bs, filename, options, flags, drv, local_err); +ret = bdrv_open(bs, filename, options, flags, drv, local_err); options = NULL; } else { ret = bdrv_open_common(bs, NULL, options, flags, drv, local_err); @@ -1108,8 +1108,6 @@ int bdrv_open_backing_file(BlockDriverState *bs, QDict *options, Error **errp) sizeof(backing_filename)); } -bs-backing_hd = bdrv_new(); - if (bs-backing_format[0] != '\0') { back_drv = bdrv_find_format(bs-backing_format); } @@ -1118,11 +1116,10 @@ int bdrv_open_backing_file(BlockDriverState *bs, QDict *options, Error **errp) back_flags = bs-open_flags ~(BDRV_O_RDWR | BDRV_O_SNAPSHOT | BDRV_O_COPY_ON_READ); -ret = bdrv_open(bs-backing_hd, +ret = bdrv_open(bs-backing_hd, *backing_filename ? backing_filename : NULL, options, back_flags, back_drv, local_err); if (ret 0) { -bdrv_unref(bs-backing_hd); bs-backing_hd = NULL; bs-open_flags |= BDRV_O_NO_BACKING; error_setg(errp, Could not open backing file: %s, @@ -1189,8 +1186,6 @@ int bdrv_open_image(BlockDriverState **pbs, const char *filename, /* If a filename is given and the block driver should be detected automatically (instead of using none), use bdrv_open() in order to do that auto-detection. */ -BlockDriverState *bs; - if (reference) { error_setg(errp, Cannot reference an existing block device while giving a filename); @@ -1198,13 +1193,8 @@ int bdrv_open_image(BlockDriverState **pbs, const char *filename, goto done; } -bs = bdrv_new(); -ret = bdrv_open(bs, filename, image_options, flags, NULL, errp); -if (ret 0) { -bdrv_unref(bs); -} else { -*pbs = bs; -} +*pbs = NULL; bdrv_open set *file = NULL before calling bdrv_open_image so this is redundant. What would be the correct behavior if the caller was giving *pbs != NULL ? Is loosing the reference to a previously existing bds right ? +ret = bdrv_open(pbs, filename, image_options, flags, NULL, errp); } else { ret = bdrv_file_open(pbs, filename, reference, image_options, flags, errp); @@ -1222,14 +1212,17 @@ done: * empty set of options. The reference to the QDict belongs to the block layer * after the call (even on failure), so if the caller intends to reuse the * dictionary, it needs to use QINCREF() before calling bdrv_open. + * + * If *pbs is NULL, a new BDS will be created with a pointer to it stored there. + * If it is not NULL, the referenced BDS will be reused. */ -int bdrv_open(BlockDriverState *bs, const char *filename, QDict *options, +int bdrv_open(BlockDriverState **pbs, const char *filename, QDict *options, int flags, BlockDriver *drv, Error **errp) { int ret; /* TODO: extra byte is a hack to ensure MAX_PATH space on Windows. */ char tmp_filename[PATH_MAX + 1]; -BlockDriverState *file = NULL; +BlockDriverState *file = NULL, *bs = NULL; const char *drvname; Error *local_err = NULL; @@ -1238,12 +1231,17 @@ int bdrv_open(BlockDriverState *bs, const char *filename, QDict *options, options = qdict_new(); } +if (*pbs) { +bs = *pbs; +} else { +bs = bdrv_new(); +} bs-options = options; options = qdict_clone_shallow(options); /* For snapshot=on, create a temporary qcow2 overlay */ if (flags BDRV_O_SNAPSHOT) { -BlockDriverState *bs1; +BlockDriverState *bs1 = NULL;
[Qemu-devel] [Qemu/Virtio-scsi]The feature of 'raw device mapping' cannot isolate the LUN to the owning virtual machine
Hi,all A instance was created by virsh command in the CentOS 6.4. The LUN in the Storage Array Network(SAN) was attached to the instance with the following xml. disk type='block' device='lun' driver name='qemu' type='raw' cache='none'/ source dev='/dev/mapper/360022a11ecba5db427db0023'/ target dev='vdb' bus='virtio'/ address type='pci' domain='0x' bus='0x00' slot='0x06' function='0x0'/ /disk controller type='scsi' model='virtio-scsi'/ A scsi report command was executed in the instance, for example sg_luns /dev/vdb. However, It returned the list of the Luns in the SAN. 1) The unrelated luns in the SAN were not isolated in the instance. [root@localhost ~]# sg_luns /dev/vdb Lun list length = 80 which imples 10 lun entries Report luns [select_report=0]: 0001 0002 0003 0004 0005 0006 0007 0008 0009 [root@localhost ~]#sg_map Stopping because no sg device found [root@localhost ~]# [root@localhost ~]# [cid:image009.png@01CF1B49.A36DAC30] 2) The report lun command in the physical server: [root@qixiaozhen sdb]# sg_luns /dev/mapper/360022a11ecba5db427db0023 Lun list length = 80 which imples 10 lun entries Report luns [select_report=0x0]: 0001 0002 0003 0004 0005 0006 0007 0008 0009 [root@qixiaozhen sdb]# Is there any security problem if the report lun command was not isolated ? Sincerely, Qi --- Xiaozhen Qi Huawei Technologies Co.,LTD. IT Product Line CloudOS PDU China, Xi'an Mobile: +86-13609283376 Email: qixiaoz...@huawei.com inline: image009.png
Re: [Qemu-devel] [PATCH 03/10] block: Make bdrv_file_open() static
Le Sunday 26 Jan 2014 à 20:02:36 (+0100), Max Reitz a écrit : Add the bdrv_open() option BDRV_O_PROTOCOL which results in passing the call to bdrv_file_open(). Additionally, make bdrv_file_open() static and therefore bdrv_open() the only way to call it. Consequently, all existing calls to bdrv_file_open() have to be adjusted to use bdrv_open() with the BDRV_O_PROTOCOL flag instead. Signed-off-by: Max Reitz mre...@redhat.com --- block.c | 17 - block/cow.c | 6 +++--- block/qcow.c | 6 +++--- block/qcow2.c | 5 +++-- block/qed.c | 5 +++-- block/sheepdog.c | 8 +--- block/vhdx.c | 5 +++-- block/vmdk.c | 11 +++ include/block/block.h | 5 ++--- qemu-io.c | 4 +++- 10 files changed, 44 insertions(+), 28 deletions(-) diff --git a/block.c b/block.c index f9923bb..0fb7892 100644 --- a/block.c +++ b/block.c @@ -947,9 +947,9 @@ free_and_fail: * after the call (even on failure), so if the caller intends to reuse the * dictionary, it needs to use QINCREF() before calling bdrv_file_open. */ -int bdrv_file_open(BlockDriverState **pbs, const char *filename, - const char *reference, QDict *options, int flags, - Error **errp) +static int bdrv_file_open(BlockDriverState **pbs, const char *filename, + const char *reference, QDict *options, int flags, + Error **errp) { BlockDriverState *bs = NULL; BlockDriver *drv; @@ -1196,8 +1196,9 @@ int bdrv_open_image(BlockDriverState **pbs, const char *filename, *pbs = NULL; ret = bdrv_open(pbs, filename, NULL, image_options, flags, NULL, errp); } else { -ret = bdrv_file_open(pbs, filename, reference, image_options, flags, - errp); +*pbs = NULL; +ret = bdrv_open(pbs, filename, reference, image_options, +flags | BDRV_O_PROTOCOL, NULL, errp); } done: @@ -1227,6 +1228,12 @@ int bdrv_open(BlockDriverState **pbs, const char *filename, const char *drvname; Error *local_err = NULL; +if (flags BDRV_O_PROTOCOL) { +assert(!drv); +return bdrv_file_open(pbs, filename, reference, options, + flags ~BDRV_O_PROTOCOL, errp); +} + /* NULL means an empty set of options */ if (options == NULL) { options = qdict_new(); diff --git a/block/cow.c b/block/cow.c index 7fc0b12..f0748a2 100644 --- a/block/cow.c +++ b/block/cow.c @@ -332,7 +332,7 @@ static int cow_create(const char *filename, QEMUOptionParameter *options, const char *image_filename = NULL; Error *local_err = NULL; int ret; -BlockDriverState *cow_bs; +BlockDriverState *cow_bs = NULL; /* Read out options */ while (options options-name) { @@ -351,8 +351,8 @@ static int cow_create(const char *filename, QEMUOptionParameter *options, return ret; } -ret = bdrv_file_open(cow_bs, filename, NULL, NULL, BDRV_O_RDWR, - local_err); +ret = bdrv_open(cow_bs, filename, NULL, NULL, +BDRV_O_RDWR | BDRV_O_PROTOCOL, NULL, local_err); if (ret 0) { qerror_report_err(local_err); error_free(local_err); diff --git a/block/qcow.c b/block/qcow.c index 948b0c5..4881d84 100644 --- a/block/qcow.c +++ b/block/qcow.c @@ -670,7 +670,7 @@ static int qcow_create(const char *filename, QEMUOptionParameter *options, int flags = 0; Error *local_err = NULL; int ret; -BlockDriverState *qcow_bs; +BlockDriverState *qcow_bs = NULL; /* Read out options */ while (options options-name) { @@ -691,8 +691,8 @@ static int qcow_create(const char *filename, QEMUOptionParameter *options, return ret; } -ret = bdrv_file_open(qcow_bs, filename, NULL, NULL, BDRV_O_RDWR, - local_err); +ret = bdrv_open(qcow_bs, filename, NULL, NULL, +BDRV_O_RDWR | BDRV_O_PROTOCOL, NULL, local_err); if (ret 0) { qerror_report_err(local_err); error_free(local_err); diff --git a/block/qcow2.c b/block/qcow2.c index 7202a26..40b957b 100644 --- a/block/qcow2.c +++ b/block/qcow2.c @@ -1479,7 +1479,7 @@ static int qcow2_create2(const char *filename, int64_t total_size, * 2 GB for 64k clusters, and we don't want to have a 2 GB initial file * size for any qcow2 image. */ -BlockDriverState* bs; +BlockDriverState *bs = NULL; QCowHeader *header; uint8_t* refcount_table; Error *local_err = NULL; @@ -1491,7 +1491,8 @@ static int qcow2_create2(const char *filename, int64_t total_size, return ret; } -ret = bdrv_file_open(bs, filename, NULL, NULL, BDRV_O_RDWR,
Re: [Qemu-devel] [PATCH 04/10] block: Reuse NULL options check from bdrv_open()
Le Sunday 26 Jan 2014 à 20:02:37 (+0100), Max Reitz a écrit : Remove the check whether options is NULL form bdrv_file_open() and rely s/form/for/g ? on the one in bdrv_open() instead. Signed-off-by: Max Reitz mre...@redhat.com --- block.c | 15 +-- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/block.c b/block.c index 0fb7892..c7219cb 100644 --- a/block.c +++ b/block.c @@ -958,11 +958,6 @@ static int bdrv_file_open(BlockDriverState **pbs, const char *filename, Error *local_err = NULL; int ret; -/* NULL means an empty set of options */ -if (options == NULL) { -options = qdict_new(); -} - if (reference) { if (filename || qdict_size(options)) { error_setg(errp, Cannot reference an existing block device with @@ -1228,17 +1223,17 @@ int bdrv_open(BlockDriverState **pbs, const char *filename, const char *drvname; Error *local_err = NULL; +/* NULL means an empty set of options */ +if (options == NULL) { +options = qdict_new(); +} + if (flags BDRV_O_PROTOCOL) { assert(!drv); return bdrv_file_open(pbs, filename, reference, options, flags ~BDRV_O_PROTOCOL, errp); } -/* NULL means an empty set of options */ -if (options == NULL) { -options = qdict_new(); -} - if (reference) { bool options_non_empty = qdict_size(options); QDECREF(options); -- 1.8.5.3 Reviewed-by: Benoit Canet ben...@irqsave.net
Re: [Qemu-devel] [PATCH 05/10] block: Reuse reference handling from bdrv_open()
Le Sunday 26 Jan 2014 à 20:02:38 (+0100), Max Reitz a écrit : Remove the reference parameter and the related handling code from bdrv_file_open(), since it exists in bdrv_open() now as well. Signed-off-by: Max Reitz mre...@redhat.com --- block.c | 33 +++-- 1 file changed, 7 insertions(+), 26 deletions(-) diff --git a/block.c b/block.c index c7219cb..6c29115 100644 --- a/block.c +++ b/block.c @@ -948,8 +948,7 @@ free_and_fail: * dictionary, it needs to use QINCREF() before calling bdrv_file_open. */ static int bdrv_file_open(BlockDriverState **pbs, const char *filename, - const char *reference, QDict *options, int flags, - Error **errp) + QDict *options, int flags, Error **errp) { BlockDriverState *bs = NULL; BlockDriver *drv; @@ -958,24 +957,6 @@ static int bdrv_file_open(BlockDriverState **pbs, const char *filename, Error *local_err = NULL; int ret; -if (reference) { -if (filename || qdict_size(options)) { -error_setg(errp, Cannot reference an existing block device with - additional options or a new filename); -return -EINVAL; -} -QDECREF(options); - -bs = bdrv_find(reference); -if (!bs) { -error_setg(errp, Cannot find block device '%s', reference); -return -ENODEV; -} -bdrv_ref(bs); -*pbs = bs; -return 0; -} - bs = bdrv_new(); bs-options = options; options = qdict_clone_shallow(options); @@ -1228,12 +1209,6 @@ int bdrv_open(BlockDriverState **pbs, const char *filename, options = qdict_new(); } -if (flags BDRV_O_PROTOCOL) { -assert(!drv); -return bdrv_file_open(pbs, filename, reference, options, - flags ~BDRV_O_PROTOCOL, errp); -} - if (reference) { bool options_non_empty = qdict_size(options); QDECREF(options); @@ -1260,6 +1235,12 @@ int bdrv_open(BlockDriverState **pbs, const char *filename, return 0; } +if (flags BDRV_O_PROTOCOL) { +assert(!drv); +return bdrv_file_open(pbs, filename, options, flags ~BDRV_O_PROTOCOL, + errp); +} + if (*pbs) { bs = *pbs; } else { -- 1.8.5.3 Reviewed-by: Benoit Canet ben...@irqsave.net
Re: [Qemu-devel] [PATCH 06/10] block: Remove bdrv_new() from bdrv_file_open()
Le Sunday 26 Jan 2014 à 20:02:39 (+0100), Max Reitz a écrit : Change bdrv_file_open() to take a simple pointer to an already existing BDS instead of an indirect one. The BDS will be created in bdrv_open() if necessary. Signed-off-by: Max Reitz mre...@redhat.com --- block.c | 29 ++--- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/block.c b/block.c index 6c29115..72eddd5 100644 --- a/block.c +++ b/block.c @@ -947,17 +947,15 @@ free_and_fail: * after the call (even on failure), so if the caller intends to reuse the * dictionary, it needs to use QINCREF() before calling bdrv_file_open. */ -static int bdrv_file_open(BlockDriverState **pbs, const char *filename, +static int bdrv_file_open(BlockDriverState *bs, const char *filename, QDict *options, int flags, Error **errp) { -BlockDriverState *bs = NULL; BlockDriver *drv; const char *drvname; bool allow_protocol_prefix = false; Error *local_err = NULL; int ret; -bs = bdrv_new(); bs-options = options; options = qdict_clone_shallow(options); @@ -1036,7 +1034,6 @@ static int bdrv_file_open(BlockDriverState **pbs, const char *filename, QDECREF(options); bs-growable = 1; -*pbs = bs; return 0; fail: @@ -1044,7 +1041,6 @@ fail: if (!bs-drv) { QDECREF(bs-options); } -bdrv_unref(bs); return ret; } @@ -1235,17 +1231,28 @@ int bdrv_open(BlockDriverState **pbs, const char *filename, return 0; } -if (flags BDRV_O_PROTOCOL) { -assert(!drv); -return bdrv_file_open(pbs, filename, options, flags ~BDRV_O_PROTOCOL, - errp); -} - if (*pbs) { bs = *pbs; } else { bs = bdrv_new(); } + +if (flags BDRV_O_PROTOCOL) { +assert(!drv); +ret = bdrv_file_open(bs, filename, options, flags ~BDRV_O_PROTOCOL, + errp); +if (ret) { +if (*pbs) { +bdrv_close(bs); +} else { +bdrv_unref(bs); +} Can the goto chain be factorized with this snippet of code: something like this is already in it ? Something like if (!ret) { return ret; } goto exit_close_or_unref; +} else { +*pbs = bs; +} +return ret; +} + bs-options = options; options = qdict_clone_shallow(options); -- 1.8.5.3