Re: [Qemu-devel] [PATCH 05/30] exec: do not use qemu/tls.h
On 28 June 2013 19:26, Paolo Bonzini wrote: > The next patch will change qemu/tls.h to support more platforms, but at > some performance cost. Declare cpu_single_env directly instead of using > the tls.h abstractions. > > Signed-off-by: Paolo Bonzini > --- > exec.c | 10 -- > include/exec/cpu-all.h | 14 +++--- > include/qemu/tls.h | 52 > -- > 3 files changed, 19 insertions(+), 57 deletions(-) > delete mode 100644 include/qemu/tls.h > > diff --git a/exec.c b/exec.c > index d28403b..a788981 100644 > --- a/exec.c > +++ b/exec.c > @@ -70,9 +70,15 @@ static MemoryRegion io_mem_unassigned; > #endif > > CPUArchState *first_cpu; > + > /* current CPU in the current thread. It is only valid inside > - cpu_exec() */ > -DEFINE_TLS(CPUArchState *,cpu_single_env); > + * cpu_exec(). See comment in include/exec/cpu-all.h. */ > +#if defined CONFIG_KVM || (defined CONFIG_USER_ONLY && defined > CONFIG_USE_NPTL) > +__thread CPUArchState *cpu_single_env; > +#else > +CPUArchState *cpu_single_env; > +#endif I don't like having the semantics of this variable differ depending on whether CONFIG_KVM was defined. In particular this means that the variable is per-thread if you're running TCG on a QEMU that was configured with KVM support, but not per-thread if you're running TCG on a QEMU that was configured without per-thread support. That's just bizarre and a recipe for confusion and for bugs creeping in in the less-well-tested config combinations. We should just be consistent and always make this be per-thread. thanks -- PMM
Re: [Qemu-devel] [PATCH v4 00/11] Fix versatile_pci
On 28 June 2013 08:01, Rob Landley wrote: > Now that the next kernel's about to come out, I'm trying to get my arm > versatile image to work under qemu 1.5.0. The old kernel doesn't work, and > the current vanilla kernel doesn't work. This change broke it. > > I'm testing current linux-git both with and without this patch: > > --- linux/arch/arm/mach-versatile/pci.c 2013-04-28 19:36:01.0 -0500 > +++ linux.bak/arch/arm/mach-versatile/pci.c 2013-04-29 > 19:09:44.857097553 -0500 > @@ -333,7 +333,7 @@ > * 26 1 IRQ_SIC_PCI2 > * 27 1 IRQ_SIC_PCI3 > */ > - irq = IRQ_SIC_PCI0 + ((slot - 24 + pin - 1) & 3); > + irq = 59; //IRQ_SIC_PCI0 + ((slot - 24 + pin - 1) & 3); > > return irq; > } > > With the patch, qemu 1.2.0 works, but qemu 1.5 versatile does not work with > or without the patch. The "with the patch" case is uninteresting, because it's not actually a fix for anything, it's just a change that happened to work with old QEMU, and it's not a change that is in upstream Linux. > Here's a test image to demonstrate the problem: it works fine under qemu > 1.2.0, but doesn't under 1.5.0: > > http://landley.net/aboriginal/bin/system-image-armv5l.tar.bz2 > > Extract it and ./run-emulator.sh. You get a shell prompt from 1.2.0, from > 1.5.0 it never gets a scsi interrupt, and after a timeout goes into an > abort/reset loop. Is this an image with your patch or without it? Does it work if you use the -global option to force legacy IRQ mapping? >> >> This version of the patchset avoids breaking legacy Linux guests >> >> by automatically detecting those broken kernels and switching back >> >> to the old mapping. > > > As testing with the above image confirms: it does not. I tested with several separate variants of the Linux kernel. >> >> This works by looking at the values the kernel >> >> writes to the PCI_INTERRUPT_LINE register in the config space, which >> >> is effectively the interrupt number the kernel expects the device >> >> to be using. If this doesn't match reality we use the broken mapping. >> >> (Thanks to Michael S. Tsirkin for this suggestion.) > > > Define "reality". "would work on real hardware". > The kernel changed what irqs it was expecting _three_times_ last year, and > as far as I can tell none of them were what they were _trying_ to do. > > Here's my blog entry and the source control comments where I diagnosed this > stuff to show that the kernel guys have no flipping CLUE how an arm > versatile board actually works: I agree that the kernel has made a bit of a mess in this area, so we don't need to have that argument again. > The kernel code in this area is CRAP, has changed multiple times in > semi-random ways, has obviously NEVER been tested on real hardware, and if > you've implemented what the actual versatile documentation says it's clearly > not what the kernel is doing. I tested these changes against a patchset which Arnd wrote which I can guarantee was tested on real hardware because I did the testing myself. > Do you have a kernel that runs under current qemu arm versatile emulation? I > can poke around and figure out which irqs it expects _now_, but it's not > "right" and presumably you're just going to change it again when you realize > what qemu is doing and what the unpatched kernel is doing don't match. The ones on http://people.debian.org/~aurel32/qemu/armel/ should work. -- PMM
Re: [Qemu-devel] [Bug 1195882] Re: Make fails on Centos - can't find autoreconf
On Saturday 29 June 2013 00:12:17 you wrote: > > As far as I know, autoreconf does not exist in the red > > hat/fedora/centos world. > > > > Can't find a yum, rpm. or other distro for it on the above os. > > You aren't looking very hard; on my RHEL 6.4 box (which has the same > packages as what you can install in CentOS), I see: > > $ rpm -qf `which autoreconf` > autoconf-2.63-5.1.el6.noarch > You're right.Also installed automake which supplies an 'aclocal' executable that's not in the autoconf distro, and libtool to fix a 'possibly undefined macro AC_LIBTOOL' issue. Seems to be happily compiling/linking now. My apologies for the pseudo-bug report. BTW, thank you for your assistance. /Todd -- You received this bug notification because you are a member of qemu- devel-ml, which is subscribed to QEMU. https://bugs.launchpad.net/bugs/1195882 Title: Make fails on Centos - can't find autoreconf Status in QEMU: New Bug description: [root@H002 qemu-1.4.2]# make \ GEN i386-softmmu/config-devices.mak GEN x86_64-softmmu/config-devices.mak GEN alpha-softmmu/config-devices.mak GEN arm-softmmu/config-devices.mak GEN cris-softmmu/config-devices.mak GEN lm32-softmmu/config-devices.mak ( ) GEN unicore32-linux-user/config-devices.mak GEN s390x-linux-user/config-devices.mak GEN config-all-devices.mak GEN config-host.h (cd /opt/qemu/qemu-1.4.2/pixman; autoreconf -v --install) /bin/sh: autoreconf: command not found make: *** [/opt/qemu/qemu-1.4.2/pixman/configure] Error 127 * Exact same error for 1.5.1 build So, qemu not supported on anything but Ubuntu? To manage notifications about this bug go to: https://bugs.launchpad.net/qemu/+bug/1195882/+subscriptions
Re: [Qemu-devel] [Bug 1195882] Re: Make fails on Centos - can't find autoreconf
On Friday 28 June 2013 18:20:29 you wrote: > autoreconf is part of the autoconf package. Do you have that installed? > Hi, Thanks for the response. You're right, it was the lack of autoconf. Actually, on CentOS/RH, you need to check for autoconf automake (includes autoconf?) libtools Seems to be building happily now. Sorry for the newbie question. /T. -- You received this bug notification because you are a member of qemu- devel-ml, which is subscribed to QEMU. https://bugs.launchpad.net/bugs/1195882 Title: Make fails on Centos - can't find autoreconf Status in QEMU: New Bug description: [root@H002 qemu-1.4.2]# make \ GEN i386-softmmu/config-devices.mak GEN x86_64-softmmu/config-devices.mak GEN alpha-softmmu/config-devices.mak GEN arm-softmmu/config-devices.mak GEN cris-softmmu/config-devices.mak GEN lm32-softmmu/config-devices.mak ( ) GEN unicore32-linux-user/config-devices.mak GEN s390x-linux-user/config-devices.mak GEN config-all-devices.mak GEN config-host.h (cd /opt/qemu/qemu-1.4.2/pixman; autoreconf -v --install) /bin/sh: autoreconf: command not found make: *** [/opt/qemu/qemu-1.4.2/pixman/configure] Error 127 * Exact same error for 1.5.1 build So, qemu not supported on anything but Ubuntu? To manage notifications about this bug go to: https://bugs.launchpad.net/qemu/+bug/1195882/+subscriptions
Re: [Qemu-devel] [PATCH] highbank: add initial Calxeda Midway A15 support
Am 28.06.2013 13:59, schrieb Andre Przywara: > From: Rob Herring > > While the Calxeda Midway part is actually a bit more than a "Highbank > with A15s", for QEMU's purposes this view is sufficient. So to allow > both emulation with that chip as well as KVM guests using that model > add an A15 CPU and it's peripherals as an option. The use of: > "-M highbank -cpu cortex-a15" simply gives the new chip without the > need for a new model. > > Signed-off-by: Rob Herring > Signed-off-by: Andre Przywara > --- > hw/arm/highbank.c | 19 +-- > 1 file changed, 13 insertions(+), 6 deletions(-) > > diff --git a/hw/arm/highbank.c b/hw/arm/highbank.c > index 4405dbd..ed864c6 100644 > --- a/hw/arm/highbank.c > +++ b/hw/arm/highbank.c > @@ -196,6 +196,7 @@ static void highbank_init(QEMUMachineInitArgs *args) > const char *kernel_filename = args->kernel_filename; > const char *kernel_cmdline = args->kernel_cmdline; > const char *initrd_filename = args->initrd_filename; > +CPUARMState *env = NULL; > DeviceState *dev; > SysBusDevice *busdev; > qemu_irq *irqp; > @@ -223,6 +224,8 @@ static void highbank_init(QEMUMachineInitArgs *args) > cpu->reset_cbar = GIC_BASE_ADDR; > irqp = arm_pic_init_cpu(cpu); > cpu_irq[n] = irqp[ARM_PIC_CPU_IRQ]; > + > +env = &cpu->env; > } > > sysmem = get_system_memory(); > @@ -246,7 +249,16 @@ static void highbank_init(QEMUMachineInitArgs *args) > } > } > > -dev = qdev_create(NULL, "a9mpcore_priv"); > +if (arm_feature(env, ARM_FEATURE_LPAE)) { > +dev = qdev_create(NULL, "a15mpcore_priv"); This feels a bit fragile to me... Cortex-A7 or other cores might grow support for LPAE, too. I would suggest something along these lines: if (object_get_class(OBJECT(cpu)) == object_class_by_name("cortex-a15-" TYPE_ARM_CPU)) {...} In a QOM context Peter, the Samsung guys and me had been discussing how to improve CPU modelling, which I have been experimenting with some more on my Tegra branch: http://repo.or.cz/w/qemu/afaerber.git/shortlog/refs/heads/tegra Transferred to Highbank this would result in something like this: /machine/highbank-soc - name board-specific, a DeviceState /machine/highbank-soc/cortex - a Container for ARM standard peripherals /machine/highbank-soc/cortex/cpu[0..3] - an ARMCPU core /machine/highbank-soc/foo - anything that's specific to this SoC I now wonder whether it would make sense to turn the "cortex" node into a DeviceState type "cortex-a15-arm-soc" rather than an empty Container filled by each SoC? DeviceState would help with recursive QOM realization, and we could then better embed what is now a15mpcore_priv. Certainly outside the scope of this patch, but long-term I would like to get away from the board-level CPU peripheral fiddling that is being done here and clearly separate SoC from machine via different files. Regards, Andreas > +} else { > +dev = qdev_create(NULL, "l2x0"); > +qdev_init_nofail(dev); > +busdev = SYS_BUS_DEVICE(dev); > +sysbus_mmio_map(busdev, 0, 0xfff12000); > + > +dev = qdev_create(NULL, "a9mpcore_priv"); > +} > qdev_prop_set_uint32(dev, "num-cpu", smp_cpus); > qdev_prop_set_uint32(dev, "num-irq", NIRQ_GIC); > qdev_init_nofail(dev); > @@ -260,11 +272,6 @@ static void highbank_init(QEMUMachineInitArgs *args) > pic[n] = qdev_get_gpio_in(dev, n); > } > > -dev = qdev_create(NULL, "l2x0"); > -qdev_init_nofail(dev); > -busdev = SYS_BUS_DEVICE(dev); > -sysbus_mmio_map(busdev, 0, 0xfff12000); > - > dev = qdev_create(NULL, "sp804"); > qdev_prop_set_uint32(dev, "freq0", 15000); > qdev_prop_set_uint32(dev, "freq1", 15000); > -- 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 v2] linux-user: Move cpu_clone_regs() and cpu_set_tls() into linux-user
Am 28.06.2013 19:35, schrieb Richard Henderson: > On 06/28/2013 06:22 AM, Peter Maydell wrote: >> The functions cpu_clone_regs() and cpu_set_tls() are not purely CPU >> related -- they are specific to the TLS ABI for a a particular OS. >> Move them into the linux-user/ tree where they belong. >> >> target-lm32 had entirely unused implementations, since it has no >> linux-user target; just drop them. >> >> Signed-off-by: Peter Maydell >> --- >> Changes v1->v2: move the openrisc and i386 functions (accidentally >> omitted from v1), drop the unused lm32 functions. > > Acked-by: Richard Henderson Thanks, applied to qom-cpu: https://github.com/afaerber/qemu-cpu/commits/qom-cpu Andreas -- 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 v2] cpu: Drop unnecessary dynamic casts in *_env_get_cpu()
Am 28.06.2013 19:32, schrieb Richard Henderson: > On 06/28/2013 06:23 AM, Andreas Färber wrote: >> A transition from CPUFooState to FooCPU can be considered safe, >> just like FooCPU::env access in the opposite direction. >> The only benefit of the FOO_CPU() casts would be protection against >> bogus CPUFooState pointers, but then surrounding code would likely >> break, too. >> >> This should slightly improve interrupt etc. performance. >> >> Reported-by: Anthony Liguori >> Signed-off-by: Andreas Färber > > Acked-by: Richard Henderson Thanks, applied to qom-cpu (with extended commit message): https://github.com/afaerber/qemu-cpu/commits/qom-cpu Andreas -- 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] highbank: add initial Calxeda Midway A15 support
Am 29.06.2013 14:54, schrieb Andreas Färber: > Am 28.06.2013 13:59, schrieb Andre Przywara: >> From: Rob Herring >> >> While the Calxeda Midway part is actually a bit more than a "Highbank >> with A15s", for QEMU's purposes this view is sufficient. So to allow >> both emulation with that chip as well as KVM guests using that model >> add an A15 CPU and it's peripherals as an option. The use of: >> "-M highbank -cpu cortex-a15" simply gives the new chip without the >> need for a new model. >> >> Signed-off-by: Rob Herring >> Signed-off-by: Andre Przywara >> --- >> hw/arm/highbank.c | 19 +-- >> 1 file changed, 13 insertions(+), 6 deletions(-) >> >> diff --git a/hw/arm/highbank.c b/hw/arm/highbank.c >> index 4405dbd..ed864c6 100644 >> --- a/hw/arm/highbank.c >> +++ b/hw/arm/highbank.c >> @@ -196,6 +196,7 @@ static void highbank_init(QEMUMachineInitArgs *args) >> const char *kernel_filename = args->kernel_filename; >> const char *kernel_cmdline = args->kernel_cmdline; >> const char *initrd_filename = args->initrd_filename; >> +CPUARMState *env = NULL; >> DeviceState *dev; >> SysBusDevice *busdev; >> qemu_irq *irqp; >> @@ -223,6 +224,8 @@ static void highbank_init(QEMUMachineInitArgs *args) >> cpu->reset_cbar = GIC_BASE_ADDR; >> irqp = arm_pic_init_cpu(cpu); >> cpu_irq[n] = irqp[ARM_PIC_CPU_IRQ]; >> + >> +env = &cpu->env; >> } >> >> sysmem = get_system_memory(); >> @@ -246,7 +249,16 @@ static void highbank_init(QEMUMachineInitArgs *args) >> } >> } >> >> -dev = qdev_create(NULL, "a9mpcore_priv"); >> +if (arm_feature(env, ARM_FEATURE_LPAE)) { >> +dev = qdev_create(NULL, "a15mpcore_priv"); > > This feels a bit fragile to me... Cortex-A7 or other cores might grow > support for LPAE, too. Add to that, feature inference is done as part of QOM realize, for which it is too early to depend on in machine init. > I would suggest something along these lines: > > if (object_get_class(OBJECT(cpu)) == object_class_by_name("cortex-a15-" > TYPE_ARM_CPU)) {...} Andreas -- SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg
[Qemu-devel] [PATCH] RFCv3 kvm irqfd: support msimessage to irq translation in PHB
On PPC64 systems MSI Messages are translated to system IRQ in a PCI host bridge. This is already supported for emulated MSI/MSIX but not for irqfd where the current QEMU allocates IRQ numbers from irqchip and maps MSIMessages to those IRQ in the host kernel. The patch extends irqfd support in order to avoid unnecessary mapping and reuse the one which already exists in a PCI host bridge. Specifically, a map_msi callback is added to PCIBus and pci_bus_map_msi() to PCI API. The latter returns -1 if a specific PHB does not provide with any trsnslation so the existing code will work. Signed-off-by: Alexey Kardashevskiy --- Looks like we agreed that in general PHB is the right place for this, not KVM, so I am trying again. Probably something should be done to kvm_irqchip_update_msi_route() as well but I do not really understand what exactly. Any suggestions? --- hw/misc/vfio.c |7 +-- hw/pci/pci.c | 13 + hw/ppc/spapr_pci.c |6 ++ hw/virtio/virtio-pci.c |2 +- include/hw/pci/pci.h |4 include/hw/pci/pci_bus.h |1 + include/sysemu/kvm.h |2 +- kvm-all.c|7 ++- 8 files changed, 37 insertions(+), 5 deletions(-) diff --git a/hw/misc/vfio.c b/hw/misc/vfio.c index 52fb036..59911bb 100644 --- a/hw/misc/vfio.c +++ b/hw/misc/vfio.c @@ -624,7 +624,9 @@ static int vfio_msix_vector_do_use(PCIDevice *pdev, unsigned int nr, * Attempt to enable route through KVM irqchip, * default to userspace handling if unavailable. */ -vector->virq = msg ? kvm_irqchip_add_msi_route(kvm_state, *msg) : -1; + +vector->virq = msg ? +kvm_irqchip_add_msi_route(kvm_state, vdev->pdev.bus, *msg) : -1; if (vector->virq < 0 || kvm_irqchip_add_irqfd_notifier(kvm_state, &vector->interrupt, vector->virq) < 0) { @@ -792,7 +794,8 @@ retry: * Attempt to enable route through KVM irqchip, * default to userspace handling if unavailable. */ -vector->virq = kvm_irqchip_add_msi_route(kvm_state, msg); +vector->virq = kvm_irqchip_add_msi_route(kvm_state, vdev->pdev.bus, + msg); if (vector->virq < 0 || kvm_irqchip_add_irqfd_notifier(kvm_state, &vector->interrupt, vector->virq) < 0) { diff --git a/hw/pci/pci.c b/hw/pci/pci.c index 61b681a..543f172 100644 --- a/hw/pci/pci.c +++ b/hw/pci/pci.c @@ -1240,6 +1240,19 @@ void pci_device_set_intx_routing_notifier(PCIDevice *dev, dev->intx_routing_notifier = notifier; } +void pci_bus_set_map_msi_fn(PCIBus *bus, pci_map_msi_fn map_msi_fn) +{ +bus->map_msi = map_msi_fn; +} + +int pci_bus_map_msi(PCIBus *bus, MSIMessage msg) +{ +if (bus->map_msi) { +return bus->map_msi(bus, msg); +} +return -1; +} + /* * PCI-to-PCI bridge specification * 9.1: Interrupt routing. Table 9-1 diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c index 23dbc0e..bae4faf 100644 --- a/hw/ppc/spapr_pci.c +++ b/hw/ppc/spapr_pci.c @@ -486,6 +486,11 @@ static void spapr_msi_write(void *opaque, hwaddr addr, qemu_irq_pulse(xics_get_qirq(spapr->icp, irq)); } +static int spapr_msi_get_irq(PCIBus *bus, MSIMessage msg) +{ +return msg.data; +} + static const MemoryRegionOps spapr_msi_ops = { /* There is no .read as the read result is undefined by PCI spec */ .read = NULL, @@ -657,6 +662,7 @@ static int spapr_phb_init(SysBusDevice *s) sphb->lsi_table[i].irq = irq; } +pci_bus_set_map_msi_fn(bus, spapr_msi_get_irq); return 0; } diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c index b070b64..06a4e13 100644 --- a/hw/virtio/virtio-pci.c +++ b/hw/virtio/virtio-pci.c @@ -481,7 +481,7 @@ static int kvm_virtio_pci_vq_vector_use(VirtIOPCIProxy *proxy, int ret; if (irqfd->users == 0) { -ret = kvm_irqchip_add_msi_route(kvm_state, msg); +ret = kvm_irqchip_add_msi_route(kvm_state, proxy->pci_dev.bus, msg); if (ret < 0) { return ret; } diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h index 6ef1f97..8c1edd6 100644 --- a/include/hw/pci/pci.h +++ b/include/hw/pci/pci.h @@ -332,6 +332,7 @@ MemoryRegion *pci_address_space_io(PCIDevice *dev); typedef void (*pci_set_irq_fn)(void *opaque, int irq_num, int level); typedef int (*pci_map_irq_fn)(PCIDevice *pci_dev, int irq_num); typedef PCIINTxRoute (*pci_route_irq_fn)(void *opaque, int pin); +typedef int (*pci_map_msi_fn)(PCIBus *bus, MSIMessage msg); typedef enum { PCI_HOTPLUG_DISABLED, @@ -375,6 +376,9 @@ bool pci_intx_route_changed(PCIINTxRoute *old, PCIINTxRoute *new); void pci_bus_fire_intx_routing_notifier(PCIBus *bus); void pci_device_set_intx_routing_notifier(PCIDevice *dev, PCIINTxRoutingNotifier notifier); +void pci_bus_set_map_msi_fn(PCIBus
[Qemu-devel] [PATCH v2] spapr: Fix compiler warnings for some versions of gcc
i686-w64-mingw32-gcc (GCC) 4.6.3 from Debian wheezy reports these warnings: hw/ppc/spapr_hcall.c:188:1: warning: control reaches end of non-void function [-Wreturn-type] hw/ppc/spapr_pci.c:454:1: warning: control reaches end of non-void function [-Wreturn-type] Both warnings are fixed by using g_assert_not_reached instead of assert. A second line with assert(0) in spapr_pci.c which did not raise a compiler warning was modified, too, because g_assert_not_reached documents the purpose of that statement and is not removed in release builds. Signed-off-by: Stefan Weil --- This patch is an improved version which replaces http://patchwork.ozlabs.org/patch/253939/ and http://patchwork.ozlabs.org/patch/253938/. Patch http://patchwork.ozlabs.org/patch/253937/ of my previous series is still applicable. Please consider applying it to the ppc queue. I suggest replacing assert(0) by g_assert_not_reached() in the rest of QEMU's code, too. If there is consensus, I'll send a patch which does this. Replacing assert by g_assert would also make sense with a few exceptions in time critical code (TCG, TCI). Regards Stefan W. hw/ppc/spapr_hcall.c |2 +- hw/ppc/spapr_pci.c |4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c index 8f0b7e8..93af469 100644 --- a/hw/ppc/spapr_hcall.c +++ b/hw/ppc/spapr_hcall.c @@ -184,7 +184,7 @@ static target_ulong h_remove(PowerPCCPU *cpu, sPAPREnvironment *spapr, return H_HARDWARE; } -assert(0); +g_assert_not_reached(); } #define H_BULK_REMOVE_TYPE 0xc000ULL diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c index 04e8362..4b69b04 100644 --- a/hw/ppc/spapr_pci.c +++ b/hw/ppc/spapr_pci.c @@ -450,7 +450,7 @@ static uint64_t spapr_io_read(void *opaque, hwaddr addr, case 4: return cpu_inl(addr); } -assert(0); +g_assert_not_reached(); } static void spapr_io_write(void *opaque, hwaddr addr, @@ -467,7 +467,7 @@ static void spapr_io_write(void *opaque, hwaddr addr, cpu_outl(addr, data); return; } -assert(0); +g_assert_not_reached(); } static const MemoryRegionOps spapr_io_ops = { -- 1.7.10.4
[Qemu-devel] [PATCH] linux-user: Do not ignore mmap failure from host
File mapping may fail with EACCES. Signed-off-by: Jürg Billeter --- linux-user/mmap.c | 4 1 file changed, 4 insertions(+) diff --git a/linux-user/mmap.c b/linux-user/mmap.c index b412e3f..de22197 100644 --- a/linux-user/mmap.c +++ b/linux-user/mmap.c @@ -483,6 +483,10 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int prot, if (!(flags & MAP_ANONYMOUS)) { p = mmap(g2h(start), len, prot, flags | MAP_FIXED, fd, host_offset); +if (p == MAP_FAILED) { +munmap(g2h(start), host_len); +goto fail; +} host_start += offset - host_offset; } start = h2g(host_start); -- 1.8.2.3
[Qemu-devel] [PATCH] semaphore: fix a hangup problem under load on NetBSD hosts.
Fix following bugs in "fallback implementation of counting semaphores with mutex+condvar" added in c166cb72f1676855816340666c3b618beef4b976: - waiting threads are not restarted properly if more than one threads are waiting unblock signals in qemu_sem_timedwait() - possible missing pthread_cond_signal(3) calls when waiting threads are returned by ETIMEDOUT - fix an uninitialized variable The problem is analyzed by and fix is provided by Noriyuki Soda. Signed-off-by: Izumi Tsutsui --- util/qemu-thread-posix.c | 17 + 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/util/qemu-thread-posix.c b/util/qemu-thread-posix.c index 4489abf..db7a15b 100644 --- a/util/qemu-thread-posix.c +++ b/util/qemu-thread-posix.c @@ -172,10 +172,9 @@ void qemu_sem_post(QemuSemaphore *sem) pthread_mutex_lock(&sem->lock); if (sem->count == INT_MAX) { rc = EINVAL; -} else if (sem->count++ < 0) { -rc = pthread_cond_signal(&sem->cond); } else { -rc = 0; +sem->count++; +rc = pthread_cond_signal(&sem->cond); } pthread_mutex_unlock(&sem->lock); if (rc != 0) { @@ -207,19 +206,21 @@ int qemu_sem_timedwait(QemuSemaphore *sem, int ms) struct timespec ts; #if defined(__APPLE__) || defined(__NetBSD__) +rc = 0; compute_abs_deadline(&ts, ms); pthread_mutex_lock(&sem->lock); ---sem->count; -while (sem->count < 0) { +while (sem->count <= 0) { rc = pthread_cond_timedwait(&sem->cond, &sem->lock, &ts); if (rc == ETIMEDOUT) { -++sem->count; break; } if (rc != 0) { error_exit(rc, __func__); } } +if (rc != ETIMEDOUT) { +--sem->count; +} pthread_mutex_unlock(&sem->lock); return (rc == ETIMEDOUT ? -1 : 0); #else @@ -251,10 +252,10 @@ void qemu_sem_wait(QemuSemaphore *sem) { #if defined(__APPLE__) || defined(__NetBSD__) pthread_mutex_lock(&sem->lock); ---sem->count; -while (sem->count < 0) { +while (sem->count <= 0) { pthread_cond_wait(&sem->cond, &sem->lock); } +--sem->count; pthread_mutex_unlock(&sem->lock); #else int rc; -- 1.8.0.1
Re: [Qemu-devel] [PATCH] RFCv3 kvm irqfd: support msimessage to irq translation in PHB
Am 29.06.2013 15:45, schrieb Alexey Kardashevskiy: > On PPC64 systems MSI Messages are translated to system IRQ in a PCI > host bridge. This is already supported for emulated MSI/MSIX but > not for irqfd where the current QEMU allocates IRQ numbers from > irqchip and maps MSIMessages to those IRQ in the host kernel. > > The patch extends irqfd support in order to avoid unnecessary > mapping and reuse the one which already exists in a PCI host bridge. > > Specifically, a map_msi callback is added to PCIBus and pci_bus_map_msi() > to PCI API. The latter returns -1 if a specific PHB does not provide > with any trsnslation so the existing code will work. > > Signed-off-by: Alexey Kardashevskiy > > --- > > Looks like we agreed that in general PHB is the right place for this, > not KVM, so I am trying again. > > Probably something should be done to kvm_irqchip_update_msi_route() > as well but I do not really understand what exactly. Any suggestions? > > > --- > hw/misc/vfio.c |7 +-- > hw/pci/pci.c | 13 + > hw/ppc/spapr_pci.c |6 ++ > hw/virtio/virtio-pci.c |2 +- > include/hw/pci/pci.h |4 > include/hw/pci/pci_bus.h |1 + > include/sysemu/kvm.h |2 +- > kvm-all.c|7 ++- > 8 files changed, 37 insertions(+), 5 deletions(-) > > diff --git a/hw/misc/vfio.c b/hw/misc/vfio.c > index 52fb036..59911bb 100644 > --- a/hw/misc/vfio.c > +++ b/hw/misc/vfio.c > @@ -624,7 +624,9 @@ static int vfio_msix_vector_do_use(PCIDevice *pdev, > unsigned int nr, > * Attempt to enable route through KVM irqchip, > * default to userspace handling if unavailable. > */ > -vector->virq = msg ? kvm_irqchip_add_msi_route(kvm_state, *msg) : -1; > + > +vector->virq = msg ? > +kvm_irqchip_add_msi_route(kvm_state, vdev->pdev.bus, *msg) : -1; Please don't access device-internal parent fields like ->pdev. To obtain a PCIDevice you can use PCI_DEVICE(vdev). But in this case isn't that just a complicated way to access the function's argument pdev? > if (vector->virq < 0 || > kvm_irqchip_add_irqfd_notifier(kvm_state, &vector->interrupt, > vector->virq) < 0) { > @@ -792,7 +794,8 @@ retry: > * Attempt to enable route through KVM irqchip, > * default to userspace handling if unavailable. > */ > -vector->virq = kvm_irqchip_add_msi_route(kvm_state, msg); > +vector->virq = kvm_irqchip_add_msi_route(kvm_state, vdev->pdev.bus, > + msg); Ditto. > if (vector->virq < 0 || > kvm_irqchip_add_irqfd_notifier(kvm_state, &vector->interrupt, > vector->virq) < 0) { > diff --git a/hw/pci/pci.c b/hw/pci/pci.c > index 61b681a..543f172 100644 > --- a/hw/pci/pci.c > +++ b/hw/pci/pci.c > @@ -1240,6 +1240,19 @@ void pci_device_set_intx_routing_notifier(PCIDevice > *dev, > dev->intx_routing_notifier = notifier; > } > > +void pci_bus_set_map_msi_fn(PCIBus *bus, pci_map_msi_fn map_msi_fn) > +{ > +bus->map_msi = map_msi_fn; > +} > + > +int pci_bus_map_msi(PCIBus *bus, MSIMessage msg) > +{ > +if (bus->map_msi) { > +return bus->map_msi(bus, msg); > +} > +return -1; > +} > + > /* > * PCI-to-PCI bridge specification > * 9.1: Interrupt routing. Table 9-1 > diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c > index 23dbc0e..bae4faf 100644 > --- a/hw/ppc/spapr_pci.c > +++ b/hw/ppc/spapr_pci.c > @@ -486,6 +486,11 @@ static void spapr_msi_write(void *opaque, hwaddr addr, > qemu_irq_pulse(xics_get_qirq(spapr->icp, irq)); > } > > +static int spapr_msi_get_irq(PCIBus *bus, MSIMessage msg) > +{ > +return msg.data; > +} > + > static const MemoryRegionOps spapr_msi_ops = { > /* There is no .read as the read result is undefined by PCI spec */ > .read = NULL, > @@ -657,6 +662,7 @@ static int spapr_phb_init(SysBusDevice *s) > > sphb->lsi_table[i].irq = irq; > } > +pci_bus_set_map_msi_fn(bus, spapr_msi_get_irq); > > return 0; > } > diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c > index b070b64..06a4e13 100644 > --- a/hw/virtio/virtio-pci.c > +++ b/hw/virtio/virtio-pci.c > @@ -481,7 +481,7 @@ static int kvm_virtio_pci_vq_vector_use(VirtIOPCIProxy > *proxy, > int ret; > > if (irqfd->users == 0) { > -ret = kvm_irqchip_add_msi_route(kvm_state, msg); > +ret = kvm_irqchip_add_msi_route(kvm_state, proxy->pci_dev.bus, msg); PCIDevice *pci_dev = PCI_DEVICE(proxy); and pci_dev->bus please. Andreas > if (ret < 0) { > return ret; > } > diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h > index 6ef1f97..8c1edd6 100644 > --- a/include/hw/pci/pci.h > +++ b/include/hw/pci/pci.h > @@ -332,6 +332,7 @@ MemoryRegion *pci_address_space_io(PCIDevice *dev); > typedef void (*pci
Re: [Qemu-devel] [PATCH] RFCv3 kvm irqfd: support msimessage to irq translation in PHB
On Sat, Jun 29, 2013 at 8:45 AM, Alexey Kardashevskiy wrote: > On PPC64 systems MSI Messages are translated to system IRQ in a PCI > host bridge. This is already supported for emulated MSI/MSIX but > not for irqfd where the current QEMU allocates IRQ numbers from > irqchip and maps MSIMessages to those IRQ in the host kernel. > > The patch extends irqfd support in order to avoid unnecessary > mapping and reuse the one which already exists in a PCI host bridge. > > Specifically, a map_msi callback is added to PCIBus and pci_bus_map_msi() > to PCI API. The latter returns -1 if a specific PHB does not provide > with any trsnslation so the existing code will work. I think there's a bit of confusion here. The kernel needs a "virq" number to create an eventfd. virq is just a KVM concept, it doesn't correspond to anything useful in hardware. On pseries, there is a 1-1 mapping between XICS IRQs and VIRQs and MSI can be trivially mapped to a virq. On x86, we need to call a special kernel function which essentially creates an apic message->virq mapping such that we can deliver the irqfd. So what this should look like is: 1) A PCI bus function to do the MSI -> virq mapping 2) On x86 (and e500), this is implemented by calling kvm_irqchip_add_msi_route() 3) On pseries, this just returns msi->data Perhaps (2) can just be the default PCI bus implementation to simplify things. > Signed-off-by: Alexey Kardashevskiy > > --- > > Looks like we agreed that in general PHB is the right place for this, > not KVM, so I am trying again. > > Probably something should be done to kvm_irqchip_update_msi_route() > as well but I do not really understand what exactly. Any suggestions? > > > --- > hw/misc/vfio.c |7 +-- > hw/pci/pci.c | 13 + > hw/ppc/spapr_pci.c |6 ++ > hw/virtio/virtio-pci.c |2 +- > include/hw/pci/pci.h |4 > include/hw/pci/pci_bus.h |1 + > include/sysemu/kvm.h |2 +- > kvm-all.c|7 ++- > 8 files changed, 37 insertions(+), 5 deletions(-) > > diff --git a/hw/misc/vfio.c b/hw/misc/vfio.c > index 52fb036..59911bb 100644 > --- a/hw/misc/vfio.c > +++ b/hw/misc/vfio.c > @@ -624,7 +624,9 @@ static int vfio_msix_vector_do_use(PCIDevice *pdev, > unsigned int nr, > * Attempt to enable route through KVM irqchip, > * default to userspace handling if unavailable. > */ > -vector->virq = msg ? kvm_irqchip_add_msi_route(kvm_state, *msg) : -1; > + > +vector->virq = msg ? > +kvm_irqchip_add_msi_route(kvm_state, vdev->pdev.bus, *msg) : -1; This is wrong. You could call the bus function to map an MSI message to a virq here. > if (vector->virq < 0 || > kvm_irqchip_add_irqfd_notifier(kvm_state, &vector->interrupt, > vector->virq) < 0) { > @@ -792,7 +794,8 @@ retry: > * Attempt to enable route through KVM irqchip, > * default to userspace handling if unavailable. > */ > -vector->virq = kvm_irqchip_add_msi_route(kvm_state, msg); > +vector->virq = kvm_irqchip_add_msi_route(kvm_state, vdev->pdev.bus, > + msg); And here. > if (vector->virq < 0 || > kvm_irqchip_add_irqfd_notifier(kvm_state, &vector->interrupt, > vector->virq) < 0) { > diff --git a/hw/pci/pci.c b/hw/pci/pci.c > index 61b681a..543f172 100644 > --- a/hw/pci/pci.c > +++ b/hw/pci/pci.c > @@ -1240,6 +1240,19 @@ void pci_device_set_intx_routing_notifier(PCIDevice > *dev, > dev->intx_routing_notifier = notifier; > } > > +void pci_bus_set_map_msi_fn(PCIBus *bus, pci_map_msi_fn map_msi_fn) > +{ > +bus->map_msi = map_msi_fn; > +} You don't need this function. You can do this overloading as part of the PCI bus initialization in spapr_pci.c Regards, Anthony Liguori > +int pci_bus_map_msi(PCIBus *bus, MSIMessage msg) > +{ > +if (bus->map_msi) { > +return bus->map_msi(bus, msg); > +} > +return -1; > +} > + > /* > * PCI-to-PCI bridge specification > * 9.1: Interrupt routing. Table 9-1 > diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c > index 23dbc0e..bae4faf 100644 > --- a/hw/ppc/spapr_pci.c > +++ b/hw/ppc/spapr_pci.c > @@ -486,6 +486,11 @@ static void spapr_msi_write(void *opaque, hwaddr addr, > qemu_irq_pulse(xics_get_qirq(spapr->icp, irq)); > } > > +static int spapr_msi_get_irq(PCIBus *bus, MSIMessage msg) > +{ > +return msg.data; > +} > + > static const MemoryRegionOps spapr_msi_ops = { > /* There is no .read as the read result is undefined by PCI spec */ > .read = NULL, > @@ -657,6 +662,7 @@ static int spapr_phb_init(SysBusDevice *s) > > sphb->lsi_table[i].irq = irq; > } > +pci_bus_set_map_msi_fn(bus, spapr_msi_get_irq); > > return 0; > } > diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c > index b070b64..06a4e13
Re: [Qemu-devel] [PATCH v2] spapr: Fix compiler warnings for some versions of gcc
On Sat, Jun 29, 2013 at 03:47:26PM +0200, Stefan Weil wrote: > i686-w64-mingw32-gcc (GCC) 4.6.3 from Debian wheezy reports these warnings: > > hw/ppc/spapr_hcall.c:188:1: warning: > control reaches end of non-void function [-Wreturn-type] > > hw/ppc/spapr_pci.c:454:1: warning: > control reaches end of non-void function [-Wreturn-type] > > Both warnings are fixed by using g_assert_not_reached instead of assert. > A second line with assert(0) in spapr_pci.c which did not raise a compiler > warning was modified, too, because g_assert_not_reached documents the > purpose of that statement and is not removed in release builds. > > Signed-off-by: Stefan Weil Makes sense to me. Acked-by: David Gibson -- David Gibson| I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_ | _way_ _around_! http://www.ozlabs.org/~dgibson pgpGMjAH0darj.pgp Description: PGP signature
Re: [Qemu-devel] [PATCH 0/2] Add infinite loop checking in img_create()
Am 27.06.2013 09:38, schrieb Xu Wang: > From: Xu Wang > > If user creates a image with loop in backing file, qemu doesn't give any > warning or error report and creation successful. If this image was opend > by qemu, no response would occure and segment fault would happend at last. > Hence these patches refine and export infinite loop checking in > collect_image_info_list() and add checking into img_create(). If a loop > would occure, an error info output and creation interrupted. > > Xu Wang (2): > Refine and export infinite loop checking in collect_image_info_list() > Check infinite loop in img_create() In the future please use a prefix such as "qemu-img: ..." on both cover letter and patches to indicate which part of code it concerns, and CC the respective maintainers of that area to assure appropriate review. Regards, Andreas > > qemu-img.c | 121 > ++--- > 1 file changed, 100 insertions(+), 21 deletions(-) > -- SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg
[Qemu-devel] [PATCH] aes: Remove unused code (NDEBUG, u16)
The current code includes assert.h very early (from qemu-common.h), so the definition of NDEBUG was without any effect. In the initial version from 2004, NDEBUG was used to disable the assertions. Those assertions are not in time critical code, so it is no longer reasonable to disable them and the definition of NDEBUG can be removed. Type u16 is also unused and therefore does not need a type definition. Signed-off-by: Stefan Weil --- util/aes.c |5 - 1 file changed, 5 deletions(-) diff --git a/util/aes.c b/util/aes.c index 91e97fa..4b4d88e 100644 --- a/util/aes.c +++ b/util/aes.c @@ -30,12 +30,7 @@ #include "qemu-common.h" #include "qemu/aes.h" -#ifndef NDEBUG -#define NDEBUG -#endif - typedef uint32_t u32; -typedef uint16_t u16; typedef uint8_t u8; /* This controls loop-unrolling in aes_core.c */ -- 1.7.10.4
[Qemu-devel] [PATCH] PPC: Mac: Fix guest exported tbfreq values
We can tell the guest the frequency of its time base through fwcfg. However, we tell it a different value from the speed tb actually runs at. Let's fix it and make the tbfreq initialization and the fwcfg exposure use the same values. Signed-off-by: Alexander Graf --- hw/ppc/mac_newworld.c | 5 +++-- hw/ppc/mac_oldworld.c | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/hw/ppc/mac_newworld.c b/hw/ppc/mac_newworld.c index 3badfa3..253089a 100644 --- a/hw/ppc/mac_newworld.c +++ b/hw/ppc/mac_newworld.c @@ -71,6 +71,7 @@ #define MAX_IDE_BUS 2 #define CFG_ADDR 0xf510 +#define TBFREQ (100UL * 1000UL * 1000UL) /* debug UniNorth */ //#define DEBUG_UNIN @@ -191,7 +192,7 @@ static void ppc_core99_init(QEMUMachineInitArgs *args) env = &cpu->env; /* Set time-base frequency to 100 Mhz */ -cpu_ppc_tb_init(env, 100UL * 1000UL * 1000UL); +cpu_ppc_tb_init(env, TBFREQ); qemu_register_reset(ppc_core99_reset, cpu); } @@ -460,7 +461,7 @@ static void ppc_core99_init(QEMUMachineInitArgs *args) fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_KVM_PID, getpid()); #endif } else { -fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_TBFREQ, get_ticks_per_sec()); +fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_TBFREQ, TBFREQ); } /* Mac OS X requires a "known good" clock-frequency value; pass it one. */ fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_CLOCKFREQ, 26600); diff --git a/hw/ppc/mac_oldworld.c b/hw/ppc/mac_oldworld.c index abab5e4..230bb30 100644 --- a/hw/ppc/mac_oldworld.c +++ b/hw/ppc/mac_oldworld.c @@ -45,6 +45,7 @@ #define MAX_IDE_BUS 2 #define CFG_ADDR 0xf510 +#define TBFREQ 1660UL static int fw_cfg_boot_set(void *opaque, const char *boot_device) { @@ -114,7 +115,7 @@ static void ppc_heathrow_init(QEMUMachineInitArgs *args) env = &cpu->env; /* Set time-base frequency to 16.6 Mhz */ -cpu_ppc_tb_init(env, 1660UL); +cpu_ppc_tb_init(env, TBFREQ); qemu_register_reset(ppc_heathrow_reset, cpu); } @@ -330,7 +331,7 @@ static void ppc_heathrow_init(QEMUMachineInitArgs *args) fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_KVM_PID, getpid()); #endif } else { -fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_TBFREQ, get_ticks_per_sec()); +fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_TBFREQ, TBFREQ); } /* Mac OS X requires a "known good" clock-frequency value; pass it one. */ fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_CLOCKFREQ, 26600); -- 1.8.1.4
[Qemu-devel] [Bug 661696] Re: incomplete emulation of fstenv under TCG
The bug is still present in the newly released QEMU-1.5.1. I've ported Chalkerx's patch to this release as well. See attached patch. Is there a problem with this patch, since it has not been committed? // MOKI ** Patch added: "patch-qemu-1.5.1-fpip.diff" https://bugs.launchpad.net/qemu/+bug/661696/+attachment/3718352/+files/patch-qemu-1.5.1-fpip.diff -- You received this bug notification because you are a member of qemu- devel-ml, which is subscribed to QEMU. https://bugs.launchpad.net/bugs/661696 Title: incomplete emulation of fstenv under TCG Status in QEMU: New Bug description: Steps to reproduce: 1) Install Windows (tried XP and 7) in qemu (tried qemu without kvm and qemu-kvm). 2) Get OllyDbg ( http://ollydbg.de/odbg200.zip ). 3) Use some Metasploit-encoded file, example included. It is not a virus! File was generated with Metasploit, command (if i remember it right): `msfpayload windows/exec cmd=notepad R | msfencode -e x86/shikata_ga_nai -t exe -o cmd_exec_notepad.shikata_ga_nai.exe`. 4) Launch the file under Windows in qemu, make sure it opens a notepad. 5) Open file under OllyDbg, run (F9) it there. It opens a notpad. Close OllyDbg. 6) Open file under OllyDbg, trace over (Ctrl+F12) it there. It fails with `Access violation when writing to [some address]`. Command: 316A 13, XOR DWORD PTR DS:[EDX+13],EBP Under native Windows, the trace over command works fine. Under VMware the trace works fine. Under VirtualBox it also fails (checked in the spring). $ qemu-kvm --version QEMU PC emulator version 0.12.5 (qemu-kvm-0.12.5), Copyright (c) 2003-2008 Fabrice Bellard To manage notifications about this bug go to: https://bugs.launchpad.net/qemu/+bug/661696/+subscriptions
Re: [Qemu-devel] [Bug 661696] Re: incomplete emulation of fstenv under TCG
Am 29.06.2013 19:10, schrieb Morten Shearman Kirkegaard: > The bug is still present in the newly released QEMU-1.5.1. I've ported > Chalkerx's patch to this release as well. See attached patch. > > Is there a problem with this patch, since it has not been committed? > > // MOKI > > ** Patch added: "patch-qemu-1.5.1-fpip.diff" > > https://bugs.launchpad.net/qemu/+bug/661696/+attachment/3718352/+files/patch-qemu-1.5.1-fpip.diff Yes, see http://lists.nongnu.org/archive/html/qemu-devel/2013-05/msg03521.html Patches need to be submitted to qemu-devel mailing list for review if you want to see them in any release: http://wiki.qemu.org/Contribute/SubmitAPatch The thread above has some unresolved review feedback, including lack of Signed-off-by just like yours, and I haven't seen a newer version yet nor a late Signed-off-by from the original author. Regards, Andreas -- 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 3/6] Added Aarch64 CPU Initialization, Get and Put Registers Support.
On 06/28/2013 02:43 PM, Alexander Graf wrote: On 28.06.2013, at 14:11, Mian M. Hamayun wrote: diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h index c614070..4df5292 100644 --- a/linux-headers/linux/kvm.h +++ b/linux-headers/linux/kvm.h @@ -783,6 +783,7 @@ struct kvm_dirty_tlb { #define KVM_REG_IA640x3000ULL #define KVM_REG_ARM 0x4000ULL #define KVM_REG_S3900x5000ULL +#define KVM_REG_ARM64 0x6000ULL #define KVM_REG_SIZE_SHIFT 52 #define KVM_REG_SIZE_MASK 0x00f0ULL This should be part of your header update patch. Just to make sure that we understand it correctly, do you mean that this macro definition should be moved to the arm64 specific header that we include in another patch series ? or keep this change in the same file and do it along with the header inclusion in a single patch ? +#ifdef TARGET_AARCH64 +int kvm_arch_init_vcpu(CPUState *cs) +{ +struct kvm_vcpu_init init; +int ret; + +/* Try initializing with Foundation Models */ +init.target = KVM_ARM_TARGET_FOUNDATION_V8; +memset(init.features, 0, sizeof(init.features)); +ret = kvm_vcpu_ioctl(cs, KVM_ARM_VCPU_INIT, &init); +if (ret) { +/* Retry initializing with Fast Models */ +init.target = KVM_ARM_TARGET_AEM_V8; +ret = kvm_vcpu_ioctl(cs, KVM_ARM_VCPU_INIT, &init); Not sure I understand this part. Do we have different CPU types for the different models? If so, they'd be different -cpu parameters, with -cpu host picking the same as the host's. KVM tool does a very similar thing, using a loop and tries to initialize supported processors types and gets done when it succeeds with anyone of them. We could include a similar implementation in the next revision. +{ +struct kvm_one_reg reg; +int i; +int ret; + +ARMCPU *cpu = ARM_CPU(cs); +CPUARMState *env = &cpu->env; + +for (i = 0; i < 31; i++) { s/31/ARRAY_SIZE(...)/ Agreed, we should avoid hard-coding as much as possible. +reg.id = AARCH64_CORE_REG(regs.regs[i]); +reg.addr = (uintptr_t)(env) + offsetof(CPUARMState, xregs[i]); reg.addr = (uintptr_t)&env->xregs[i]; Our implementation was influenced by the existing kvm_arch_get_registers() implementation for the A15 CPU, with slight differences. Anyways, we will include the proposed change in the next revision. -- Hamayun
Re: [Qemu-devel] [Bug 661696] Re: incomplete emulation of fstenv under TCG
Thanks for porting the patch. This is the mailing thread I started back in 2010 with that patch: http://lists.gnu.org/archive/html/qemu-devel/2010-11/msg02497.html That thread has some problems noted. Sadly, I did not have enough free time to investigate all the other places that should be fixed for proper fpip/etc. support. That patch seems to be related: https://patchwork.kernel.org/patch/871232/, but is kvm only. You could try contacting the person that did the patch for kvm. Nikita Skovoroda. 2013/6/29 Morten Shearman Kirkegaard <661...@bugs.launchpad.net>: > The bug is still present in the newly released QEMU-1.5.1. I've ported > Chalkerx's patch to this release as well. See attached patch. > > Is there a problem with this patch, since it has not been committed? > > // MOKI > > ** Patch added: "patch-qemu-1.5.1-fpip.diff" > > https://bugs.launchpad.net/qemu/+bug/661696/+attachment/3718352/+files/patch-qemu-1.5.1-fpip.diff -- You received this bug notification because you are a member of qemu- devel-ml, which is subscribed to QEMU. https://bugs.launchpad.net/bugs/661696 Title: incomplete emulation of fstenv under TCG Status in QEMU: New Bug description: Steps to reproduce: 1) Install Windows (tried XP and 7) in qemu (tried qemu without kvm and qemu-kvm). 2) Get OllyDbg ( http://ollydbg.de/odbg200.zip ). 3) Use some Metasploit-encoded file, example included. It is not a virus! File was generated with Metasploit, command (if i remember it right): `msfpayload windows/exec cmd=notepad R | msfencode -e x86/shikata_ga_nai -t exe -o cmd_exec_notepad.shikata_ga_nai.exe`. 4) Launch the file under Windows in qemu, make sure it opens a notepad. 5) Open file under OllyDbg, run (F9) it there. It opens a notpad. Close OllyDbg. 6) Open file under OllyDbg, trace over (Ctrl+F12) it there. It fails with `Access violation when writing to [some address]`. Command: 316A 13, XOR DWORD PTR DS:[EDX+13],EBP Under native Windows, the trace over command works fine. Under VMware the trace works fine. Under VirtualBox it also fails (checked in the spring). $ qemu-kvm --version QEMU PC emulator version 0.12.5 (qemu-kvm-0.12.5), Copyright (c) 2003-2008 Fabrice Bellard To manage notifications about this bug go to: https://bugs.launchpad.net/qemu/+bug/661696/+subscriptions
[Qemu-devel] How does 'make test' work?
How is one meant to make the tests? make test fails with: make[1]: Entering directory `/home/amb/qemu/git/qemu/tests/tcg' cc -m32 -I/home/amb/qemu/git/qemu/tcg -I/home/amb/qemu/git/qemu/tcg/i386 -I/home/amb/qemu/git/qemu/linux-headers -I/home/amb/qemu/git/qemu/linux-headers -I. -I/home/amb/qemu/git/qemu -I/home/amb/qemu/git/qemu/include -I. -I. -I../.. -pthread -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -O2 -g -c -o test_path.o test_path.c test_path.c:4:17: fatal error: iov.c: No such file or directory If I fudge the include path it still doesn't work (see below). I get the feeling I must have missed something. Alex amb@nimrod-ubuntu:~/qemu/git/qemu$ make test CFLAGS='-O2 -g -I/home/amb/qemu/git/qemu/util' CHK version_gen.h make -C tests/tcg test make[1]: Entering directory `/home/amb/qemu/git/qemu/tests/tcg' cc -m32 -I/home/amb/qemu/git/qemu/tcg -I/home/amb/qemu/git/qemu/tcg/i386 -I/home/amb/qemu/git/qemu/linux-headers -I/home/amb/qemu/git/qemu/linux-headers -I. -I/home/amb/qemu/git/qemu -I/home/amb/qemu/git/qemu/include -I. -I. -I../.. -pthread -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -O2 -g -I/home/amb/qemu/git/qemu/util -c -o test_path.o test_path.c In file included from /home/amb/qemu/git/qemu/util/cutils.c:25:0, from test_path.c:5: /home/amb/qemu/git/qemu/include/qemu/host-utils.h: In function ‘mulu64’: /home/amb/qemu/git/qemu/include/qemu/host-utils.h:35:5: error: unknown type name ‘__uint128_t’ /home/amb/qemu/git/qemu/include/qemu/host-utils.h:35:22: error: ‘__uint128_t’ undeclared (first use in this function) /home/amb/qemu/git/qemu/include/qemu/host-utils.h:35:22: note: each undeclared identifier is reported only once for each function it appears in /home/amb/qemu/git/qemu/include/qemu/host-utils.h:35:34: error: expected ‘,’ or ‘;’ before ‘a’ /home/amb/qemu/git/qemu/include/qemu/host-utils.h:37:5: warning: right shift count >= width of type [enabled by default] /home/amb/qemu/git/qemu/include/qemu/host-utils.h: In function ‘muls64’: /home/amb/qemu/git/qemu/include/qemu/host-utils.h:43:5: error: unknown type name ‘__int128_t’ /home/amb/qemu/git/qemu/include/qemu/host-utils.h:43:21: error: ‘__int128_t’ undeclared (first use in this function) /home/amb/qemu/git/qemu/include/qemu/host-utils.h:43:32: error: expected ‘,’ or ‘;’ before ‘a’ /home/amb/qemu/git/qemu/include/qemu/host-utils.h:45:5: warning: right shift count >= width of type [enabled by default] test_path.c: At top level: test_path.c:7:19: fatal error: trace.c: No such file or directory compilation terminated. make[1]: *** [test_path.o] Error 1 make[1]: Leaving directory `/home/amb/qemu/git/qemu/tests/tcg' make: *** [test] Error 2 -- Alex Bligh
[Qemu-devel] [PATCH] [RFC] Add delay option to blkdebug
This is an RFC for a very lightly tested patch.
[Qemu-devel] [PATCH] Add delay option to blkdebug
Add a delay option to blkdebug, allowing operations to be delayed by a specifiable number of microseconds. Example configuration: [inject-error] event = "read_aio" delay = "20" Signed-off-by: Alex Bligh --- block/blkdebug.c | 83 ++ 1 file changed, 83 insertions(+) diff --git a/block/blkdebug.c b/block/blkdebug.c index ccb627a..dafb805 100644 --- a/block/blkdebug.c +++ b/block/blkdebug.c @@ -40,6 +40,9 @@ typedef struct BlkdebugAIOCB { BlockDriverAIOCB common; QEMUBH *bh; int ret; +bool *finished; +int64_t delay; +int64_t starttime; } BlkdebugAIOCB; typedef struct BlkdebugSuspendedReq { @@ -71,6 +74,7 @@ typedef struct BlkdebugRule { int immediately; int once; int64_t sector; +int64_t delay; } inject; struct { int new_state; @@ -111,6 +115,10 @@ static QemuOptsList inject_error_opts = { .name = "immediately", .type = QEMU_OPT_BOOL, }, +{ +.name = "delay", /* delay in microseconds */ +.type = QEMU_OPT_NUMBER, +}, { /* end of list */ } }, }; @@ -236,6 +244,10 @@ static int add_rule(QemuOpts *opts, void *opaque) rule->options.inject.immediately = qemu_opt_get_bool(opts, "immediately", 0); rule->options.inject.sector = qemu_opt_get_number(opts, "sector", -1); +rule->options.inject.delay = qemu_opt_get_number(opts, "delay", 0); +if (rule->options.inject.delay) { +rule->options.inject.error = 0; +} break; case ACTION_SET_STATE: @@ -399,6 +411,9 @@ fail: static void error_callback_bh(void *opaque) { struct BlkdebugAIOCB *acb = opaque; +if (acb->finished) { +*acb->finished = true; +} qemu_bh_delete(acb->bh); acb->common.cb(acb->common.opaque, acb->ret); qemu_aio_release(acb); @@ -407,6 +422,13 @@ static void error_callback_bh(void *opaque) static void blkdebug_aio_cancel(BlockDriverAIOCB *blockacb) { BlkdebugAIOCB *acb = container_of(blockacb, BlkdebugAIOCB, common); +bool finished = false; + +/* Wait until request completes, invokes its callback, and frees itself */ +acb->finished = &finished; +while (!finished) { +qemu_aio_wait(); +} qemu_aio_release(acb); } @@ -427,6 +449,7 @@ static BlockDriverAIOCB *inject_error(BlockDriverState *bs, } acb = qemu_aio_get(&blkdebug_aiocb_info, bs, cb, opaque); +acb->finished = NULL; acb->ret = -error; bh = qemu_bh_new(error_callback_bh, acb); @@ -436,6 +459,50 @@ static BlockDriverAIOCB *inject_error(BlockDriverState *bs, return &acb->common; } +static BlkdebugAIOCB *blkdebug_aio_get(BlockDriverState *bs, int64_t delay, + BlockDriverCompletionFunc *cb, + void *opaque) +{ +BlkdebugAIOCB *acb = qemu_aio_get(&blkdebug_aiocb_info, bs, cb, opaque); + +acb->bh = NULL; +acb->delay = delay; +acb->finished = NULL; +return acb; +} + +static void blkdebug_aio_delay_bh(void *opaque) +{ +int64_t currenttime; +BlkdebugAIOCB *acb = opaque; + +/* Unfortunately we cannot use a timer as under qemu-img for instance + * the timer loop is not run. + */ +currenttime = qemu_get_clock_ns(rt_clock); +if ((currenttime - acb->starttime) < (acb->delay * 1000)) { +qemu_bh_schedule_idle(acb->bh); +return; +} + +qemu_bh_delete(acb->bh); + +acb->common.cb(acb->common.opaque, acb->ret); +if (acb->finished) { +*acb->finished = true; +} +qemu_aio_release(acb); +} + +static void blkdebug_aio_delay_cb(void *opaque, int ret) +{ +BlkdebugAIOCB *acb = opaque; + +acb->starttime = qemu_get_clock_ns(rt_clock); +acb->bh = qemu_bh_new(blkdebug_aio_delay_bh, acb); +qemu_bh_schedule_idle(acb->bh); +} + static BlockDriverAIOCB *blkdebug_aio_readv(BlockDriverState *bs, int64_t sector_num, QEMUIOVector *qiov, int nb_sectors, BlockDriverCompletionFunc *cb, void *opaque) @@ -455,6 +522,14 @@ static BlockDriverAIOCB *blkdebug_aio_readv(BlockDriverState *bs, return inject_error(bs, cb, opaque, rule); } +if (rule && rule->options.inject.delay) { +BlkdebugAIOCB *acb = blkdebug_aio_get(bs, rule->options.inject.delay, cb, opaque); + +bdrv_aio_readv(bs->file, sector_num, qiov, nb_sectors, + blkdebug_aio_delay_cb, acb); +return &acb->common; +} + return bdrv_aio_readv(bs->file, sector_num, qiov, nb_sectors, cb, opaque); } @@ -477,6 +552,14 @@ static BlockDriverAIOCB *blkdebug_aio_writev(BlockDriverState *bs, return inject_error(bs, cb, opaque, rule); } +if (rule && rule->options.inject.delay) { +BlkdebugAIOCB *acb = blkdebug_aio_get(bs, rule->options.inject.delay,
Re: [Qemu-devel] [PATCH 3/6] Added Aarch64 CPU Initialization, Get and Put Registers Support.
On 29.06.2013, at 19:48, Mian M. Hamayun wrote: > > On 06/28/2013 02:43 PM, Alexander Graf wrote: >> On 28.06.2013, at 14:11, Mian M. Hamayun wrote: >> >>> diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h >>> index c614070..4df5292 100644 >>> --- a/linux-headers/linux/kvm.h >>> +++ b/linux-headers/linux/kvm.h >>> @@ -783,6 +783,7 @@ struct kvm_dirty_tlb { >>> #define KVM_REG_IA640x3000ULL >>> #define KVM_REG_ARM 0x4000ULL >>> #define KVM_REG_S3900x5000ULL >>> +#define KVM_REG_ARM64 0x6000ULL >>> >>> #define KVM_REG_SIZE_SHIFT 52 >>> #define KVM_REG_SIZE_MASK 0x00f0ULL >> This should be part of your header update patch. > Just to make sure that we understand it correctly, do you mean that this > macro definition should be moved to the arm64 specific header that we include > in another patch series ? or keep this change in the same file and do it > along with the header inclusion in a single patch ? I'm saying you should generate the Linux header update from an upstream branch that includes this change. >>> +#ifdef TARGET_AARCH64 >>> +int kvm_arch_init_vcpu(CPUState *cs) >>> +{ >>> +struct kvm_vcpu_init init; >>> +int ret; >>> + >>> +/* Try initializing with Foundation Models */ >>> +init.target = KVM_ARM_TARGET_FOUNDATION_V8; >>> +memset(init.features, 0, sizeof(init.features)); >>> +ret = kvm_vcpu_ioctl(cs, KVM_ARM_VCPU_INIT, &init); >>> +if (ret) { >>> +/* Retry initializing with Fast Models */ >>> +init.target = KVM_ARM_TARGET_AEM_V8; >>> +ret = kvm_vcpu_ioctl(cs, KVM_ARM_VCPU_INIT, &init); >> Not sure I understand this part. Do we have different CPU types for the >> different models? If so, they'd be different -cpu parameters, with -cpu host >> picking the same as the host's. > KVM tool does a very similar thing, using a loop and tries to initialize > supported processors types and gets done when it succeeds with anyone of > them. We could include a similar implementation in the next revision. Is there no way to evaluate what we're running on so that we can expose the same thing to the guest? It's what -cpu host does usually. Taking one by trial-and-error breaks cross-virtualization. Alex
Re: [Qemu-devel] [PATCH 3/6] Added Aarch64 CPU Initialization, Get and Put Registers Support.
On 28 June 2013 13:11, Mian M. Hamayun wrote: > From: "Mian M. Hamayun" > > The init function tries to initialize with Foundation models first and on > failure retries initializing on Fast Models. > > Get and Put Registers deal with the basic state of Aarch64 CPUs for the > moment. > > Signed-off-by: Mian M. Hamayun > --- > linux-headers/linux/kvm.h |1 + > target-arm/cpu.c |8 +++ > target-arm/cpu.h |1 + > target-arm/kvm.c | 120 > + > 4 files changed, 130 insertions(+) > > diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h > index c614070..4df5292 100644 > --- a/linux-headers/linux/kvm.h > +++ b/linux-headers/linux/kvm.h > @@ -783,6 +783,7 @@ struct kvm_dirty_tlb { > #define KVM_REG_IA64 0x3000ULL > #define KVM_REG_ARM0x4000ULL > #define KVM_REG_S390 0x5000ULL > +#define KVM_REG_ARM64 0x6000ULL > > #define KVM_REG_SIZE_SHIFT 52 > #define KVM_REG_SIZE_MASK 0x00f0ULL > diff --git a/target-arm/cpu.c b/target-arm/cpu.c > index 496a59f..34eba77 100644 > --- a/target-arm/cpu.c > +++ b/target-arm/cpu.c > @@ -601,6 +601,13 @@ static void cortex_a15_initfn(Object *obj) > define_arm_cp_regs(cpu, cortexa15_cp_reginfo); > } > > +static void cortex_a57_initfn(Object *obj) > +{ > +ARMCPU *cpu = ARM_CPU(obj); > +set_feature(&cpu->env, ARM_FEATURE_V8); > +cpu->env.aarch64 = 1; /* We force 64-bit mode for guests */ This is definitely in the wrong place. cpu reset for 64 bit CPUs should start them off in AArch64. > +} > + > static void ti925t_initfn(Object *obj) > { > ARMCPU *cpu = ARM_CPU(obj); > @@ -781,6 +788,7 @@ static const ARMCPUInfo arm_cpus[] = { > { .name = "cortex-a8", .initfn = cortex_a8_initfn }, > { .name = "cortex-a9", .initfn = cortex_a9_initfn }, > { .name = "cortex-a15", .initfn = cortex_a15_initfn }, > +{ .name = "cortex-a57", .initfn = cortex_a57_initfn }, > { .name = "ti925t", .initfn = ti925t_initfn }, > { .name = "sa1100", .initfn = sa1100_initfn }, > { .name = "sa1110", .initfn = sa1110_initfn }, > diff --git a/target-arm/cpu.h b/target-arm/cpu.h > index cd42814..f1cae7f 100644 > --- a/target-arm/cpu.h > +++ b/target-arm/cpu.h > @@ -410,6 +410,7 @@ enum arm_features { > ARM_FEATURE_V6, > ARM_FEATURE_V6K, > ARM_FEATURE_V7, > +ARM_FEATURE_V8, > ARM_FEATURE_THUMB2, > ARM_FEATURE_MPU,/* Only has Memory Protection Unit, not full MMU. */ > ARM_FEATURE_VFP3, > diff --git a/target-arm/kvm.c b/target-arm/kvm.c > index 27dcab9..0125f16 100644 > --- a/target-arm/kvm.c > +++ b/target-arm/kvm.c > @@ -23,6 +23,11 @@ > #include "cpu.h" > #include "hw/arm/arm.h" > > +#ifdef TARGET_AARCH64 > +#define AARCH64_CORE_REG(x) (KVM_REG_ARM64 | KVM_REG_SIZE_U64 | \ > + KVM_REG_ARM_CORE | KVM_REG_ARM_CORE_REG(x)) > +#endif > + > const KVMCapabilityInfo kvm_arch_required_capabilities[] = { > KVM_CAP_LAST_INFO > }; > @@ -41,6 +46,28 @@ unsigned long kvm_arch_vcpu_id(CPUState *cpu) > return cpu->cpu_index; > } > > +#ifdef TARGET_AARCH64 > +int kvm_arch_init_vcpu(CPUState *cs) > +{ > +struct kvm_vcpu_init init; > +int ret; > + > +/* Try initializing with Foundation Models */ > +init.target = KVM_ARM_TARGET_FOUNDATION_V8; > +memset(init.features, 0, sizeof(init.features)); > +ret = kvm_vcpu_ioctl(cs, KVM_ARM_VCPU_INIT, &init); > +if (ret) { > +/* Retry initializing with Fast Models */ > +init.target = KVM_ARM_TARGET_AEM_V8; If we're emulating an A57 we should be asking KVM for an A57 guest. If we're asking KVM for "a CPU like the one in the Foundation model" we need to support that via -cpu $something. But I'm a bit dubious about that anyway -- you need to provide a good justification for why KVM/QEMU should be emulating emulators and not hardware. -- PMM
Re: [Qemu-devel] [PATCH 1/6] Added aarch64 configure support and default configuration
On 28 June 2013 13:11, Mian M. Hamayun wrote: > From: "Mian M. Hamayun" > > Signed-off-by: Mian M. Hamayun > --- > configure |3 +- > default-configs/aarch64-softmmu.mak | 83 > +++ > 2 files changed, 85 insertions(+), 1 deletion(-) > create mode 100644 default-configs/aarch64-softmmu.mak > > diff --git a/configure b/configure > index b247e5b..ddec40d 100755 > --- a/configure > +++ b/configure > @@ -4293,10 +4293,11 @@ case "$target_name" in >*) > esac > case "$target_name" in > - arm|i386|x86_64|ppcemb|ppc|ppc64|s390x) > + arm|aarch64|i386|x86_64|ppcemb|ppc|ppc64|s390x) > # Make sure the target and host cpus are compatible > if test "$kvm" = "yes" -a "$target_softmmu" = "yes" -a \ >\( "$target_name" = "$cpu" -o \ > + \( "$target_name" = "arm"-a "$cpu" = "aarch64" \) -o \ >\( "$target_name" = "ppcemb" -a "$cpu" = "ppc" \) -o \ >\( "$target_name" = "ppc64" -a "$cpu" = "ppc" \) -o \ >\( "$target_name" = "ppc"-a "$cpu" = "ppc64" \) -o \ So this is enabling support for emulating 32 bit VMs with a QEMU running as a 64 bit process, but the commit message doesn't mention this. Did you test that combination? thanks -- PMM
Re: [Qemu-devel] [PATCH 4/6] Added the Versatile Express Machine Model for A57
On 28 June 2013 13:11, Mian M. Hamayun wrote: > From: "Mian M. Hamayun" > > The vexpress model for A57 is based on the A15 machine model with a few > changes in the daughterboard initialization (using a subset of A15 > functionality). The A57 daughterboard init also shares the A15MPCore > private memory region with A15 daughterboard init function. So, which documentation or TRM or hardware are you basing this definition of an A57 Versatile Express daughterboard on? -- PMM
Re: [Qemu-devel] [PATCH 6/6] Added SMP for Aarch64 Processors.
On 28 June 2013 13:11, Mian M. Hamayun wrote: > From: Alexander Spyridakis > > AArch64 uses a cpu-release-addr memory location (defined in the dts) as > a way to inform secondary CPUs where to jump to and enter their holding > pen. Inject a very simple bootloader that polls this memory location, > until the primary CPU sets it to the right address. This and the previous patch are a bit heavy on the #ifdef TARGET_AARCH64. I suspect the code could be restructured better to avoid that. thanks -- PMM
[Qemu-devel] [PATCH RFC qom-cpu 00/41] QOM CPUState, part 11: GDB stub
Hello, This series cleans up gdbstub by changing all its internal CPU state to CPUState and by moving most target-specific code into the target directories. It depends on part 10 and starts with a follow-up, consolidating reset logging. Support for m68k, moxie and unicore32 to set the PC via gdbstub is added. Lightweight subclasses for XtensaCPU are introduced, keeping the XtensaConfig mechanisms, to stop xtensa from deviating at gdbstub level wrt register count. I'm wondering whether there would be interest in adding a "program-counter" dynamic property to the CPU, given that a setter has been factored out here? Available for testing at: git://github.com/afaerber/qemu-cpu.git qom-cpu-11.v1 https://github.com/afaerber/qemu-cpu/commits/qom-cpu-11.v1 Regards, Andreas Cc: Anthony Liguori Cc: Blue Swirl Cc: Aurélien Jarno Cc: Paolo Bonzini Cc: Jan Kiszka (gdbstub) Cc: Anthony Green (moxie) Cc: Guan Xuetao (unicore32) Cc: Max Filippov (xtensa) Andreas Färber (41): log: Change log_cpu_state[_mask]() argument to CPUState cpu: Move reset logging to CPUState gdbstub: Change GDBState::query_cpu to CPUState cpu: Introduce CPUClass::set_pc() for gdb_set_cpu_pc() target-m68k: Implement CPUClass::set_pc() target-moxie: Implement CPUClass::set_pc() target-unicore32: Implement CPUClass::set_pc() cpu: Introduce CPUClass::synchronize_from_tb() to drop cpu_pc_from_tb() gdbstub: Replace two find_cpu() with qemu_get_cpu() target-alpha: Change gen_intermediate_code_internal() argument to AlphaCPU target-arm: Change gen_intermediate_code_internal() argument to ARMCPU target-cris: Change gen_intermediate_code_internal() argument to CRISCPU target-i386: Change gen_intermediate_code_internal() argument to X86CPU target-lm32: Change gen_intermediate_code_internal() argument to LM32CPU target-m68k: Change gen_intermediate_code_internal() argument to M68kCPU target-microblaze: Change gen_intermediate_code_internal() argument types target-mips: Change gen_intermediate_code_internal() argument to MIPSCPU target-ppc: Change gen_intermediate_code_internal() argument to PowerPCCPU target-s390x: Change gen_intermediate_code_internal() argument to S390CPU target-sh4: Change gen_intermediate_code_internal() argument to SuperHCPU target-sparc: Change gen_intermediate_code_internal() argument to SPARCCPU target-unicore32: Change gen_intermediate_code_internal() signature target-xtensa: Change gen_intermediate_code_internal() arg to XtensaCPU target-alpha: Change DisasContext::env to CPUState cpu: Move singlestep_enabled field from CPU_COMMON to CPUState gdbstub: Update gdb_handlesig() and gdb_signalled() Coding Style cpu: Change cpu_single_step() argument to CPUState kvm: Change kvm_{insert,remove}_breakpoint() argument to CPUState gdbstub: Change syscall callback argument to CPUState gdbstub: Change gdb_handlesig() argument to CPUState gdbstub: Change GDBState::c_cpu to CPUState gdbstub: Change gdb_{read,write}_register() argument to CPUState cpu: Turn cpu_get_phys_page_debug() into a CPUClass hook exec: Change cpu_memory_rw_debug() argument to CPUState cpu: Introduce CPUClass::memory_rw_debug() for target_memory_rw_debug() gdbstub: Change GDBState::g_cpu to CPUState cpu: Move gdb_regs field from CPU_COMMON to CPUState gdbstub: Change gdb_register_coprocessor() argument to CPUState target-xtensa: Introduce XtensaCPU subclasses gdbstub: Move num_g_regs to CPUState and NUM_CORE_REGS to CPUClass cpu: Introduce CPUClass::gdb_{read,write}_register() bsd-user/main.c | 10 +- cpu-exec.c | 16 +- cpus.c |6 +- disas.c |4 +- exec.c | 38 +- gdbstub.c | 1590 --- hw/i386/kvmvapic.c | 78 +- hw/xtensa/pic_cpu.c | 47 +- include/exec/cpu-all.h | 14 +- include/exec/cpu-defs.h |3 - include/exec/exec-all.h |3 - include/exec/gdbstub.h | 45 +- include/exec/softmmu-semi.h | 18 +- include/qemu/log.h | 26 +- include/qemu/typedefs.h |3 + include/qom/cpu.h | 95 ++- include/sysemu/kvm.h|4 +- kvm-all.c | 12 +- kvm-stub.c |4 +- linux-user/main.c | 40 +- linux-user/signal.c |3 +- monitor.c |2 +- qom/cpu.c | 30 + target-alpha/Makefile.objs |1 + target-alpha/cpu-qom.h |3 + target-alpha/cpu.c | 18 +- target-alpha/cpu.h |5 - target-alpha/gdbstub.c | 93 +++ target-alpha/helper.c |5 +- target-alpha/translate.c| 25 +- target-arm/Makefile.objs|1 + target-
[Qemu-devel] [PATCH RFC qom-cpu 05/41] target-m68k: Implement CPUClass::set_pc()
This adds support for GDB's c addr (Continue) and s addr (Single Step). Prepares for dropping cpu_pc_from_tb(). Signed-off-by: Andreas Färber --- target-m68k/cpu.c | 8 1 file changed, 8 insertions(+) diff --git a/target-m68k/cpu.c b/target-m68k/cpu.c index 1b6ef66..1ac1893 100644 --- a/target-m68k/cpu.c +++ b/target-m68k/cpu.c @@ -23,6 +23,13 @@ #include "migration/vmstate.h" +static void m68k_cpu_set_pc(CPUState *cs, uint64_t value) +{ +M68kCPU *cpu = M68K_CPU(cs); + +cpu->env.pc = value; +} + static void m68k_set_feature(CPUM68KState *env, int feature) { env->features |= (1u << feature); @@ -182,6 +189,7 @@ static void m68k_cpu_class_init(ObjectClass *c, void *data) cc->class_by_name = m68k_cpu_class_by_name; cc->do_interrupt = m68k_cpu_do_interrupt; cc->dump_state = m68k_cpu_dump_state; +cc->set_pc = m68k_cpu_set_pc; dc->vmsd = &vmstate_m68k_cpu; } -- 1.8.1.4
[Qemu-devel] [PATCH RFC qom-cpu 07/41] target-unicore32: Implement CPUClass::set_pc()
This adds support for GDB's c addr (Continue) and s addr (Single Step). Prepares for dropping cpu_pc_from_tb(). Signed-off-by: Andreas Färber --- target-unicore32/cpu.c | 8 1 file changed, 8 insertions(+) diff --git a/target-unicore32/cpu.c b/target-unicore32/cpu.c index 6572f01..2e99bd3 100644 --- a/target-unicore32/cpu.c +++ b/target-unicore32/cpu.c @@ -16,6 +16,13 @@ #include "qemu-common.h" #include "migration/vmstate.h" +static void uc32_cpu_set_pc(CPUState *cs, uint64_t value) +{ +UniCore32CPU *cpu = UNICORE32_CPU(cs); + +cpu->env.regs[31] = value; +} + static inline void set_feature(CPUUniCore32State *env, int feature) { env->features |= feature; @@ -131,6 +138,7 @@ static void uc32_cpu_class_init(ObjectClass *oc, void *data) cc->class_by_name = uc32_cpu_class_by_name; cc->do_interrupt = uc32_cpu_do_interrupt; cc->dump_state = uc32_cpu_dump_state; +cc->set_pc = uc32_cpu_set_pc; dc->vmsd = &vmstate_uc32_cpu; } -- 1.8.1.4
[Qemu-devel] [PATCH RFC qom-cpu 03/41] gdbstub: Change GDBState::query_cpu to CPUState
Since first_cpu/next_cpu are CPUState, CPUArchState is no longer needed. Signed-off-by: Andreas Färber --- gdbstub.c | 9 - 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/gdbstub.c b/gdbstub.c index 5793bcd..4a0d04e 100644 --- a/gdbstub.c +++ b/gdbstub.c @@ -289,7 +289,7 @@ enum RSState { typedef struct GDBState { CPUArchState *c_cpu; /* current CPU for step/continue ops */ CPUArchState *g_cpu; /* current CPU for other ops */ -CPUArchState *query_cpu; /* for q{f|s}ThreadInfo */ +CPUState *query_cpu; /* for q{f|s}ThreadInfo */ enum RSState state; /* parsing state */ char line_buf[MAX_PACKET_LENGTH]; int line_buf_index; @@ -2399,15 +2399,14 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf) put_packet(s, "QC1"); break; } else if (strcmp(p,"fThreadInfo") == 0) { -s->query_cpu = first_cpu->env_ptr; +s->query_cpu = first_cpu; goto report_cpuinfo; } else if (strcmp(p,"sThreadInfo") == 0) { report_cpuinfo: if (s->query_cpu) { -snprintf(buf, sizeof(buf), "m%x", - cpu_index(ENV_GET_CPU(s->query_cpu))); +snprintf(buf, sizeof(buf), "m%x", cpu_index(s->query_cpu)); put_packet(s, buf); -s->query_cpu = ENV_GET_CPU(s->query_cpu)->next_cpu->env_ptr; +s->query_cpu = s->query_cpu->next_cpu; } else put_packet(s, "l"); break; -- 1.8.1.4
[Qemu-devel] [PATCH RFC qom-cpu 02/41] cpu: Move reset logging to CPUState
x86 was using additional CPU_DUMP_* flags, so make that configurable in CPUClass::reset_dump_flags. This adds reset logging for alpha, unicore32 and xtensa. Signed-off-by: Andreas Färber --- include/qom/cpu.h | 2 ++ qom/cpu.c | 8 target-arm/cpu.c| 5 - target-cris/cpu.c | 5 - target-i386/cpu.c | 6 +- target-lm32/cpu.c | 5 - target-m68k/cpu.c | 5 - target-microblaze/cpu.c | 5 - target-mips/cpu.c | 5 - target-moxie/cpu.c | 5 - target-openrisc/cpu.c | 5 - target-ppc/translate_init.c | 5 - target-s390x/cpu.c | 5 - target-sh4/cpu.c| 5 - target-sparc/cpu.c | 5 - 15 files changed, 11 insertions(+), 65 deletions(-) diff --git a/include/qom/cpu.h b/include/qom/cpu.h index a08a8ab..147c256 100644 --- a/include/qom/cpu.h +++ b/include/qom/cpu.h @@ -53,6 +53,7 @@ typedef void (*CPUUnassignedAccess)(CPUState *cpu, hwaddr addr, * @class_by_name: Callback to map -cpu command line model name to an * instantiatable CPU type. * @reset: Callback to reset the #CPUState to its initial state. + * @reset_dump_flags: #CPUDumpFlags to use for reset logging. * @do_interrupt: Callback for interrupt handling. * @do_unassigned_access: Callback for unassigned access handling. * @dump_state: Callback for dumping state. @@ -72,6 +73,7 @@ typedef struct CPUClass { ObjectClass *(*class_by_name)(const char *cpu_model); void (*reset)(CPUState *cpu); +int reset_dump_flags; void (*do_interrupt)(CPUState *cpu); CPUUnassignedAccess do_unassigned_access; void (*dump_state)(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf, diff --git a/qom/cpu.c b/qom/cpu.c index ee8f632..5c45ab5 100644 --- a/qom/cpu.c +++ b/qom/cpu.c @@ -22,6 +22,7 @@ #include "qom/cpu.h" #include "sysemu/kvm.h" #include "qemu/notify.h" +#include "qemu/log.h" #include "sysemu/sysemu.h" typedef struct CPUExistsArgs { @@ -187,6 +188,13 @@ void cpu_reset(CPUState *cpu) static void cpu_common_reset(CPUState *cpu) { +CPUClass *cc = CPU_GET_CLASS(cpu); + +if (qemu_loglevel_mask(CPU_LOG_RESET)) { +qemu_log("CPU Reset (CPU %d)\n", cpu->cpu_index); +log_cpu_state(cpu, cc->reset_dump_flags); +} + cpu->exit_request = 0; cpu->interrupt_request = 0; cpu->current_tb = NULL; diff --git a/target-arm/cpu.c b/target-arm/cpu.c index 84974a9..be26acc 100644 --- a/target-arm/cpu.c +++ b/target-arm/cpu.c @@ -63,11 +63,6 @@ static void arm_cpu_reset(CPUState *s) ARMCPUClass *acc = ARM_CPU_GET_CLASS(cpu); CPUARMState *env = &cpu->env; -if (qemu_loglevel_mask(CPU_LOG_RESET)) { -qemu_log("CPU Reset (CPU %d)\n", s->cpu_index); -log_cpu_state(s, 0); -} - acc->parent_reset(s); memset(env, 0, offsetof(CPUARMState, breakpoints)); diff --git a/target-cris/cpu.c b/target-cris/cpu.c index f6c4f3f..2abb57f 100644 --- a/target-cris/cpu.c +++ b/target-cris/cpu.c @@ -34,11 +34,6 @@ static void cris_cpu_reset(CPUState *s) CPUCRISState *env = &cpu->env; uint32_t vr; -if (qemu_loglevel_mask(CPU_LOG_RESET)) { -qemu_log("CPU Reset (CPU %d)\n", s->cpu_index); -log_cpu_state(s, 0); -} - ccc->parent_reset(s); vr = env->pregs[PR_VR]; diff --git a/target-i386/cpu.c b/target-i386/cpu.c index 82a451b..e3f75a8 100644 --- a/target-i386/cpu.c +++ b/target-i386/cpu.c @@ -2175,11 +2175,6 @@ static void x86_cpu_reset(CPUState *s) CPUX86State *env = &cpu->env; int i; -if (qemu_loglevel_mask(CPU_LOG_RESET)) { -qemu_log("CPU Reset (CPU %d)\n", s->cpu_index); -log_cpu_state(s, CPU_DUMP_FPU | CPU_DUMP_CCOP); -} - xcc->parent_reset(s); @@ -2523,6 +2518,7 @@ static void x86_cpu_common_class_init(ObjectClass *oc, void *data) xcc->parent_reset = cc->reset; cc->reset = x86_cpu_reset; +cc->reset_dump_flags = CPU_DUMP_FPU | CPU_DUMP_CCOP; cc->do_interrupt = x86_cpu_do_interrupt; cc->dump_state = x86_cpu_dump_state; diff --git a/target-lm32/cpu.c b/target-lm32/cpu.c index 6e44d45..04327ac 100644 --- a/target-lm32/cpu.c +++ b/target-lm32/cpu.c @@ -29,11 +29,6 @@ static void lm32_cpu_reset(CPUState *s) LM32CPUClass *lcc = LM32_CPU_GET_CLASS(cpu); CPULM32State *env = &cpu->env; -if (qemu_loglevel_mask(CPU_LOG_RESET)) { -qemu_log("CPU Reset (CPU %d)\n", s->cpu_index); -log_cpu_state(s, 0); -} - lcc->parent_reset(s); /* reset cpu state */ diff --git a/target-m68k/cpu.c b/target-m68k/cpu.c index c9ac30f..1b6ef66 100644 --- a/target-m68k/cpu.c +++ b/target-m68k/cpu.c @@ -35,11 +35,6 @@ static void m68k_cpu_reset(CPUState *s) M68kCPUClass *mcc = M68K_CPU_GET_CLASS(cpu); CPUM68KState *env = &cpu->env; -if (qemu_loglevel_mask(CPU_LOG_RESET)) { -qemu_log("CPU Reset (CPU %d)\n", s->cpu_index); -log_
[Qemu-devel] [PATCH RFC qom-cpu 06/41] target-moxie: Implement CPUClass::set_pc()
This adds support for GDB's c addr (Continue) and s addr (Single Step). Prepares for dropping cpu_pc_from_tb(). Signed-off-by: Andreas Färber --- target-moxie/cpu.c | 8 1 file changed, 8 insertions(+) diff --git a/target-moxie/cpu.c b/target-moxie/cpu.c index 92ca594..8e32584 100644 --- a/target-moxie/cpu.c +++ b/target-moxie/cpu.c @@ -22,6 +22,13 @@ #include "migration/vmstate.h" #include "machine.h" +static void moxie_cpu_set_pc(CPUState *cs, uint64_t value) +{ +MoxieCPU *cpu = MOXIE_CPU(cs); + +cpu->env.pc = value; +} + static void moxie_cpu_reset(CPUState *s) { MoxieCPU *cpu = MOXIE_CPU(s); @@ -93,6 +100,7 @@ static void moxie_cpu_class_init(ObjectClass *oc, void *data) cc->do_interrupt = moxie_cpu_do_interrupt; cc->dump_state = moxie_cpu_dump_state; +cc->set_pc = moxie_cpu_set_pc; cpu_class_set_vmsd(cc, &vmstate_moxie_cpu); } -- 1.8.1.4
[Qemu-devel] [PATCH RFC qom-cpu 01/41] log: Change log_cpu_state[_mask]() argument to CPUState
Since commit 878096eeb278a8ac1ccd6667af73e026f29b4cf5 (cpu: Turn cpu_dump_{state,statistics}() into CPUState hooks) CPUArchState is no longer needed. Add documentation and make the functions available through qemu/log.h outside NEED_CPU_H to allow use in qom/cpu.c. Moving them to qom/cpu.h was not yet possible due to convoluted include paths, so that some devices grow an implicit and unneeded dependency on qom/cpu.h for now. Signed-off-by: Andreas Färber --- cpu-exec.c| 6 +++--- exec.c| 2 +- include/qemu/log.h| 26 +- linux-user/main.c | 5 +++-- target-arm/cpu.c | 2 +- target-cris/cpu.c | 2 +- target-i386/cpu.c | 2 +- target-i386/seg_helper.c | 5 +++-- target-i386/smm_helper.c | 6 -- target-lm32/cpu.c | 2 +- target-lm32/helper.c | 4 ++-- target-m68k/cpu.c | 2 +- target-microblaze/cpu.c | 2 +- target-microblaze/helper.c| 12 ++-- target-microblaze/translate.c | 5 - target-mips/cpu.c | 2 +- target-mips/helper.c | 2 +- target-moxie/cpu.c| 2 +- target-openrisc/cpu.c | 2 +- target-openrisc/translate.c | 2 +- target-ppc/mmu-hash32.c | 2 +- target-ppc/mmu-hash64.c | 2 +- target-ppc/mmu_helper.c | 2 +- target-ppc/translate_init.c | 2 +- target-s390x/cpu.c| 2 +- target-sh4/cpu.c | 2 +- target-sh4/helper.c | 2 +- target-sparc/cpu.c| 2 +- target-sparc/int32_helper.c | 2 +- target-sparc/int64_helper.c | 2 +- 30 files changed, 68 insertions(+), 45 deletions(-) diff --git a/cpu-exec.c b/cpu-exec.c index 503b103..9c46846 100644 --- a/cpu-exec.c +++ b/cpu-exec.c @@ -577,15 +577,15 @@ int cpu_exec(CPUArchState *env) if (qemu_loglevel_mask(CPU_LOG_TB_CPU)) { /* restore flags in standard format */ #if defined(TARGET_I386) -log_cpu_state(env, CPU_DUMP_CCOP); +log_cpu_state(cpu, CPU_DUMP_CCOP); #elif defined(TARGET_M68K) cpu_m68k_flush_flags(env, env->cc_op); env->cc_op = CC_OP_FLAGS; env->sr = (env->sr & 0xffe0) | env->cc_dest | (env->cc_x << 4); -log_cpu_state(env, 0); +log_cpu_state(cpu, 0); #else -log_cpu_state(env, 0); +log_cpu_state(cpu, 0); #endif } #endif /* DEBUG_DISAS */ diff --git a/exec.c b/exec.c index fe419f7..4e20143 100644 --- a/exec.c +++ b/exec.c @@ -613,7 +613,7 @@ void cpu_abort(CPUArchState *env, const char *fmt, ...) qemu_log("qemu: fatal: "); qemu_log_vprintf(fmt, ap2); qemu_log("\n"); -log_cpu_state(env, CPU_DUMP_FPU | CPU_DUMP_CCOP); +log_cpu_state(cpu, CPU_DUMP_FPU | CPU_DUMP_CCOP); qemu_log_flush(); qemu_log_close(); } diff --git a/include/qemu/log.h b/include/qemu/log.h index a9cf214..d515424 100644 --- a/include/qemu/log.h +++ b/include/qemu/log.h @@ -5,6 +5,7 @@ #include #include #include "qemu/compiler.h" +#include "qom/cpu.h" #ifdef NEED_CPU_H #include "disas/disas.h" #endif @@ -70,22 +71,37 @@ void GCC_FMT_ATTR(2, 3) qemu_log_mask(int mask, const char *fmt, ...); /* Special cases: */ -#ifdef NEED_CPU_H /* cpu_dump_state() logging functions: */ -static inline void log_cpu_state(CPUArchState *env1, int flags) +/** + * log_cpu_state: + * @cpu: The CPU whose state is to be logged. + * @flags: Flags what to log. + * + * Logs the output of cpu_dump_state(). + */ +static inline void log_cpu_state(CPUState *cpu, int flags) { if (qemu_log_enabled()) { -cpu_dump_state(ENV_GET_CPU(env1), qemu_logfile, fprintf, flags); +cpu_dump_state(cpu, qemu_logfile, fprintf, flags); } } -static inline void log_cpu_state_mask(int mask, CPUArchState *env1, int flags) +/** + * log_cpu_state_mask: + * @mask: Mask when to log. + * @cpu: The CPU whose state is to be logged. + * @flags: Flags what to log. + * + * Logs the output of cpu_dump_state() if loglevel includes @mask. + */ +static inline void log_cpu_state_mask(int mask, CPUState *cpu, int flags) { if (qemu_loglevel & mask) { -log_cpu_state(env1, flags); +log_cpu_state(cpu, flags); } } +#ifdef NEED_CPU_H /* disas() and target_disas() to qemu_logfile: */ static inline void log_target_disas(CPUArchState *env, target_ulong start, target_ulong len, int flags) diff --git a/linux-user/main.c b/linux-user/main.c index 67ea9ba..7f15d3d 100644 --- a/linux-user/main.c +++ b/linux-user/main.c @@ -1302,11 +1302,12 @@ int ppc_dcr_write (ppc_dcr_t *dcr_env, int dcrn, uint32_t val) #define EXCP_DUMP(env, fmt, ...)\ do {
[Qemu-devel] [PATCH RFC qom-cpu 11/41] target-arm: Change gen_intermediate_code_internal() argument to ARMCPU
Also use bool type while at it. Prepares for moving singlestep_enabled field to CPUState. Signed-off-by: Andreas Färber --- target-arm/translate.c | 9 + 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/target-arm/translate.c b/target-arm/translate.c index af2aef2..9310c58 100644 --- a/target-arm/translate.c +++ b/target-arm/translate.c @@ -9796,10 +9796,11 @@ undef: /* generate intermediate code in gen_opc_buf and gen_opparam_buf for basic block 'tb'. If search_pc is TRUE, also generate PC information for each intermediate instruction. */ -static inline void gen_intermediate_code_internal(CPUARMState *env, +static inline void gen_intermediate_code_internal(ARMCPU *cpu, TranslationBlock *tb, - int search_pc) + bool search_pc) { +CPUARMState *env = &cpu->env; DisasContext dc1, *dc = &dc1; CPUBreakpoint *bp; uint16_t *gen_opc_end; @@ -10072,12 +10073,12 @@ done_generating: void gen_intermediate_code(CPUARMState *env, TranslationBlock *tb) { -gen_intermediate_code_internal(env, tb, 0); +gen_intermediate_code_internal(arm_env_get_cpu(env), tb, false); } void gen_intermediate_code_pc(CPUARMState *env, TranslationBlock *tb) { -gen_intermediate_code_internal(env, tb, 1); +gen_intermediate_code_internal(arm_env_get_cpu(env), tb, true); } static const char *cpu_mode_names[16] = { -- 1.8.1.4
[Qemu-devel] [PATCH RFC qom-cpu 21/41] target-sparc: Change gen_intermediate_code_internal() argument to SPARCCPU
Also use bool type while at it. Prepares for moving singlestep_enabled field to CPUState. Signed-off-by: Andreas Färber --- target-sparc/translate.c | 10 ++ 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/target-sparc/translate.c b/target-sparc/translate.c index eb6e800..5e771e5 100644 --- a/target-sparc/translate.c +++ b/target-sparc/translate.c @@ -5219,9 +5219,11 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn) } } -static inline void gen_intermediate_code_internal(TranslationBlock * tb, - int spc, CPUSPARCState *env) +static inline void gen_intermediate_code_internal(SPARCCPU *cpu, + TranslationBlock *tb, + bool spc) { +CPUSPARCState *env = &cpu->env; target_ulong pc_start, last_pc; uint16_t *gen_opc_end; DisasContext dc1, *dc = &dc1; @@ -5347,12 +5349,12 @@ static inline void gen_intermediate_code_internal(TranslationBlock * tb, void gen_intermediate_code(CPUSPARCState * env, TranslationBlock * tb) { -gen_intermediate_code_internal(tb, 0, env); +gen_intermediate_code_internal(sparc_env_get_cpu(env), tb, false); } void gen_intermediate_code_pc(CPUSPARCState * env, TranslationBlock * tb) { -gen_intermediate_code_internal(tb, 1, env); +gen_intermediate_code_internal(sparc_env_get_cpu(env), tb, true); } void gen_intermediate_code_init(CPUSPARCState *env) -- 1.8.1.4
[Qemu-devel] [PATCH RFC qom-cpu 09/41] gdbstub: Replace two find_cpu() with qemu_get_cpu()
Since commit cb446ecab714b2444a270be209e0533bcd2ee534 (kvm: Change cpu_synchronize_state() argument to CPUState), one was no longer accessing CPUArchState, the other was just checking existence. Signed-off-by: Andreas Färber --- gdbstub.c | 10 +- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/gdbstub.c b/gdbstub.c index bdf4496..07838eb 100644 --- a/gdbstub.c +++ b/gdbstub.c @@ -2065,6 +2065,7 @@ static CPUArchState *find_cpu(uint32_t thread_id) static int gdb_handle_packet(GDBState *s, const char *line_buf) { CPUArchState *env; +CPUState *cpu; const char *p; uint32_t thread; int ch, reg_size, type, res; @@ -2333,9 +2334,9 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf) break; case 'T': thread = strtoull(p, (char **)&p, 16); -env = find_cpu(thread); +cpu = qemu_get_cpu(thread); -if (env != NULL) { +if (cpu != NULL) { put_packet(s, "OK"); } else { put_packet(s, "E22"); @@ -2385,9 +2386,8 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf) break; } else if (strncmp(p,"ThreadExtraInfo,", 16) == 0) { thread = strtoull(p+16, (char **)&p, 16); -env = find_cpu(thread); -if (env != NULL) { -CPUState *cpu = ENV_GET_CPU(env); +cpu = qemu_get_cpu(thread); +if (cpu != NULL) { cpu_synchronize_state(cpu); len = snprintf((char *)mem_buf, sizeof(mem_buf), "CPU#%d [%s]", cpu->cpu_index, -- 1.8.1.4
[Qemu-devel] [PATCH RFC qom-cpu 08/41] cpu: Introduce CPUClass::synchronize_from_tb() to drop cpu_pc_from_tb()
Where no extra implementation is needed, fall back to CPUClass::set_pc(). Signed-off-by: Andreas Färber --- cpu-exec.c | 8 +++- include/exec/exec-all.h | 3 --- include/qemu/typedefs.h | 3 +++ include/qom/cpu.h | 1 + target-alpha/cpu.h | 5 - target-arm/cpu.h| 5 - target-cris/cpu.h | 4 target-i386/cpu.c | 8 target-i386/cpu.h | 5 - target-lm32/cpu.h | 5 - target-m68k/cpu.h | 5 - target-microblaze/cpu.h | 5 - target-mips/cpu.c | 11 +++ target-mips/cpu.h | 7 --- target-moxie/cpu.h | 5 - target-openrisc/cpu.h | 5 - target-ppc/cpu.h| 5 - target-s390x/cpu.h | 5 - target-sh4/cpu.c| 9 + target-sh4/cpu.h| 6 -- target-sparc/cpu.c | 9 + target-sparc/cpu.h | 6 -- target-unicore32/cpu.h | 5 - target-xtensa/cpu.h | 5 - 24 files changed, 48 insertions(+), 87 deletions(-) diff --git a/cpu-exec.c b/cpu-exec.c index 9c46846..88f4e75 100644 --- a/cpu-exec.c +++ b/cpu-exec.c @@ -59,8 +59,14 @@ static inline tcg_target_ulong cpu_tb_exec(CPUState *cpu, uint8_t *tb_ptr) * counter hit zero); we must restore the guest PC to the address * of the start of the TB. */ +CPUClass *cc = CPU_GET_CLASS(cpu); TranslationBlock *tb = (TranslationBlock *)(next_tb & ~TB_EXIT_MASK); -cpu_pc_from_tb(env, tb); +if (cc->synchronize_from_tb) { +cc->synchronize_from_tb(cpu, tb); +} else { +assert(cc->set_pc); +cc->set_pc(cpu, tb->pc); +} } if ((next_tb & TB_EXIT_MASK) == TB_EXIT_REQUESTED) { /* We were asked to stop executing TBs (probably a pending diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h index b2162a4..5e33e03 100644 --- a/include/exec/exec-all.h +++ b/include/exec/exec-all.h @@ -40,9 +40,6 @@ typedef ram_addr_t tb_page_addr_t; #define DISAS_UPDATE 2 /* cpu state was modified dynamically */ #define DISAS_TB_JUMP 3 /* only pc was modified statically */ -struct TranslationBlock; -typedef struct TranslationBlock TranslationBlock; - /* XXX: make safe guess about sizes */ #define MAX_OP_PER_INSTR 208 diff --git a/include/qemu/typedefs.h b/include/qemu/typedefs.h index 698fc03..dba6e95 100644 --- a/include/qemu/typedefs.h +++ b/include/qemu/typedefs.h @@ -24,6 +24,9 @@ typedef struct MemoryRegionSection MemoryRegionSection; typedef struct MemoryMappingList MemoryMappingList; +struct TranslationBlock; +typedef struct TranslationBlock TranslationBlock; + typedef struct NICInfo NICInfo; typedef struct HCIInfo HCIInfo; typedef struct AudioState AudioState; diff --git a/include/qom/cpu.h b/include/qom/cpu.h index 3701eb1..d8b77af 100644 --- a/include/qom/cpu.h +++ b/include/qom/cpu.h @@ -85,6 +85,7 @@ typedef struct CPUClass { void (*get_memory_mapping)(CPUState *cpu, MemoryMappingList *list, Error **errp); void (*set_pc)(CPUState *cpu, uint64_t value); +void (*synchronize_from_tb)(CPUState *cpu, struct TranslationBlock *tb); const struct VMStateDescription *vmsd; int (*write_elf64_note)(WriteCoreDumpFunction f, CPUState *cpu, diff --git a/target-alpha/cpu.h b/target-alpha/cpu.h index 066f032..c85dc6e 100644 --- a/target-alpha/cpu.h +++ b/target-alpha/cpu.h @@ -515,9 +515,4 @@ static inline bool cpu_has_work(CPUState *cpu) #include "exec/exec-all.h" -static inline void cpu_pc_from_tb(CPUAlphaState *env, TranslationBlock *tb) -{ -env->pc = tb->pc; -} - #endif /* !defined (__CPU_ALPHA_H__) */ diff --git a/target-arm/cpu.h b/target-arm/cpu.h index 1369604..0027492 100644 --- a/target-arm/cpu.h +++ b/target-arm/cpu.h @@ -796,11 +796,6 @@ static inline bool cpu_has_work(CPUState *cpu) #include "exec/exec-all.h" -static inline void cpu_pc_from_tb(CPUARMState *env, TranslationBlock *tb) -{ -env->regs[15] = tb->pc; -} - /* Load an instruction and return it in the standard little-endian order */ static inline uint32_t arm_ldl_code(CPUARMState *env, uint32_t addr, bool do_swap) diff --git a/target-cris/cpu.h b/target-cris/cpu.h index c12a8ca..4b9fc4c 100644 --- a/target-cris/cpu.h +++ b/target-cris/cpu.h @@ -279,8 +279,4 @@ static inline bool cpu_has_work(CPUState *cpu) #include "exec/exec-all.h" -static inline void cpu_pc_from_tb(CPUCRISState *env, TranslationBlock *tb) -{ -env->pc = tb->pc; -} #endif diff --git a/target-i386/cpu.c b/target-i386/cpu.c index 83584e6..eda2444 100644 --- a/target-i386/cpu.c +++ b/target-i386/cpu.c @@ -2513,6 +2513,13 @@ static void x86_cpu_set_pc(CPUState *cs, uint64_t value) cpu->env.eip = value; } +static void x86_cpu_synchronize_from_tb(CPUState *cs, TranslationBlock *tb) +{ +X86CPU *cpu = X86_CPU(cs); + +cpu->env.eip = tb->pc - tb->cs_base; +} + static
[Qemu-devel] [PATCH RFC qom-cpu 27/41] cpu: Change cpu_single_step() argument to CPUState
Use CPUState::env_ptr for now. Needed for GdbState::c_cpu. Signed-off-by: Andreas Färber --- exec.c | 4 ++-- gdbstub.c | 9 + include/exec/cpu-all.h | 6 -- include/qom/cpu.h | 6 ++ 4 files changed, 13 insertions(+), 12 deletions(-) diff --git a/exec.c b/exec.c index f2d848c..56a1d84 100644 --- a/exec.c +++ b/exec.c @@ -581,10 +581,10 @@ void cpu_breakpoint_remove_all(CPUArchState *env, int mask) /* enable or disable single step mode. EXCP_DEBUG is returned by the CPU loop after each instruction */ -void cpu_single_step(CPUArchState *env, int enabled) +void cpu_single_step(CPUState *cpu, int enabled) { #if defined(TARGET_HAS_ICE) -CPUState *cpu = ENV_GET_CPU(env); +CPUArchState *env = cpu->env_ptr; if (cpu->singlestep_enabled != enabled) { cpu->singlestep_enabled = enabled; diff --git a/gdbstub.c b/gdbstub.c index ede5cb1..17da380 100644 --- a/gdbstub.c +++ b/gdbstub.c @@ -2153,7 +2153,7 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf) s->c_cpu = env; } if (res == 's') { -cpu_single_step(s->c_cpu, sstep_flags); +cpu_single_step(ENV_GET_CPU(s->c_cpu), sstep_flags); } s->signal = res_signal; gdb_continue(s); @@ -2181,7 +2181,7 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf) addr = strtoull(p, (char **)&p, 16); gdb_set_cpu_pc(s, addr); } -cpu_single_step(s->c_cpu, sstep_flags); +cpu_single_step(ENV_GET_CPU(s->c_cpu), sstep_flags); gdb_continue(s); return RS_IDLE; case 'F': @@ -2568,7 +2568,7 @@ send_packet: put_packet(s, buf); /* disable single step if it was enabled */ -cpu_single_step(env, 0); +cpu_single_step(cpu, 0); } #endif @@ -2761,6 +2761,7 @@ gdb_queuesig (void) int gdb_handlesig(CPUArchState *env, int sig) { +CPUState *cpu = ENV_GET_CPU(env); GDBState *s; char buf[256]; int n; @@ -2771,7 +2772,7 @@ gdb_handlesig(CPUArchState *env, int sig) } /* disable single step if it was enabled */ -cpu_single_step(env, 0); +cpu_single_step(cpu, 0); tb_flush(env); if (sig != 0) { diff --git a/include/exec/cpu-all.h b/include/exec/cpu-all.h index 6499cd0..1f3c002 100644 --- a/include/exec/cpu-all.h +++ b/include/exec/cpu-all.h @@ -428,12 +428,6 @@ int cpu_watchpoint_remove(CPUArchState *env, target_ulong addr, void cpu_watchpoint_remove_by_ref(CPUArchState *env, CPUWatchpoint *watchpoint); void cpu_watchpoint_remove_all(CPUArchState *env, int mask); -#define SSTEP_ENABLE 0x1 /* Enable simulated HW single stepping */ -#define SSTEP_NOIRQ 0x2 /* Do not use IRQ while single stepping */ -#define SSTEP_NOTIMER 0x4 /* Do not Timers while single stepping */ - -void cpu_single_step(CPUArchState *env, int enabled); - #if !defined(CONFIG_USER_ONLY) /* Return the physical page corresponding to a virtual one. Use it diff --git a/include/qom/cpu.h b/include/qom/cpu.h index a02b142..cd10b1d 100644 --- a/include/qom/cpu.h +++ b/include/qom/cpu.h @@ -482,6 +482,12 @@ void cpu_resume(CPUState *cpu); */ void qemu_init_vcpu(CPUState *cpu); +#define SSTEP_ENABLE 0x1 /* Enable simulated HW single stepping */ +#define SSTEP_NOIRQ 0x2 /* Do not use IRQ while single stepping */ +#define SSTEP_NOTIMER 0x4 /* Do not Timers while single stepping */ + +void cpu_single_step(CPUState *cpu, int enabled); + #ifdef CONFIG_SOFTMMU extern const struct VMStateDescription vmstate_cpu_common; #else -- 1.8.1.4
[Qemu-devel] [PATCH RFC qom-cpu 15/41] target-m68k: Change gen_intermediate_code_internal() argument to M68kCPU
Also use bool type while at it. Prepares for moving singlestep_enabled field to CPUState. Signed-off-by: Andreas Färber --- target-m68k/translate.c | 9 + 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/target-m68k/translate.c b/target-m68k/translate.c index 3752094..2d73af5 100644 --- a/target-m68k/translate.c +++ b/target-m68k/translate.c @@ -2971,9 +2971,10 @@ static void disas_m68k_insn(CPUM68KState * env, DisasContext *s) /* generate intermediate code for basic block 'tb'. */ static inline void -gen_intermediate_code_internal(CPUM68KState *env, TranslationBlock *tb, - int search_pc) +gen_intermediate_code_internal(M68kCPU *cpu, TranslationBlock *tb, + bool search_pc) { +CPUM68KState *env = &cpu->env; DisasContext dc1, *dc = &dc1; uint16_t *gen_opc_end; CPUBreakpoint *bp; @@ -3096,12 +3097,12 @@ gen_intermediate_code_internal(CPUM68KState *env, TranslationBlock *tb, void gen_intermediate_code(CPUM68KState *env, TranslationBlock *tb) { -gen_intermediate_code_internal(env, tb, 0); +gen_intermediate_code_internal(m68k_env_get_cpu(env), tb, false); } void gen_intermediate_code_pc(CPUM68KState *env, TranslationBlock *tb) { -gen_intermediate_code_internal(env, tb, 1); +gen_intermediate_code_internal(m68k_env_get_cpu(env), tb, true); } void m68k_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf, -- 1.8.1.4
[Qemu-devel] [PATCH RFC qom-cpu 28/41] kvm: Change kvm_{insert, remove}_breakpoint() argument to CPUState
CPUArchState is no longer directly used since converting CPU loops to CPUState. Prepares for changing GDBState::c_cpu to CPUState. Signed-off-by: Andreas Färber --- gdbstub.c| 12 include/sysemu/kvm.h | 4 ++-- kvm-all.c| 10 -- kvm-stub.c | 4 ++-- 4 files changed, 16 insertions(+), 14 deletions(-) diff --git a/gdbstub.c b/gdbstub.c index 17da380..b77cd3e 100644 --- a/gdbstub.c +++ b/gdbstub.c @@ -1954,8 +1954,10 @@ static int gdb_breakpoint_insert(target_ulong addr, target_ulong len, int type) CPUArchState *env; int err = 0; -if (kvm_enabled()) -return kvm_insert_breakpoint(gdbserver_state->c_cpu, addr, len, type); +if (kvm_enabled()) { +return kvm_insert_breakpoint(ENV_GET_CPU(gdbserver_state->c_cpu), + addr, len, type); +} switch (type) { case GDB_BREAKPOINT_SW: @@ -1991,8 +1993,10 @@ static int gdb_breakpoint_remove(target_ulong addr, target_ulong len, int type) CPUArchState *env; int err = 0; -if (kvm_enabled()) -return kvm_remove_breakpoint(gdbserver_state->c_cpu, addr, len, type); +if (kvm_enabled()) { +return kvm_remove_breakpoint(ENV_GET_CPU(gdbserver_state->c_cpu), + addr, len, type); +} switch (type) { case GDB_BREAKPOINT_SW: diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h index 9460d5a..60a587e 100644 --- a/include/sysemu/kvm.h +++ b/include/sysemu/kvm.h @@ -159,9 +159,9 @@ void *kvm_arch_ram_alloc(ram_addr_t size); void kvm_setup_guest_memory(void *start, size_t size); void kvm_flush_coalesced_mmio_buffer(void); -int kvm_insert_breakpoint(CPUArchState *env, target_ulong addr, +int kvm_insert_breakpoint(CPUState *cpu, target_ulong addr, target_ulong len, int type); -int kvm_remove_breakpoint(CPUArchState *env, target_ulong addr, +int kvm_remove_breakpoint(CPUState *cpu, target_ulong addr, target_ulong len, int type); void kvm_remove_all_breakpoints(CPUState *cpu); int kvm_update_guest_debug(CPUArchState *env, unsigned long reinject_trap); diff --git a/kvm-all.c b/kvm-all.c index 65e93cd..9991953 100644 --- a/kvm-all.c +++ b/kvm-all.c @@ -1896,10 +1896,9 @@ int kvm_update_guest_debug(CPUArchState *env, unsigned long reinject_trap) return data.err; } -int kvm_insert_breakpoint(CPUArchState *env, target_ulong addr, +int kvm_insert_breakpoint(CPUState *cpu, target_ulong addr, target_ulong len, int type) { -CPUState *cpu = ENV_GET_CPU(env); struct kvm_sw_breakpoint *bp; int err; @@ -1942,10 +1941,9 @@ int kvm_insert_breakpoint(CPUArchState *env, target_ulong addr, return 0; } -int kvm_remove_breakpoint(CPUArchState *env, target_ulong addr, +int kvm_remove_breakpoint(CPUState *cpu, target_ulong addr, target_ulong len, int type) { -CPUState *cpu = ENV_GET_CPU(env); struct kvm_sw_breakpoint *bp; int err; @@ -2018,13 +2016,13 @@ int kvm_update_guest_debug(CPUArchState *env, unsigned long reinject_trap) return -EINVAL; } -int kvm_insert_breakpoint(CPUArchState *env, target_ulong addr, +int kvm_insert_breakpoint(CPUState *cpu, target_ulong addr, target_ulong len, int type) { return -EINVAL; } -int kvm_remove_breakpoint(CPUArchState *env, target_ulong addr, +int kvm_remove_breakpoint(CPUState *cpu, target_ulong addr, target_ulong len, int type) { return -EINVAL; diff --git a/kvm-stub.c b/kvm-stub.c index a6c2b01..b7f3569 100644 --- a/kvm-stub.c +++ b/kvm-stub.c @@ -83,13 +83,13 @@ int kvm_update_guest_debug(CPUArchState *env, unsigned long reinject_trap) return -ENOSYS; } -int kvm_insert_breakpoint(CPUArchState *env, target_ulong addr, +int kvm_insert_breakpoint(CPUState *cpu, target_ulong addr, target_ulong len, int type) { return -EINVAL; } -int kvm_remove_breakpoint(CPUArchState *env, target_ulong addr, +int kvm_remove_breakpoint(CPUState *cpu, target_ulong addr, target_ulong len, int type) { return -EINVAL; -- 1.8.1.4
[Qemu-devel] [PATCH RFC qom-cpu 13/41] target-i386: Change gen_intermediate_code_internal() argument to X86CPU
Also use bool type while at it. Prepares for moving singlestep_enabled field to CPUState. Signed-off-by: Andreas Färber --- target-i386/translate.c | 9 + 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/target-i386/translate.c b/target-i386/translate.c index 14b0298..6550c27 100644 --- a/target-i386/translate.c +++ b/target-i386/translate.c @@ -8251,10 +8251,11 @@ void optimize_flags_init(void) /* generate intermediate code in gen_opc_buf and gen_opparam_buf for basic block 'tb'. If search_pc is TRUE, also generate PC information for each intermediate instruction. */ -static inline void gen_intermediate_code_internal(CPUX86State *env, +static inline void gen_intermediate_code_internal(X86CPU *cpu, TranslationBlock *tb, - int search_pc) + bool search_pc) { +CPUX86State *env = &cpu->env; DisasContext dc1, *dc = &dc1; target_ulong pc_ptr; uint16_t *gen_opc_end; @@ -8428,12 +8429,12 @@ static inline void gen_intermediate_code_internal(CPUX86State *env, void gen_intermediate_code(CPUX86State *env, TranslationBlock *tb) { -gen_intermediate_code_internal(env, tb, 0); +gen_intermediate_code_internal(x86_env_get_cpu(env), tb, false); } void gen_intermediate_code_pc(CPUX86State *env, TranslationBlock *tb) { -gen_intermediate_code_internal(env, tb, 1); +gen_intermediate_code_internal(x86_env_get_cpu(env), tb, true); } void restore_state_to_opc(CPUX86State *env, TranslationBlock *tb, int pc_pos) -- 1.8.1.4
[Qemu-devel] [PATCH RFC qom-cpu 17/41] target-mips: Change gen_intermediate_code_internal() argument to MIPSCPU
Also use bool type while at it. Prepares for moving singlestep_enabled field to CPUState. Signed-off-by: Andreas Färber --- target-mips/translate.c | 9 + 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/target-mips/translate.c b/target-mips/translate.c index 160c0c0..8246c20 100644 --- a/target-mips/translate.c +++ b/target-mips/translate.c @@ -15540,9 +15540,10 @@ static void decode_opc (CPUMIPSState *env, DisasContext *ctx, int *is_branch) } static inline void -gen_intermediate_code_internal (CPUMIPSState *env, TranslationBlock *tb, -int search_pc) +gen_intermediate_code_internal(MIPSCPU *cpu, TranslationBlock *tb, + bool search_pc) { +CPUMIPSState *env = &cpu->env; DisasContext ctx; target_ulong pc_start; uint16_t *gen_opc_end; @@ -15698,12 +15699,12 @@ done_generating: void gen_intermediate_code (CPUMIPSState *env, struct TranslationBlock *tb) { -gen_intermediate_code_internal(env, tb, 0); +gen_intermediate_code_internal(mips_env_get_cpu(env), tb, false); } void gen_intermediate_code_pc (CPUMIPSState *env, struct TranslationBlock *tb) { -gen_intermediate_code_internal(env, tb, 1); +gen_intermediate_code_internal(mips_env_get_cpu(env), tb, true); } static void fpu_dump_state(CPUMIPSState *env, FILE *f, fprintf_function fpu_fprintf, -- 1.8.1.4
[Qemu-devel] [PATCH RFC qom-cpu 32/41] gdbstub: Change gdb_{read, write}_register() argument to CPUState
Use CPUState::env_ptr for now. Prepares for changing GDBState::g_cpu to CPUState. Signed-off-by: Andreas Färber --- gdbstub.c | 16 ++-- 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/gdbstub.c b/gdbstub.c index a8fafe2..cee9c13 100644 --- a/gdbstub.c +++ b/gdbstub.c @@ -1866,8 +1866,9 @@ static const char *get_feature_xml(const char *p, const char **newp) } #endif -static int gdb_read_register(CPUArchState *env, uint8_t *mem_buf, int reg) +static int gdb_read_register(CPUState *cpu, uint8_t *mem_buf, int reg) { +CPUArchState *env = cpu->env_ptr; GDBRegisterState *r; if (reg < NUM_CORE_REGS) @@ -1881,8 +1882,9 @@ static int gdb_read_register(CPUArchState *env, uint8_t *mem_buf, int reg) return 0; } -static int gdb_write_register(CPUArchState *env, uint8_t *mem_buf, int reg) +static int gdb_write_register(CPUState *cpu, uint8_t *mem_buf, int reg) { +CPUArchState *env = cpu->env_ptr; GDBRegisterState *r; if (reg < NUM_CORE_REGS) @@ -2210,7 +2212,8 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf) #endif len = 0; for (addr = 0; addr < num_g_regs; addr++) { -reg_size = gdb_read_register(s->g_cpu, mem_buf + len, addr); +reg_size = gdb_read_register(ENV_GET_CPU(s->g_cpu), + mem_buf + len, addr); len += reg_size; } memtohex(buf, mem_buf, len); @@ -2225,7 +2228,8 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf) len = strlen(p) / 2; hextomem((uint8_t *)registers, p, len); for (addr = 0; addr < num_g_regs && len > 0; addr++) { -reg_size = gdb_write_register(s->g_cpu, registers, addr); +reg_size = gdb_write_register(ENV_GET_CPU(s->g_cpu), registers, + addr); len -= reg_size; registers += reg_size; } @@ -2264,7 +2268,7 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf) if (!gdb_has_xml) goto unknown_command; addr = strtoull(p, (char **)&p, 16); -reg_size = gdb_read_register(s->g_cpu, mem_buf, addr); +reg_size = gdb_read_register(ENV_GET_CPU(s->g_cpu), mem_buf, addr); if (reg_size) { memtohex(buf, mem_buf, reg_size); put_packet(s, buf); @@ -2280,7 +2284,7 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf) p++; reg_size = strlen(p) / 2; hextomem(mem_buf, p, reg_size); -gdb_write_register(s->g_cpu, mem_buf, addr); +gdb_write_register(ENV_GET_CPU(s->g_cpu), mem_buf, addr); put_packet(s, "OK"); break; case 'Z': -- 1.8.1.4
[Qemu-devel] [PATCH RFC qom-cpu 20/41] target-sh4: Change gen_intermediate_code_internal() argument to SuperHCPU
Also use bool type while at it. Prepares for moving singlestep_enabled field to CPUState. Signed-off-by: Andreas Färber --- target-sh4/translate.c | 9 + 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/target-sh4/translate.c b/target-sh4/translate.c index 292c9e9..2fbe668 100644 --- a/target-sh4/translate.c +++ b/target-sh4/translate.c @@ -1846,9 +1846,10 @@ static void decode_opc(DisasContext * ctx) } static inline void -gen_intermediate_code_internal(CPUSH4State * env, TranslationBlock * tb, - int search_pc) +gen_intermediate_code_internal(SuperHCPU *cpu, TranslationBlock *tb, + bool search_pc) { +CPUSH4State *env = &cpu->env; DisasContext ctx; target_ulong pc_start; static uint16_t *gen_opc_end; @@ -1969,12 +1970,12 @@ gen_intermediate_code_internal(CPUSH4State * env, TranslationBlock * tb, void gen_intermediate_code(CPUSH4State * env, struct TranslationBlock *tb) { -gen_intermediate_code_internal(env, tb, 0); +gen_intermediate_code_internal(sh_env_get_cpu(env), tb, false); } void gen_intermediate_code_pc(CPUSH4State * env, struct TranslationBlock *tb) { -gen_intermediate_code_internal(env, tb, 1); +gen_intermediate_code_internal(sh_env_get_cpu(env), tb, true); } void restore_state_to_opc(CPUSH4State *env, TranslationBlock *tb, int pc_pos) -- 1.8.1.4
[Qemu-devel] [PATCH RFC qom-cpu 24/41] target-alpha: Change DisasContext::env to CPUState
Needed for moving singlestep_enabled to CPUState. Signed-off-by: Andreas Färber --- target-alpha/translate.c | 8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/target-alpha/translate.c b/target-alpha/translate.c index dd7f0fb..147285a 100644 --- a/target-alpha/translate.c +++ b/target-alpha/translate.c @@ -38,7 +38,7 @@ typedef struct DisasContext DisasContext; struct DisasContext { struct TranslationBlock *tb; -CPUAlphaState *env; +AlphaCPU *cpu; uint64_t pc; int mem_idx; @@ -380,7 +380,7 @@ static int use_goto_tb(DisasContext *ctx, uint64_t dest) /* Check for the dest on the same page as the start of the TB. We also want to suppress goto_tb in the case of single-steping and IO. */ return (((ctx->tb->pc ^ dest) & TARGET_PAGE_MASK) == 0 -&& !ctx->env->singlestep_enabled +&& !ctx->cpu->env.singlestep_enabled && !(ctx->tb->cflags & CF_LAST_IO)); } @@ -2245,7 +2245,7 @@ static ExitStatus translate_one(DisasContext *ctx, uint32_t insn) case 0x6C: /* IMPLVER */ if (rc != 31) -tcg_gen_movi_i64(cpu_ir[rc], ctx->env->implver); +tcg_gen_movi_i64(cpu_ir[rc], ctx->cpu->env.implver); break; default: goto invalid_opc; @@ -3394,7 +3394,7 @@ static inline void gen_intermediate_code_internal(AlphaCPU *cpu, gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE; ctx.tb = tb; -ctx.env = env; +ctx.cpu = alpha_env_get_cpu(env); ctx.pc = pc_start; ctx.mem_idx = cpu_mmu_index(env); -- 1.8.1.4
[Qemu-devel] [PATCH RFC qom-cpu 29/41] gdbstub: Change syscall callback argument to CPUState
Callback implementations were specific to arm and m68k, so can easily cast to ARMCPU and M68kCPU respectively. Prepares for changing GDBState::c_cpu to CPUState. Signed-off-by: Andreas Färber --- gdbstub.c | 2 +- include/exec/gdbstub.h | 2 +- target-arm/arm-semi.c | 8 ++-- target-m68k/m68k-semi.c | 5 - 4 files changed, 12 insertions(+), 5 deletions(-) diff --git a/gdbstub.c b/gdbstub.c index b77cd3e..63ac5fe 100644 --- a/gdbstub.c +++ b/gdbstub.c @@ -2204,7 +2204,7 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf) p++; type = *p; if (s->current_syscall_cb) { -s->current_syscall_cb(s->c_cpu, ret, err); +s->current_syscall_cb(ENV_GET_CPU(s->c_cpu), ret, err); s->current_syscall_cb = NULL; } if (type == 'C') { diff --git a/include/exec/gdbstub.h b/include/exec/gdbstub.h index ded4160..de0f4fb 100644 --- a/include/exec/gdbstub.h +++ b/include/exec/gdbstub.h @@ -11,7 +11,7 @@ #define GDB_WATCHPOINT_ACCESS4 #ifdef NEED_CPU_H -typedef void (*gdb_syscall_complete_cb)(CPUArchState *env, +typedef void (*gdb_syscall_complete_cb)(CPUState *cpu, target_ulong ret, target_ulong err); void gdb_do_syscall(gdb_syscall_complete_cb cb, const char *fmt, ...); diff --git a/target-arm/arm-semi.c b/target-arm/arm-semi.c index 5f01bca..4ecea65 100644 --- a/target-arm/arm-semi.c +++ b/target-arm/arm-semi.c @@ -122,8 +122,10 @@ static target_ulong arm_semi_syscall_len; static target_ulong syscall_err; #endif -static void arm_semi_cb(CPUARMState *env, target_ulong ret, target_ulong err) +static void arm_semi_cb(CPUState *cs, target_ulong ret, target_ulong err) { +ARMCPU *cpu = ARM_CPU(cs); +CPUARMState *env = &cpu->env; #ifdef CONFIG_USER_ONLY TaskState *ts = env->opaque; #endif @@ -152,8 +154,10 @@ static void arm_semi_cb(CPUARMState *env, target_ulong ret, target_ulong err) } } -static void arm_semi_flen_cb(CPUARMState *env, target_ulong ret, target_ulong err) +static void arm_semi_flen_cb(CPUState *cs, target_ulong ret, target_ulong err) { +ARMCPU *cpu = ARM_CPU(cs); +CPUARMState *env = &cpu->env; /* The size is always stored in big-endian order, extract the value. We assume the size always fit in 32 bits. */ uint32_t size; diff --git a/target-m68k/m68k-semi.c b/target-m68k/m68k-semi.c index 239fadb..94c4983 100644 --- a/target-m68k/m68k-semi.c +++ b/target-m68k/m68k-semi.c @@ -161,8 +161,11 @@ static void m68k_semi_return_u64(CPUM68KState *env, uint64_t ret, uint32_t err) static int m68k_semi_is_fseek; -static void m68k_semi_cb(CPUM68KState *env, target_ulong ret, target_ulong err) +static void m68k_semi_cb(CPUState *cs, target_ulong ret, target_ulong err) { +M68kCPU *cpu = M68K_CPU(cs); +CPUM68KState *env = &cpu->env; + if (m68k_semi_is_fseek) { /* FIXME: We've already lost the high bits of the fseek return value. */ -- 1.8.1.4
[Qemu-devel] [PATCH RFC qom-cpu 22/41] target-unicore32: Change gen_intermediate_code_internal() signature
Use UniCore32CPU and bool. Prepares for moving singlestep_enabled field to CPUState. Signed-off-by: Andreas Färber --- target-unicore32/translate.c | 9 + 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/target-unicore32/translate.c b/target-unicore32/translate.c index e1fe4e6..d85185d 100644 --- a/target-unicore32/translate.c +++ b/target-unicore32/translate.c @@ -1876,9 +1876,10 @@ static void disas_uc32_insn(CPUUniCore32State *env, DisasContext *s) /* generate intermediate code in gen_opc_buf and gen_opparam_buf for basic block 'tb'. If search_pc is TRUE, also generate PC information for each intermediate instruction. */ -static inline void gen_intermediate_code_internal(CPUUniCore32State *env, -TranslationBlock *tb, int search_pc) +static inline void gen_intermediate_code_internal(UniCore32CPU *cpu, +TranslationBlock *tb, bool search_pc) { +CPUUniCore32State *env = &cpu->env; DisasContext dc1, *dc = &dc1; CPUBreakpoint *bp; uint16_t *gen_opc_end; @@ -2065,12 +2066,12 @@ done_generating: void gen_intermediate_code(CPUUniCore32State *env, TranslationBlock *tb) { -gen_intermediate_code_internal(env, tb, 0); +gen_intermediate_code_internal(uc32_env_get_cpu(env), tb, false); } void gen_intermediate_code_pc(CPUUniCore32State *env, TranslationBlock *tb) { -gen_intermediate_code_internal(env, tb, 1); +gen_intermediate_code_internal(uc32_env_get_cpu(env), tb, true); } static const char *cpu_mode_names[16] = { -- 1.8.1.4
[Qemu-devel] [PATCH RFC qom-cpu 38/41] gdbstub: Change gdb_register_coprocessor() argument to CPUState
Signed-off-by: Andreas Färber --- gdbstub.c | 7 +++ include/exec/gdbstub.h | 2 +- target-arm/helper.c | 7 --- target-m68k/helper.c| 3 ++- target-ppc/translate_init.c | 15 --- 5 files changed, 18 insertions(+), 16 deletions(-) diff --git a/gdbstub.c b/gdbstub.c index d862cca..4ebe9e0 100644 --- a/gdbstub.c +++ b/gdbstub.c @@ -1906,11 +1906,10 @@ static int gdb_write_register(CPUState *cpu, uint8_t *mem_buf, int reg) gdb reading a CPU register, and set_reg is gdb modifying a CPU register. */ -void gdb_register_coprocessor(CPUArchState * env, - gdb_reg_cb get_reg, gdb_reg_cb set_reg, - int num_regs, const char *xml, int g_pos) +void gdb_register_coprocessor(CPUState *cpu, + gdb_reg_cb get_reg, gdb_reg_cb set_reg, + int num_regs, const char *xml, int g_pos) { -CPUState *cpu = ENV_GET_CPU(env); GDBRegisterState *s; GDBRegisterState **p; static int last_reg = NUM_CORE_REGS; diff --git a/include/exec/gdbstub.h b/include/exec/gdbstub.h index 0f1ad9a..1bd00ae 100644 --- a/include/exec/gdbstub.h +++ b/include/exec/gdbstub.h @@ -26,7 +26,7 @@ void gdbserver_fork(CPUArchState *); #endif /* Get or set a register. Returns the size of the register. */ typedef int (*gdb_reg_cb)(CPUArchState *env, uint8_t *buf, int reg); -void gdb_register_coprocessor(CPUArchState *env, +void gdb_register_coprocessor(CPUState *cpu, gdb_reg_cb get_reg, gdb_reg_cb set_reg, int num_regs, const char *xml, int g_pos); diff --git a/target-arm/helper.c b/target-arm/helper.c index da4d4a6..5045934 100644 --- a/target-arm/helper.c +++ b/target-arm/helper.c @@ -1502,16 +1502,17 @@ ARMCPU *cpu_arm_init(const char *cpu_model) void arm_cpu_register_gdb_regs_for_features(ARMCPU *cpu) { +CPUState *cs = CPU(cpu); CPUARMState *env = &cpu->env; if (arm_feature(env, ARM_FEATURE_NEON)) { -gdb_register_coprocessor(env, vfp_gdb_get_reg, vfp_gdb_set_reg, +gdb_register_coprocessor(cs, vfp_gdb_get_reg, vfp_gdb_set_reg, 51, "arm-neon.xml", 0); } else if (arm_feature(env, ARM_FEATURE_VFP3)) { -gdb_register_coprocessor(env, vfp_gdb_get_reg, vfp_gdb_set_reg, +gdb_register_coprocessor(cs, vfp_gdb_get_reg, vfp_gdb_set_reg, 35, "arm-vfp3.xml", 0); } else if (arm_feature(env, ARM_FEATURE_VFP)) { -gdb_register_coprocessor(env, vfp_gdb_get_reg, vfp_gdb_set_reg, +gdb_register_coprocessor(cs, vfp_gdb_get_reg, vfp_gdb_set_reg, 19, "arm-vfp.xml", 0); } } diff --git a/target-m68k/helper.c b/target-m68k/helper.c index 0a94ca7..871e5ef 100644 --- a/target-m68k/helper.c +++ b/target-m68k/helper.c @@ -121,10 +121,11 @@ M68kCPU *cpu_m68k_init(const char *cpu_model) void m68k_cpu_init_gdb(M68kCPU *cpu) { +CPUState *cs = CPU(cpu); CPUM68KState *env = &cpu->env; if (m68k_feature(env, M68K_FEATURE_CF_FPU)) { -gdb_register_coprocessor(env, fpu_gdb_get_reg, fpu_gdb_set_reg, +gdb_register_coprocessor(cs, fpu_gdb_get_reg, fpu_gdb_set_reg, 11, "cf-fp.xml", 18); } /* TODO: Add [E]MAC registers. */ diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c index 815ce0c..24821f9 100644 --- a/target-ppc/translate_init.c +++ b/target-ppc/translate_init.c @@ -7695,8 +7695,8 @@ static int ppc_fixup_cpu(PowerPCCPU *cpu) static void ppc_cpu_realizefn(DeviceState *dev, Error **errp) { +CPUState *cs = CPU(dev); PowerPCCPU *cpu = POWERPC_CPU(dev); -CPUPPCState *env = &cpu->env; PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu); Error *local_err = NULL; #if !defined(CONFIG_USER_ONLY) @@ -7740,15 +7740,15 @@ static void ppc_cpu_realizefn(DeviceState *dev, Error **errp) init_ppc_proc(cpu); if (pcc->insns_flags & PPC_FLOAT) { -gdb_register_coprocessor(env, gdb_get_float_reg, gdb_set_float_reg, +gdb_register_coprocessor(cs, gdb_get_float_reg, gdb_set_float_reg, 33, "power-fpu.xml", 0); } if (pcc->insns_flags & PPC_ALTIVEC) { -gdb_register_coprocessor(env, gdb_get_avr_reg, gdb_set_avr_reg, +gdb_register_coprocessor(cs, gdb_get_avr_reg, gdb_set_avr_reg, 34, "power-altivec.xml", 0); } if (pcc->insns_flags & PPC_SPE) { -gdb_register_coprocessor(env, gdb_get_spe_reg, gdb_set_spe_reg, +gdb_register_coprocessor(cs, gdb_get_spe_reg, gdb_set_spe_reg, 34, "power-spe.xml", 0); } @@ -7756,6 +7756,7 @@ static void ppc_cpu_realizefn(DeviceState *dev, Error **errp) #if defined(PPC_DUMP_CPU) { +CPUPPCState *env = &cpu->env; const cha
[Qemu-devel] [PATCH RFC qom-cpu 25/41] cpu: Move singlestep_enabled field from CPU_COMMON to CPUState
Prepares for changing cpu_single_step() argument to CPUState. Signed-off-by: Andreas Färber --- cpu-exec.c| 2 +- cpus.c| 2 +- exec.c| 10 ++ include/exec/cpu-defs.h | 1 - include/qom/cpu.h | 1 + kvm-all.c | 2 +- target-alpha/translate.c | 12 target-arm/translate.c| 7 --- target-cris/translate.c | 7 --- target-i386/kvm.c | 6 -- target-i386/translate.c | 5 +++-- target-lm32/translate.c | 7 --- target-m68k/translate.c | 7 --- target-microblaze/translate.c | 8 +--- target-mips/translate.c | 11 +++ target-moxie/translate.c | 5 +++-- target-openrisc/translate.c | 7 --- target-ppc/translate.c| 8 +--- target-s390x/translate.c | 5 +++-- target-sh4/translate.c| 8 +--- target-sparc/translate.c | 3 ++- target-unicore32/translate.c | 7 --- target-xtensa/translate.c | 7 --- 23 files changed, 83 insertions(+), 55 deletions(-) diff --git a/cpu-exec.c b/cpu-exec.c index 88f4e75..d52e581 100644 --- a/cpu-exec.c +++ b/cpu-exec.c @@ -297,7 +297,7 @@ int cpu_exec(CPUArchState *env) for(;;) { interrupt_request = cpu->interrupt_request; if (unlikely(interrupt_request)) { -if (unlikely(env->singlestep_enabled & SSTEP_NOIRQ)) { +if (unlikely(cpu->singlestep_enabled & SSTEP_NOIRQ)) { /* Mask out external interrupts for this step. */ interrupt_request &= ~CPU_INTERRUPT_SSTEP_MASK; } diff --git a/cpus.c b/cpus.c index f97983d..8b99deb 100644 --- a/cpus.c +++ b/cpus.c @@ -1148,7 +1148,7 @@ static void tcg_exec_all(void) CPUArchState *env = cpu->env_ptr; qemu_clock_enable(vm_clock, - (env->singlestep_enabled & SSTEP_NOTIMER) == 0); + (cpu->singlestep_enabled & SSTEP_NOTIMER) == 0); if (cpu_can_run(cpu)) { r = tcg_cpu_exec(env); diff --git a/exec.c b/exec.c index 4e20143..f2d848c 100644 --- a/exec.c +++ b/exec.c @@ -584,11 +584,13 @@ void cpu_breakpoint_remove_all(CPUArchState *env, int mask) void cpu_single_step(CPUArchState *env, int enabled) { #if defined(TARGET_HAS_ICE) -if (env->singlestep_enabled != enabled) { -env->singlestep_enabled = enabled; -if (kvm_enabled()) +CPUState *cpu = ENV_GET_CPU(env); + +if (cpu->singlestep_enabled != enabled) { +cpu->singlestep_enabled = enabled; +if (kvm_enabled()) { kvm_update_guest_debug(env, 0); -else { +} else { /* must flush all the translated code to avoid inconsistencies */ /* XXX: only flush what is necessary */ tb_flush(env); diff --git a/include/exec/cpu-defs.h b/include/exec/cpu-defs.h index 39094b3..12b1ca7 100644 --- a/include/exec/cpu-defs.h +++ b/include/exec/cpu-defs.h @@ -170,7 +170,6 @@ typedef struct CPUWatchpoint { /* from this point: preserved by CPU reset */ \ /* ice debug support */ \ QTAILQ_HEAD(breakpoints_head, CPUBreakpoint) breakpoints;\ -int singlestep_enabled; \ \ QTAILQ_HEAD(watchpoints_head, CPUWatchpoint) watchpoints;\ CPUWatchpoint *watchpoint_hit; \ diff --git a/include/qom/cpu.h b/include/qom/cpu.h index d8b77af..a02b142 100644 --- a/include/qom/cpu.h +++ b/include/qom/cpu.h @@ -148,6 +148,7 @@ struct CPUState { volatile sig_atomic_t exit_request; volatile sig_atomic_t tcg_exit_req; uint32_t interrupt_request; +int singlestep_enabled; void *env_ptr; /* CPUArchState */ struct TranslationBlock *current_tb; diff --git a/kvm-all.c b/kvm-all.c index 00ef85d..65e93cd 100644 --- a/kvm-all.c +++ b/kvm-all.c @@ -1886,7 +1886,7 @@ int kvm_update_guest_debug(CPUArchState *env, unsigned long reinject_trap) data.dbg.control = reinject_trap; -if (env->singlestep_enabled) { +if (cpu->singlestep_enabled) { data.dbg.control |= KVM_GUESTDBG_ENABLE | KVM_GUESTDBG_SINGLESTEP; } kvm_arch_update_guest_debug(cpu, &data.dbg); diff --git a/target-alpha/translate.c b/target-alpha/translate.c index 147285a..0229a66 100644 --- a/target-alpha/translate.c +++ b/target-alpha/translate.c @@ -377,10 +377,12 @@ static ExitStatus gen_store_conditional(DisasContext *ctx, int ra, int rb, static int use_goto_tb(DisasContext *ctx, uint64_t dest) { +CPUState *cs = CPU(ctx->cpu); + /* Check for the dest on the same page as the start of the TB. We also want to suppress goto
[Qemu-devel] [PATCH RFC qom-cpu 26/41] gdbstub: Update gdb_handlesig() and gdb_signalled() Coding Style
In particular reindent to 4 instead of 2 spaces. Prepares for changing cpu_single_step() argument in gdb_handlesig(). Signed-off-by: Andreas Färber --- gdbstub.c | 94 +++ 1 file changed, 47 insertions(+), 47 deletions(-) diff --git a/gdbstub.c b/gdbstub.c index 07838eb..ede5cb1 100644 --- a/gdbstub.c +++ b/gdbstub.c @@ -2759,66 +2759,66 @@ gdb_queuesig (void) } int -gdb_handlesig (CPUArchState *env, int sig) +gdb_handlesig(CPUArchState *env, int sig) { - GDBState *s; - char buf[256]; - int n; +GDBState *s; +char buf[256]; +int n; - s = gdbserver_state; - if (gdbserver_fd < 0 || s->fd < 0) -return sig; +s = gdbserver_state; +if (gdbserver_fd < 0 || s->fd < 0) { +return sig; +} - /* disable single step if it was enabled */ - cpu_single_step(env, 0); - tb_flush(env); +/* disable single step if it was enabled */ +cpu_single_step(env, 0); +tb_flush(env); - if (sig != 0) -{ - snprintf(buf, sizeof(buf), "S%02x", target_signal_to_gdb (sig)); - put_packet(s, buf); -} - /* put_packet() might have detected that the peer terminated the - connection. */ - if (s->fd < 0) - return sig; - - sig = 0; - s->state = RS_IDLE; - s->running_state = 0; - while (s->running_state == 0) { - n = read (s->fd, buf, 256); - if (n > 0) -{ - int i; +if (sig != 0) { +snprintf(buf, sizeof(buf), "S%02x", target_signal_to_gdb(sig)); +put_packet(s, buf); +} +/* put_packet() might have detected that the peer terminated the + connection. */ +if (s->fd < 0) { +return sig; +} - for (i = 0; i < n; i++) -gdb_read_byte (s, buf[i]); -} - else if (n == 0 || errno != EAGAIN) -{ - /* XXX: Connection closed. Should probably wait for another - connection before continuing. */ - return sig; +sig = 0; +s->state = RS_IDLE; +s->running_state = 0; +while (s->running_state == 0) { +n = read(s->fd, buf, 256); +if (n > 0) { +int i; + +for (i = 0; i < n; i++) { +gdb_read_byte(s, buf[i]); +} +} else if (n == 0 || errno != EAGAIN) { +/* XXX: Connection closed. Should probably wait for another + connection before continuing. */ +return sig; } - } - sig = s->signal; - s->signal = 0; - return sig; +} +sig = s->signal; +s->signal = 0; +return sig; } /* Tell the remote gdb that the process has exited due to SIG. */ void gdb_signalled(CPUArchState *env, int sig) { - GDBState *s; - char buf[4]; +GDBState *s; +char buf[4]; - s = gdbserver_state; - if (gdbserver_fd < 0 || s->fd < 0) -return; +s = gdbserver_state; +if (gdbserver_fd < 0 || s->fd < 0) { +return; +} - snprintf(buf, sizeof(buf), "X%02x", target_signal_to_gdb (sig)); - put_packet(s, buf); +snprintf(buf, sizeof(buf), "X%02x", target_signal_to_gdb(sig)); +put_packet(s, buf); } static void gdb_accept(void) -- 1.8.1.4
[Qemu-devel] [PATCH RFC qom-cpu 30/41] gdbstub: Change gdb_handlesig() argument to CPUState
Prepares for changing GDBState::c_cpu to CPUState. Signed-off-by: Andreas Färber --- bsd-user/main.c| 10 ++ gdbstub.c | 6 +++--- include/exec/gdbstub.h | 2 +- linux-user/main.c | 35 +++ linux-user/signal.c| 3 ++- 5 files changed, 31 insertions(+), 25 deletions(-) diff --git a/bsd-user/main.c b/bsd-user/main.c index 1e92552..f9246aa 100644 --- a/bsd-user/main.c +++ b/bsd-user/main.c @@ -643,7 +643,7 @@ void cpu_loop(CPUSPARCState *env) { int sig; -sig = gdb_handlesig (env, TARGET_SIGTRAP); +sig = gdb_handlesig(cs, TARGET_SIGTRAP); #if 0 if (sig) { @@ -738,6 +738,7 @@ int main(int argc, char **argv) struct image_info info1, *info = &info1; TaskState ts1, *ts = &ts1; CPUArchState *env; +CPUState *cpu; int optind; const char *r; int gdbstub_port = 0; @@ -912,10 +913,11 @@ int main(int argc, char **argv) fprintf(stderr, "Unable to find CPU definition\n"); exit(1); } +cpu = ENV_GET_CPU(env); #if defined(TARGET_SPARC) || defined(TARGET_PPC) -cpu_reset(ENV_GET_CPU(env)); +cpu_reset(cpu); #endif -thread_cpu = ENV_GET_CPU(env); +thread_cpu = cpu; if (getenv("QEMU_STRACE")) { do_strace = 1; @@ -1134,7 +1136,7 @@ int main(int argc, char **argv) if (gdbstub_port) { gdbserver_start (gdbstub_port); -gdb_handlesig(env, 0); +gdb_handlesig(cpu, 0); } cpu_loop(env); /* never exits */ diff --git a/gdbstub.c b/gdbstub.c index 63ac5fe..81a8941 100644 --- a/gdbstub.c +++ b/gdbstub.c @@ -2634,7 +2634,7 @@ void gdb_do_syscall(gdb_syscall_complete_cb cb, const char *fmt, ...) va_end(va); #ifdef CONFIG_USER_ONLY put_packet(s, s->syscall_buf); -gdb_handlesig(s->c_cpu, 0); +gdb_handlesig(ENV_GET_CPU(s->c_cpu), 0); #else /* In this case wait to send the syscall packet until notification that the CPU has stopped. This must be done because if the packet is sent @@ -2763,9 +2763,9 @@ gdb_queuesig (void) } int -gdb_handlesig(CPUArchState *env, int sig) +gdb_handlesig(CPUState *cpu, int sig) { -CPUState *cpu = ENV_GET_CPU(env); +CPUArchState *env = cpu->env_ptr; GDBState *s; char buf[256]; int n; diff --git a/include/exec/gdbstub.h b/include/exec/gdbstub.h index de0f4fb..0f1ad9a 100644 --- a/include/exec/gdbstub.h +++ b/include/exec/gdbstub.h @@ -20,7 +20,7 @@ void gdb_set_stop_cpu(CPUState *cpu); void gdb_exit(CPUArchState *, int); #ifdef CONFIG_USER_ONLY int gdb_queuesig (void); -int gdb_handlesig (CPUArchState *, int); +int gdb_handlesig(CPUState *, int); void gdb_signalled(CPUArchState *, int); void gdbserver_fork(CPUArchState *); #endif diff --git a/linux-user/main.c b/linux-user/main.c index 7f15d3d..27f8232 100644 --- a/linux-user/main.c +++ b/linux-user/main.c @@ -312,6 +312,7 @@ static void set_idt(int n, unsigned int dpl) void cpu_loop(CPUX86State *env) { +CPUState *cs = CPU(x86_env_get_cpu(env)); int trapnr; abi_ulong pc; target_siginfo_t info; @@ -443,7 +444,7 @@ void cpu_loop(CPUX86State *env) { int sig; -sig = gdb_handlesig (env, TARGET_SIGTRAP); +sig = gdb_handlesig(cs, TARGET_SIGTRAP); if (sig) { info.si_signo = sig; @@ -875,7 +876,7 @@ void cpu_loop(CPUARMState *env) { int sig; -sig = gdb_handlesig (env, TARGET_SIGTRAP); +sig = gdb_handlesig(cs, TARGET_SIGTRAP); if (sig) { info.si_signo = sig; @@ -966,7 +967,7 @@ void cpu_loop(CPUUniCore32State *env) { int sig; -sig = gdb_handlesig(env, TARGET_SIGTRAP); +sig = gdb_handlesig(cs, TARGET_SIGTRAP); if (sig) { info.si_signo = sig; info.si_errno = 0; @@ -1233,7 +1234,7 @@ void cpu_loop (CPUSPARCState *env) { int sig; -sig = gdb_handlesig (env, TARGET_SIGTRAP); +sig = gdb_handlesig(cs, TARGET_SIGTRAP); if (sig) { info.si_signo = sig; @@ -1764,7 +1765,7 @@ void cpu_loop(CPUPPCState *env) { int sig; -sig = gdb_handlesig(env, TARGET_SIGTRAP); +sig = gdb_handlesig(cs, TARGET_SIGTRAP); if (sig) { info.si_signo = sig; info.si_errno = 0; @@ -2315,7 +2316,7 @@ done_syscall: { int sig; -sig = gdb_handlesig (env, TARGET_SIGTRAP); +sig = gdb_handlesig(cs, TARGET_SIGTRAP); if (sig) {
[Qemu-devel] [PATCH RFC qom-cpu 35/41] cpu: Introduce CPUClass::memory_rw_debug() for target_memory_rw_debug()
Make inline target_memory_rw_debug() always available and change its argument to CPUState. Let it check if CPUClass::memory_rw_debug provides a specialized callback and fall back to cpu_memory_rw_debug() otherwise. The only overriding implementation is for 32-bit sparc. This prepares for changing GDBState::g_cpu to CPUState. Signed-off-by: Andreas Färber --- gdbstub.c | 21 - include/qom/cpu.h | 2 ++ target-sparc/cpu.c| 3 +++ target-sparc/cpu.h| 5 ++--- target-sparc/mmu_helper.c | 8 +--- 5 files changed, 24 insertions(+), 15 deletions(-) diff --git a/gdbstub.c b/gdbstub.c index 43ecc0d..fa44550 100644 --- a/gdbstub.c +++ b/gdbstub.c @@ -42,15 +42,16 @@ #include "sysemu/kvm.h" #include "qemu/bitops.h" -#ifndef TARGET_CPU_MEMORY_RW_DEBUG -static inline int target_memory_rw_debug(CPUArchState *env, target_ulong addr, - uint8_t *buf, int len, int is_write) +static inline int target_memory_rw_debug(CPUState *cpu, target_ulong addr, + uint8_t *buf, int len, bool is_write) { -return cpu_memory_rw_debug(ENV_GET_CPU(env), addr, buf, len, is_write); +CPUClass *cc = CPU_GET_CLASS(cpu); + +if (cc->memory_rw_debug) { +return cc->memory_rw_debug(cpu, addr, buf, len, is_write); +} +return cpu_memory_rw_debug(cpu, addr, buf, len, is_write); } -#else -/* target_memory_rw_debug() defined in cpu.h */ -#endif enum { GDB_SIGNAL_0 = 0, @@ -2240,7 +2241,8 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf) if (*p == ',') p++; len = strtoull(p, NULL, 16); -if (target_memory_rw_debug(s->g_cpu, addr, mem_buf, len, 0) != 0) { +if (target_memory_rw_debug(ENV_GET_CPU(s->g_cpu), addr, mem_buf, len, + false) != 0) { put_packet (s, "E14"); } else { memtohex(buf, mem_buf, len); @@ -2255,7 +2257,8 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf) if (*p == ':') p++; hextomem(mem_buf, p, len); -if (target_memory_rw_debug(s->g_cpu, addr, mem_buf, len, 1) != 0) { +if (target_memory_rw_debug(ENV_GET_CPU(s->g_cpu), addr, mem_buf, len, + true) != 0) { put_packet(s, "E14"); } else { put_packet(s, "OK"); diff --git a/include/qom/cpu.h b/include/qom/cpu.h index 9717650..820dca4 100644 --- a/include/qom/cpu.h +++ b/include/qom/cpu.h @@ -77,6 +77,8 @@ typedef struct CPUClass { int reset_dump_flags; void (*do_interrupt)(CPUState *cpu); CPUUnassignedAccess do_unassigned_access; +int (*memory_rw_debug)(CPUState *cpu, uint64_t addr, + uint8_t *buf, int len, bool is_write); void (*dump_state)(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf, int flags); void (*dump_statistics)(CPUState *cpu, FILE *f, diff --git a/target-sparc/cpu.c b/target-sparc/cpu.c index c3e2d3d..bd9d216 100644 --- a/target-sparc/cpu.c +++ b/target-sparc/cpu.c @@ -782,6 +782,9 @@ static void sparc_cpu_class_init(ObjectClass *oc, void *data) cc->do_interrupt = sparc_cpu_do_interrupt; cc->dump_state = sparc_cpu_dump_state; +#if !defined(TARGET_SPARC64) && !defined(CONFIG_USER_ONLY) +cc->memory_rw_debug = sparc_cpu_memory_rw_debug; +#endif cc->set_pc = sparc_cpu_set_pc; cc->synchronize_from_tb = sparc_cpu_synchronize_from_tb; #ifndef CONFIG_USER_ONLY diff --git a/target-sparc/cpu.h b/target-sparc/cpu.h index 0f35a22..b043772 100644 --- a/target-sparc/cpu.h +++ b/target-sparc/cpu.h @@ -526,9 +526,8 @@ target_ulong mmu_probe(CPUSPARCState *env, target_ulong address, int mmulev); void dump_mmu(FILE *f, fprintf_function cpu_fprintf, CPUSPARCState *env); #if !defined(TARGET_SPARC64) && !defined(CONFIG_USER_ONLY) -int target_memory_rw_debug(CPUSPARCState *env, target_ulong addr, - uint8_t *buf, int len, int is_write); -#define TARGET_CPU_MEMORY_RW_DEBUG +int sparc_cpu_memory_rw_debug(CPUState *cpu, uint64_t addr, + uint8_t *buf, int len, bool is_write); #endif diff --git a/target-sparc/mmu_helper.c b/target-sparc/mmu_helper.c index bf89236..66ed1ba 100644 --- a/target-sparc/mmu_helper.c +++ b/target-sparc/mmu_helper.c @@ -353,10 +353,12 @@ void dump_mmu(FILE *f, fprintf_function cpu_fprintf, CPUSPARCState *env) * reads (and only reads) in stack frames as if windows were flushed. We assume * that the sparc ABI is followed. */ -int target_memory_rw_debug(CPUSPARCState *env, target_ulong addr, - uint8_t *buf, int len, int is_write) +int sparc_cpu_memory_rw_debug(CPUState *cs, uint64_t address, + uint8_t *buf, int len, bool is_write) { -CPUState *cs = CPU(sparc_env_get_cpu(env)); +SPARCCPU *cpu = S
[Qemu-devel] [PATCH RFC qom-cpu 37/41] cpu: Move gdb_regs field from CPU_COMMON to CPUState
Prepares for changing gdb_register_coprocessor() argument to CPUState. Signed-off-by: Andreas Färber --- gdbstub.c | 11 ++- include/exec/cpu-defs.h | 2 -- include/qom/cpu.h | 1 + 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/gdbstub.c b/gdbstub.c index 7be2342..d862cca 100644 --- a/gdbstub.c +++ b/gdbstub.c @@ -1840,7 +1840,7 @@ static const char *get_feature_xml(const char *p, const char **newp) /* Generate the XML description for this CPU. */ if (!target_xml[0]) { GDBRegisterState *r; -CPUArchState *env = first_cpu->env_ptr; +CPUState *cpu = first_cpu; snprintf(target_xml, sizeof(target_xml), "" @@ -1849,7 +1849,7 @@ static const char *get_feature_xml(const char *p, const char **newp) "", GDB_CORE_XML); -for (r = env->gdb_regs; r; r = r->next) { +for (r = cpu->gdb_regs; r; r = r->next) { pstrcat(target_xml, sizeof(target_xml), "xml); pstrcat(target_xml, sizeof(target_xml), "\"/>"); @@ -1875,7 +1875,7 @@ static int gdb_read_register(CPUState *cpu, uint8_t *mem_buf, int reg) if (reg < NUM_CORE_REGS) return cpu_gdb_read_register(env, mem_buf, reg); -for (r = env->gdb_regs; r; r = r->next) { +for (r = cpu->gdb_regs; r; r = r->next) { if (r->base_reg <= reg && reg < r->base_reg + r->num_regs) { return r->get_reg(env, mem_buf, reg - r->base_reg); } @@ -1891,7 +1891,7 @@ static int gdb_write_register(CPUState *cpu, uint8_t *mem_buf, int reg) if (reg < NUM_CORE_REGS) return cpu_gdb_write_register(env, mem_buf, reg); -for (r = env->gdb_regs; r; r = r->next) { +for (r = cpu->gdb_regs; r; r = r->next) { if (r->base_reg <= reg && reg < r->base_reg + r->num_regs) { return r->set_reg(env, mem_buf, reg - r->base_reg); } @@ -1910,11 +1910,12 @@ void gdb_register_coprocessor(CPUArchState * env, gdb_reg_cb get_reg, gdb_reg_cb set_reg, int num_regs, const char *xml, int g_pos) { +CPUState *cpu = ENV_GET_CPU(env); GDBRegisterState *s; GDBRegisterState **p; static int last_reg = NUM_CORE_REGS; -p = &env->gdb_regs; +p = &cpu->gdb_regs; while (*p) { /* Check for duplicates. */ if (strcmp((*p)->xml, xml) == 0) diff --git a/include/exec/cpu-defs.h b/include/exec/cpu-defs.h index 12b1ca7..b5b93db 100644 --- a/include/exec/cpu-defs.h +++ b/include/exec/cpu-defs.h @@ -174,8 +174,6 @@ typedef struct CPUWatchpoint { QTAILQ_HEAD(watchpoints_head, CPUWatchpoint) watchpoints;\ CPUWatchpoint *watchpoint_hit; \ \ -struct GDBRegisterState *gdb_regs; \ -\ /* Core interrupt code */ \ sigjmp_buf jmp_env; \ int exception_index;\ diff --git a/include/qom/cpu.h b/include/qom/cpu.h index 820dca4..78fbdac 100644 --- a/include/qom/cpu.h +++ b/include/qom/cpu.h @@ -156,6 +156,7 @@ struct CPUState { void *env_ptr; /* CPUArchState */ struct TranslationBlock *current_tb; +struct GDBRegisterState *gdb_regs; CPUState *next_cpu; int kvm_fd; -- 1.8.1.4
[Qemu-devel] [PATCH RFC qom-cpu 10/41] target-alpha: Change gen_intermediate_code_internal() argument to AlphaCPU
Also use bool argument while at it. Prepares for replacing DisasContext::env with CPUState and for moving singlestep_enabled field to CPUState. Signed-off-by: Andreas Färber --- target-alpha/translate.c | 9 + 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/target-alpha/translate.c b/target-alpha/translate.c index 4db16db..dd7f0fb 100644 --- a/target-alpha/translate.c +++ b/target-alpha/translate.c @@ -3375,10 +3375,11 @@ static ExitStatus translate_one(DisasContext *ctx, uint32_t insn) return ret; } -static inline void gen_intermediate_code_internal(CPUAlphaState *env, +static inline void gen_intermediate_code_internal(AlphaCPU *cpu, TranslationBlock *tb, - int search_pc) + bool search_pc) { +CPUAlphaState *env = &cpu->env; DisasContext ctx, *ctxp = &ctx; target_ulong pc_start; uint32_t insn; @@ -3502,12 +3503,12 @@ static inline void gen_intermediate_code_internal(CPUAlphaState *env, void gen_intermediate_code (CPUAlphaState *env, struct TranslationBlock *tb) { -gen_intermediate_code_internal(env, tb, 0); +gen_intermediate_code_internal(alpha_env_get_cpu(env), tb, false); } void gen_intermediate_code_pc (CPUAlphaState *env, struct TranslationBlock *tb) { -gen_intermediate_code_internal(env, tb, 1); +gen_intermediate_code_internal(alpha_env_get_cpu(env), tb, true); } void restore_state_to_opc(CPUAlphaState *env, TranslationBlock *tb, int pc_pos) -- 1.8.1.4
[Qemu-devel] [PATCH RFC qom-cpu 34/41] exec: Change cpu_memory_rw_debug() argument to CPUState
Propagate X86CPU in kvmvapic for simplicity. Signed-off-by: Andreas Färber --- cpus.c | 4 +-- disas.c | 4 +-- exec.c | 6 ++-- gdbstub.c | 2 +- hw/i386/kvmvapic.c | 72 +++-- include/exec/cpu-all.h | 3 +- include/exec/softmmu-semi.h | 18 +++- monitor.c | 2 +- target-arm/arm-semi.c | 2 +- target-i386/helper.c| 8 +++-- target-i386/kvm.c | 14 - target-sparc/mmu_helper.c | 5 ++-- target-xtensa/xtensa-semi.c | 10 +++ 13 files changed, 77 insertions(+), 73 deletions(-) diff --git a/cpus.c b/cpus.c index 8b99deb..9dbd5ff 100644 --- a/cpus.c +++ b/cpus.c @@ -1247,7 +1247,6 @@ void qmp_memsave(int64_t addr, int64_t size, const char *filename, { FILE *f; uint32_t l; -CPUArchState *env; CPUState *cpu; uint8_t buf[1024]; @@ -1261,7 +1260,6 @@ void qmp_memsave(int64_t addr, int64_t size, const char *filename, "a CPU number"); return; } -env = cpu->env_ptr; f = fopen(filename, "wb"); if (!f) { @@ -1273,7 +1271,7 @@ void qmp_memsave(int64_t addr, int64_t size, const char *filename, l = sizeof(buf); if (l > size) l = size; -cpu_memory_rw_debug(env, addr, buf, l, 0); +cpu_memory_rw_debug(cpu, addr, buf, l, 0); if (fwrite(buf, 1, l, f) != l) { error_set(errp, QERR_IO_ERROR); goto exit; diff --git a/disas.c b/disas.c index e51127e..71007fb 100644 --- a/disas.c +++ b/disas.c @@ -39,7 +39,7 @@ target_read_memory (bfd_vma memaddr, { CPUDebug *s = container_of(info, CPUDebug, info); -cpu_memory_rw_debug(s->env, memaddr, myaddr, length, 0); +cpu_memory_rw_debug(ENV_GET_CPU(s->env), memaddr, myaddr, length, 0); return 0; } @@ -392,7 +392,7 @@ monitor_read_memory (bfd_vma memaddr, bfd_byte *myaddr, int length, if (monitor_disas_is_physical) { cpu_physical_memory_read(memaddr, myaddr, length); } else { -cpu_memory_rw_debug(s->env, memaddr,myaddr, length, 0); +cpu_memory_rw_debug(ENV_GET_CPU(s->env), memaddr, myaddr, length, 0); } return 0; } diff --git a/exec.c b/exec.c index 359dc64..f4906cf 100644 --- a/exec.c +++ b/exec.c @@ -1847,7 +1847,7 @@ MemoryRegion *get_system_io(void) /* physical memory access (slow version, mainly for debug) */ #if defined(CONFIG_USER_ONLY) -int cpu_memory_rw_debug(CPUArchState *env, target_ulong addr, +int cpu_memory_rw_debug(CPUState *cpu, target_ulong addr, uint8_t *buf, int len, int is_write) { int l, flags; @@ -2565,7 +2565,7 @@ void stq_be_phys(hwaddr addr, uint64_t val) } /* virtual memory access for debug (includes writing to ROM) */ -int cpu_memory_rw_debug(CPUArchState *env, target_ulong addr, +int cpu_memory_rw_debug(CPUState *cpu, target_ulong addr, uint8_t *buf, int len, int is_write) { int l; @@ -2574,7 +2574,7 @@ int cpu_memory_rw_debug(CPUArchState *env, target_ulong addr, while (len > 0) { page = addr & TARGET_PAGE_MASK; -phys_addr = cpu_get_phys_page_debug(ENV_GET_CPU(env), page); +phys_addr = cpu_get_phys_page_debug(cpu, page); /* if no physical page mapped, return an error */ if (phys_addr == -1) return -1; diff --git a/gdbstub.c b/gdbstub.c index cee9c13..43ecc0d 100644 --- a/gdbstub.c +++ b/gdbstub.c @@ -46,7 +46,7 @@ static inline int target_memory_rw_debug(CPUArchState *env, target_ulong addr, uint8_t *buf, int len, int is_write) { -return cpu_memory_rw_debug(env, addr, buf, len, is_write); +return cpu_memory_rw_debug(ENV_GET_CPU(env), addr, buf, len, is_write); } #else /* target_memory_rw_debug() defined in cpu.h */ diff --git a/hw/i386/kvmvapic.c b/hw/i386/kvmvapic.c index 76fca34..860dea7 100644 --- a/hw/i386/kvmvapic.c +++ b/hw/i386/kvmvapic.c @@ -188,9 +188,10 @@ static bool opcode_matches(uint8_t *opcode, const TPRInstruction *instr) modrm_reg(opcode[1]) == instr->modrm_reg); } -static int evaluate_tpr_instruction(VAPICROMState *s, CPUX86State *env, +static int evaluate_tpr_instruction(VAPICROMState *s, X86CPU *cpu, target_ulong *pip, TPRAccess access) { +CPUState *cs = CPU(cpu); const TPRInstruction *instr; target_ulong ip = *pip; uint8_t opcode[2]; @@ -211,7 +212,7 @@ static int evaluate_tpr_instruction(VAPICROMState *s, CPUX86State *env, * RSP, used by the patched instruction, is zero, so the guest gets a * double fault and dies. */ -if (env->regs[R_ESP] == 0) { +if (cpu->env.regs[R_ESP] == 0) { return -1; } @@ -226,7 +227,7 @@ static int evaluate_tpr_instruction(VAPICROMState *s, CPUX86State *env, if (instr->acces
[Qemu-devel] [PATCH RFC qom-cpu 33/41] cpu: Turn cpu_get_phys_page_debug() into a CPUClass hook
Since all targets now assign a softmmu-only field, we can drop helpers cpu_class_set_{do_unassigned_access,vmsd}() and device_class_set_vmsd(). Prepares for changing cpu_memory_rw_debug() argument to CPUState. Signed-off-by: Andreas Färber --- exec.c | 20 ++-- hw/i386/kvmvapic.c | 6 ++-- include/exec/cpu-all.h | 5 --- include/qom/cpu.h | 74 + target-alpha/cpu-qom.h | 1 + target-alpha/cpu.c | 7 +++-- target-alpha/helper.c | 5 +-- target-arm/cpu-qom.h| 2 ++ target-arm/cpu.c| 5 ++- target-arm/helper.c | 8 +++-- target-cris/cpu-qom.h | 2 ++ target-cris/cpu.c | 3 ++ target-cris/helper.c| 7 +++-- target-i386/cpu-qom.h | 2 ++ target-i386/cpu.c | 3 +- target-i386/helper.c| 4 ++- target-lm32/cpu-qom.h | 1 + target-lm32/cpu.c | 5 ++- target-lm32/helper.c| 6 ++-- target-m68k/cpu-qom.h | 1 + target-m68k/cpu.c | 3 ++ target-m68k/helper.c| 2 +- target-microblaze/cpu-qom.h | 1 + target-microblaze/cpu.c | 5 ++- target-microblaze/helper.c | 4 ++- target-mips/cpu-qom.h | 1 + target-mips/cpu.c | 5 ++- target-mips/helper.c| 7 +++-- target-moxie/cpu.c | 5 ++- target-moxie/cpu.h | 1 + target-moxie/helper.c | 11 +++ target-openrisc/cpu.c | 5 ++- target-openrisc/cpu.h | 1 + target-openrisc/mmu.c | 5 ++- target-ppc/cpu-qom.h| 1 + target-ppc/mmu_helper.c | 4 ++- target-s390x/cpu-qom.h | 1 + target-s390x/cpu.c | 3 ++ target-s390x/helper.c | 5 +-- target-sh4/cpu-qom.h| 1 + target-sh4/cpu.c| 3 ++ target-sh4/helper.c | 5 +-- target-sparc/cpu-qom.h | 1 + target-sparc/cpu.c | 5 ++- target-sparc/mmu_helper.c | 11 --- target-unicore32/cpu-qom.h | 1 + target-unicore32/cpu.c | 3 ++ target-unicore32/softmmu.c | 7 +++-- target-xtensa/cpu-qom.h | 1 + target-xtensa/cpu.c | 3 ++ target-xtensa/helper.c | 7 +++-- target-xtensa/xtensa-semi.c | 4 +-- 52 files changed, 168 insertions(+), 121 deletions(-) diff --git a/exec.c b/exec.c index 56a1d84..359dc64 100644 --- a/exec.c +++ b/exec.c @@ -411,14 +411,14 @@ void cpu_exec_init(CPUArchState *env) #if defined(TARGET_HAS_ICE) #if defined(CONFIG_USER_ONLY) -static void breakpoint_invalidate(CPUArchState *env, target_ulong pc) +static void breakpoint_invalidate(CPUState *cpu, target_ulong pc) { tb_invalidate_phys_page_range(pc, pc + 1, 0); } #else -static void breakpoint_invalidate(CPUArchState *env, target_ulong pc) +static void breakpoint_invalidate(CPUState *cpu, target_ulong pc) { -tb_invalidate_phys_addr(cpu_get_phys_page_debug(env, pc) | +tb_invalidate_phys_addr(cpu_get_phys_page_debug(cpu, pc) | (pc & ~TARGET_PAGE_MASK)); } #endif @@ -521,15 +521,17 @@ int cpu_breakpoint_insert(CPUArchState *env, target_ulong pc, int flags, bp->flags = flags; /* keep all GDB-injected breakpoints in front */ -if (flags & BP_GDB) +if (flags & BP_GDB) { QTAILQ_INSERT_HEAD(&env->breakpoints, bp, entry); -else +} else { QTAILQ_INSERT_TAIL(&env->breakpoints, bp, entry); +} -breakpoint_invalidate(env, pc); +breakpoint_invalidate(ENV_GET_CPU(env), pc); -if (breakpoint) +if (breakpoint) { *breakpoint = bp; +} return 0; #else return -ENOSYS; @@ -560,7 +562,7 @@ void cpu_breakpoint_remove_by_ref(CPUArchState *env, CPUBreakpoint *breakpoint) #if defined(TARGET_HAS_ICE) QTAILQ_REMOVE(&env->breakpoints, breakpoint, entry); -breakpoint_invalidate(env, breakpoint->pc); +breakpoint_invalidate(ENV_GET_CPU(env), breakpoint->pc); g_free(breakpoint); #endif @@ -2572,7 +2574,7 @@ int cpu_memory_rw_debug(CPUArchState *env, target_ulong addr, while (len > 0) { page = addr & TARGET_PAGE_MASK; -phys_addr = cpu_get_phys_page_debug(env, page); +phys_addr = cpu_get_phys_page_debug(ENV_GET_CPU(env), page); /* if no physical page mapped, return an error */ if (phys_addr == -1) return -1; diff --git a/hw/i386/kvmvapic.c b/hw/i386/kvmvapic.c index d60864e..76fca34 100644 --- a/hw/i386/kvmvapic.c +++ b/hw/i386/kvmvapic.c @@ -146,6 +146,7 @@ static void update_guest_rom_state(VAPICROMState *s) static int find_real_tpr_addr(VAPICROMState *s, CPUX86State *env) { +CPUState *cs = CPU(x86_env_get_cpu(env)); hwaddr paddr; target_ulong addr; @@ -158,7 +159,7 @@ static int find_real_tpr_addr(VAPICROMState *s, CPUX86State *env) * virtual address space for the APIC mapping. */ for (addr = 0xf000; addr >= 0x8000; addr -= TARGET_PAGE_SIZE) { -paddr = cpu_get_phys_page_debug(env
[Qemu-devel] [PATCH RFC qom-cpu 39/41] target-xtensa: Introduce XtensaCPU subclasses
Register a CPU type per core registered. Save the XtensaConfig in XtensaCPUClass instead of CPUXtensaState. Prepares for storing per-class GDB register count. Signed-off-by: Andreas Färber --- gdbstub.c | 17 --- hw/xtensa/pic_cpu.c | 47 -- target-xtensa/cpu-qom.h | 3 ++ target-xtensa/cpu.c | 30 ++-- target-xtensa/cpu.h | 22 + target-xtensa/helper.c| 93 +++ target-xtensa/op_helper.c | 121 -- target-xtensa/translate.c | 12 +++-- 8 files changed, 236 insertions(+), 109 deletions(-) diff --git a/gdbstub.c b/gdbstub.c index 4ebe9e0..d08cfd3 100644 --- a/gdbstub.c +++ b/gdbstub.c @@ -1692,14 +1692,16 @@ static int cpu_gdb_write_register(CPULM32State *env, uint8_t *mem_buf, int n) * reset bit 0 in the 'flags' field of the registers definitions in the * gdb/xtensa-config.c inside gdb source tree or inside gdb overlay. */ -#define NUM_CORE_REGS (env->config->gdb_regmap.num_regs) +#define NUM_CORE_REGS \ + (XTENSA_CPU_GET_CLASS(xtensa_env_get_cpu(env))->config->gdb_regmap.num_regs) #define num_g_regs NUM_CORE_REGS static int cpu_gdb_read_register(CPUXtensaState *env, uint8_t *mem_buf, int n) { -const XtensaGdbReg *reg = env->config->gdb_regmap.reg + n; +XtensaCPUClass *xcc = XTENSA_CPU_GET_CLASS(xtensa_env_get_cpu(env)); +const XtensaGdbReg *reg = xcc->config->gdb_regmap.reg + n; -if (n < 0 || n >= env->config->gdb_regmap.num_regs) { +if (n < 0 || n >= xcc->config->gdb_regmap.num_regs) { return 0; } @@ -1710,7 +1712,7 @@ static int cpu_gdb_read_register(CPUXtensaState *env, uint8_t *mem_buf, int n) case 1: /*ar*/ xtensa_sync_phys_from_window(env); -GET_REG32(env->phys_regs[(reg->targno & 0xff) % env->config->nareg]); +GET_REG32(env->phys_regs[(reg->targno & 0xff) % xcc->config->nareg]); break; case 2: /*SR*/ @@ -1738,10 +1740,11 @@ static int cpu_gdb_read_register(CPUXtensaState *env, uint8_t *mem_buf, int n) static int cpu_gdb_write_register(CPUXtensaState *env, uint8_t *mem_buf, int n) { +XtensaCPUClass *xcc = XTENSA_CPU_GET_CLASS(xtensa_env_get_cpu(env)); uint32_t tmp; -const XtensaGdbReg *reg = env->config->gdb_regmap.reg + n; +const XtensaGdbReg *reg = xcc->config->gdb_regmap.reg + n; -if (n < 0 || n >= env->config->gdb_regmap.num_regs) { +if (n < 0 || n >= xcc->config->gdb_regmap.num_regs) { return 0; } @@ -1753,7 +1756,7 @@ static int cpu_gdb_write_register(CPUXtensaState *env, uint8_t *mem_buf, int n) break; case 1: /*ar*/ -env->phys_regs[(reg->targno & 0xff) % env->config->nareg] = tmp; +env->phys_regs[(reg->targno & 0xff) % xcc->config->nareg] = tmp; xtensa_sync_window_from_phys(env); break; diff --git a/hw/xtensa/pic_cpu.c b/hw/xtensa/pic_cpu.c index 7f015ff..048038d 100644 --- a/hw/xtensa/pic_cpu.c +++ b/hw/xtensa/pic_cpu.c @@ -31,13 +31,15 @@ void xtensa_advance_ccount(CPUXtensaState *env, uint32_t d) { +XtensaCPU *cpu = xtensa_env_get_cpu(env); +XtensaCPUClass *xcc = XTENSA_CPU_GET_CLASS(cpu); uint32_t old_ccount = env->sregs[CCOUNT]; env->sregs[CCOUNT] += d; -if (xtensa_option_enabled(env->config, XTENSA_OPTION_TIMER_INTERRUPT)) { +if (xtensa_option_enabled(xcc->config, XTENSA_OPTION_TIMER_INTERRUPT)) { int i; -for (i = 0; i < env->config->nccompare; ++i) { +for (i = 0; i < xcc->config->nccompare; ++i) { if (env->sregs[CCOMPARE + i] - old_ccount <= d) { xtensa_timer_irq(env, i, 1); } @@ -47,7 +49,9 @@ void xtensa_advance_ccount(CPUXtensaState *env, uint32_t d) void check_interrupts(CPUXtensaState *env) { -CPUState *cs = CPU(xtensa_env_get_cpu(env)); +XtensaCPU *cpu = xtensa_env_get_cpu(env); +CPUState *cs = CPU(cpu); +XtensaCPUClass *xcc = XTENSA_CPU_GET_CLASS(cpu); int minlevel = xtensa_get_cintlevel(env); uint32_t int_set_enabled = env->sregs[INTSET] & env->sregs[INTENABLE]; int level; @@ -60,11 +64,11 @@ void check_interrupts(CPUXtensaState *env) xtensa_advance_ccount(env, muldiv64(now - env->halt_clock, -env->config->clock_freq_khz, 100)); +xcc->config->clock_freq_khz, 100)); env->halt_clock = now; } -for (level = env->config->nlevel; level > minlevel; --level) { -if (env->config->level_mask[level] & int_set_enabled) { +for (level = xcc->config->nlevel; level > minlevel; --level) { +if (xcc->config->level_mask[level] & int_set_enabled) { env->pending_irq_level = level; cpu_interrupt(cs, CPU_INTERRUPT_HARD); qemu_log_mask(CPU_LOG_INT, @@ -86,15 +90,17 @@ void check_interrupts(CPUXtensaState *env) static void xtensa_set_irq(void *opaque, int irq,
Re: [Qemu-devel] Openbios upgrade broke sparc32 linux.
On 28/06/2013 23:44, Mark Cave-Ayland wrote: On 28/06/13 03:08, Rob Landley wrote: Commit 467b34689d27 upgraded the openbios image, and ever since my linux system images hang about the time they try to initialize interrupts. http://landley.net/aboriginal/bin/system-image-sparc.tar.bz2 Extract that and "./run-emulator.sh" in the tarball. Using qemu 1.2.0 for example works fine, you get a shell prompt. Using 1.5.0 hangs. Rob Hi Rob, Thanks for the bug report. I did a quick bisect on OpenBIOS and it points to the following commit: commit 167aafd70f64e74a77787ca5bf9f4dc750b27fc3 Author: blueswirl Date: Sun Feb 3 16:50:11 2013 + SPARC32: microSPARC-II identification For the microSPARC-II = Fujitsu MB86904 = Sun STP1012PGA, PSR.IMPL=0 and PSR.VERS=4. This CPU model is used as default by QEMU when emulating a SparcStation-4 or SparcStation-5. Signed-off-by: Olivier DANET Signed-off-by: Blue Swirl The commit itself is very simple and looks like this: http://git.qemu.org/?p=openbios.git;a=commitdiff;h=0fe772df8717ef75d91eae8ef221e9966ce2fd7f. My guess would be that Linux is trying to do some slightly different initialisation based upon identifying the CPU, but I'm not too familiar with the kernel code myself. Blue/Olivier - can either of you comment on this? ATB, Mark. How embarrassing... - QEMU 1.5.1 can boot Debian Etch (kernel 2.6.18), RedHat 4.2 (kernel 2.0.30), NetBSD 6.1 and OpenBSD 5.3. - Your image (Linux 3.8) can be started with a TurboSparc CPU : qemu -cpu "Fujitsu MB86907". - My SparcStation-5 has a 110MHz MicroSPARC-II and the .attributes (aka .properties) fields are identical to OpenBIOS values, except for the mask_rev : I have 0x26, OpenBIOS sets 0x23 Before the patch, OpenBIOS had an incoherence between the PSR register content and the BIOS defined values. In Linux "arch/sparc/mm/srmmu.c:get_srmmu_type(void)", this correspond to "a TurboSparc emulating Swift". (Swift is the MS-2). TurboSPARC could be the new QEMU default, but, ideally, the MS-II should be preferred as it is compatible with more OSes ( hoping to run NextStep in QEMU one day ...). Maybe recent Linux kernels are not compatible with the way QEMU emulates the MS-II... Regards Olivier [temlib.org]
[Qemu-devel] [PATCH RFC qom-cpu 04/41] cpu: Introduce CPUClass::set_pc() for gdb_set_cpu_pc()
This moves setting the Program Counter from gdbstub into target code. Use uint64_t type as maximum replacement for target_ulong. Signed-off-by: Andreas Färber --- gdbstub.c | 39 ++- include/qom/cpu.h | 1 + target-alpha/cpu.c | 8 target-arm/cpu.c| 8 target-cris/cpu.c | 8 target-i386/cpu.c | 8 target-lm32/cpu.c | 8 target-microblaze/cpu.c | 8 target-mips/cpu.c | 14 ++ target-openrisc/cpu.c | 8 target-ppc/translate_init.c | 8 target-s390x/cpu.c | 8 target-sh4/cpu.c| 8 target-sparc/cpu.c | 9 + target-xtensa/cpu.c | 8 15 files changed, 118 insertions(+), 33 deletions(-) diff --git a/gdbstub.c b/gdbstub.c index 4a0d04e..bdf4496 100644 --- a/gdbstub.c +++ b/gdbstub.c @@ -2042,40 +2042,13 @@ static void gdb_breakpoint_remove_all(void) static void gdb_set_cpu_pc(GDBState *s, target_ulong pc) { -cpu_synchronize_state(ENV_GET_CPU(s->c_cpu)); -#if defined(TARGET_I386) -s->c_cpu->eip = pc; -#elif defined (TARGET_PPC) -s->c_cpu->nip = pc; -#elif defined (TARGET_SPARC) -s->c_cpu->pc = pc; -s->c_cpu->npc = pc + 4; -#elif defined (TARGET_ARM) -s->c_cpu->regs[15] = pc; -#elif defined (TARGET_SH4) -s->c_cpu->pc = pc; -#elif defined (TARGET_MIPS) -s->c_cpu->active_tc.PC = pc & ~(target_ulong)1; -if (pc & 1) { -s->c_cpu->hflags |= MIPS_HFLAG_M16; -} else { -s->c_cpu->hflags &= ~(MIPS_HFLAG_M16); +CPUState *cpu = ENV_GET_CPU(s->c_cpu); +CPUClass *cc = CPU_GET_CLASS(cpu); + +cpu_synchronize_state(cpu); +if (cc->set_pc) { +cc->set_pc(cpu, pc); } -#elif defined (TARGET_MICROBLAZE) -s->c_cpu->sregs[SR_PC] = pc; -#elif defined(TARGET_OPENRISC) -s->c_cpu->pc = pc; -#elif defined (TARGET_CRIS) -s->c_cpu->pc = pc; -#elif defined (TARGET_ALPHA) -s->c_cpu->pc = pc; -#elif defined (TARGET_S390X) -s->c_cpu->psw.addr = pc; -#elif defined (TARGET_LM32) -s->c_cpu->pc = pc; -#elif defined(TARGET_XTENSA) -s->c_cpu->pc = pc; -#endif } static CPUArchState *find_cpu(uint32_t thread_id) diff --git a/include/qom/cpu.h b/include/qom/cpu.h index 147c256..3701eb1 100644 --- a/include/qom/cpu.h +++ b/include/qom/cpu.h @@ -84,6 +84,7 @@ typedef struct CPUClass { bool (*get_paging_enabled)(const CPUState *cpu); void (*get_memory_mapping)(CPUState *cpu, MemoryMappingList *list, Error **errp); +void (*set_pc)(CPUState *cpu, uint64_t value); const struct VMStateDescription *vmsd; int (*write_elf64_note)(WriteCoreDumpFunction f, CPUState *cpu, diff --git a/target-alpha/cpu.c b/target-alpha/cpu.c index 2670805..9679ac4 100644 --- a/target-alpha/cpu.c +++ b/target-alpha/cpu.c @@ -24,6 +24,13 @@ #include "migration/vmstate.h" +static void alpha_cpu_set_pc(CPUState *cs, uint64_t value) +{ +AlphaCPU *cpu = ALPHA_CPU(cs); + +cpu->env.pc = value; +} + static void alpha_cpu_realizefn(DeviceState *dev, Error **errp) { AlphaCPUClass *acc = ALPHA_CPU_GET_CLASS(dev); @@ -264,6 +271,7 @@ static void alpha_cpu_class_init(ObjectClass *oc, void *data) cc->do_interrupt = alpha_cpu_do_interrupt; cc->dump_state = alpha_cpu_dump_state; cpu_class_set_do_unassigned_access(cc, alpha_cpu_unassigned_access); +cc->set_pc = alpha_cpu_set_pc; device_class_set_vmsd(dc, &vmstate_alpha_cpu); } diff --git a/target-arm/cpu.c b/target-arm/cpu.c index be26acc..281e252 100644 --- a/target-arm/cpu.c +++ b/target-arm/cpu.c @@ -25,6 +25,13 @@ #endif #include "sysemu/sysemu.h" +static void arm_cpu_set_pc(CPUState *cs, uint64_t value) +{ +ARMCPU *cpu = ARM_CPU(cs); + +cpu->env.regs[15] = value; +} + static void cp_reg_reset(gpointer key, gpointer value, gpointer opaque) { /* Reset a single ARMCPRegInfo register */ @@ -811,6 +818,7 @@ static void arm_cpu_class_init(ObjectClass *oc, void *data) cc->class_by_name = arm_cpu_class_by_name; cc->do_interrupt = arm_cpu_do_interrupt; cc->dump_state = arm_cpu_dump_state; +cc->set_pc = arm_cpu_set_pc; cpu_class_set_vmsd(cc, &vmstate_arm_cpu); } diff --git a/target-cris/cpu.c b/target-cris/cpu.c index 2abb57f..f7e8c2a 100644 --- a/target-cris/cpu.c +++ b/target-cris/cpu.c @@ -26,6 +26,13 @@ #include "mmu.h" +static void cris_cpu_set_pc(CPUState *cs, uint64_t value) +{ +CRISCPU *cpu = CRIS_CPU(cs); + +cpu->env.pc = value; +} + /* CPUClass::reset() */ static void cris_cpu_reset(CPUState *s) { @@ -247,6 +254,7 @@ static void cris_cpu_class_init(ObjectClass *oc, void *data) cc->class_by_name = cris_cpu_class_by_name; cc->do_interrupt = cris_cpu_do_interrupt; cc->dump_state = cris_cpu_dump_state; +cc->set_pc = cris_cpu_set_pc; } static const
[Qemu-devel] [PATCH RFC qom-cpu 16/41] target-microblaze: Change gen_intermediate_code_internal() argument types
Use MicroBlazeCPU and bool. Prepares for moving singlestep_enabled field to CPUState. Signed-off-by: Andreas Färber --- target-microblaze/translate.c | 12 +--- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/target-microblaze/translate.c b/target-microblaze/translate.c index f9acdb1..6484378 100644 --- a/target-microblaze/translate.c +++ b/target-microblaze/translate.c @@ -1738,12 +1738,10 @@ static void check_breakpoint(CPUMBState *env, DisasContext *dc) /* generate intermediate code for basic block 'tb'. */ static void -gen_intermediate_code_internal(CPUMBState *env, TranslationBlock *tb, - int search_pc) +gen_intermediate_code_internal(MicroBlazeCPU *cpu, TranslationBlock *tb, + bool search_pc) { -#if !SIM_COMPAT -MicroBlazeCPU *cpu = mb_env_get_cpu(env); -#endif +CPUMBState *env = &cpu->env; uint16_t *gen_opc_end; uint32_t pc_start; int j, lj; @@ -1944,12 +1942,12 @@ gen_intermediate_code_internal(CPUMBState *env, TranslationBlock *tb, void gen_intermediate_code (CPUMBState *env, struct TranslationBlock *tb) { -gen_intermediate_code_internal(env, tb, 0); +gen_intermediate_code_internal(mb_env_get_cpu(env), tb, false); } void gen_intermediate_code_pc (CPUMBState *env, struct TranslationBlock *tb) { -gen_intermediate_code_internal(env, tb, 1); +gen_intermediate_code_internal(mb_env_get_cpu(env), tb, true); } void mb_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf, -- 1.8.1.4
[Qemu-devel] [PATCH RFC qom-cpu 12/41] target-cris: Change gen_intermediate_code_internal() argument to CRISCPU
Also use bool type while at it. Prepares for moving singlestep_enabled field to CPUState. Signed-off-by: Andreas Färber --- target-cris/translate.c | 9 + 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/target-cris/translate.c b/target-cris/translate.c index 09d0d2b..ce1f03b 100644 --- a/target-cris/translate.c +++ b/target-cris/translate.c @@ -3162,9 +3162,10 @@ static void check_breakpoint(CPUCRISState *env, DisasContext *dc) /* generate intermediate code for basic block 'tb'. */ static void -gen_intermediate_code_internal(CPUCRISState *env, TranslationBlock *tb, - int search_pc) +gen_intermediate_code_internal(CRISCPU *cpu, TranslationBlock *tb, + bool search_pc) { +CPUCRISState *env = &cpu->env; uint16_t *gen_opc_end; uint32_t pc_start; unsigned int insn_len; @@ -3419,12 +3420,12 @@ gen_intermediate_code_internal(CPUCRISState *env, TranslationBlock *tb, void gen_intermediate_code (CPUCRISState *env, struct TranslationBlock *tb) { -gen_intermediate_code_internal(env, tb, 0); +gen_intermediate_code_internal(cris_env_get_cpu(env), tb, false); } void gen_intermediate_code_pc (CPUCRISState *env, struct TranslationBlock *tb) { -gen_intermediate_code_internal(env, tb, 1); +gen_intermediate_code_internal(cris_env_get_cpu(env), tb, true); } void cris_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf, -- 1.8.1.4
[Qemu-devel] [PATCH RFC qom-cpu 23/41] target-xtensa: Change gen_intermediate_code_internal() arg to XtensaCPU
Also use bool type while at it. Prepares for moving singlestep_enabled field to CPUState. Signed-off-by: Andreas Färber --- target-xtensa/translate.c | 10 ++ 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/target-xtensa/translate.c b/target-xtensa/translate.c index dcb90a5..d5f2068 100644 --- a/target-xtensa/translate.c +++ b/target-xtensa/translate.c @@ -2875,9 +2875,11 @@ static void gen_ibreak_check(CPUXtensaState *env, DisasContext *dc) } } -static void gen_intermediate_code_internal( -CPUXtensaState *env, TranslationBlock *tb, int search_pc) +static void gen_intermediate_code_internal(XtensaCPU *cpu, + TranslationBlock *tb, + bool search_pc) { +CPUXtensaState *env = &cpu->env; DisasContext dc; int insn_count = 0; int j, lj = -1; @@ -3006,12 +3008,12 @@ static void gen_intermediate_code_internal( void gen_intermediate_code(CPUXtensaState *env, TranslationBlock *tb) { -gen_intermediate_code_internal(env, tb, 0); +gen_intermediate_code_internal(xtensa_env_get_cpu(env), tb, false); } void gen_intermediate_code_pc(CPUXtensaState *env, TranslationBlock *tb) { -gen_intermediate_code_internal(env, tb, 1); +gen_intermediate_code_internal(xtensa_env_get_cpu(env), tb, true); } void xtensa_cpu_dump_state(CPUState *cs, FILE *f, -- 1.8.1.4
[Qemu-devel] [PATCH RFC qom-cpu 14/41] target-lm32: Change gen_intermediate_code_internal() argument to LM32CPU
Also use bool type while at it. Prepares for moving singlestep_enabled field to CPUState. Signed-off-by: Andreas Färber --- target-lm32/translate.c | 9 + 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/target-lm32/translate.c b/target-lm32/translate.c index 227a801..6d107dc 100644 --- a/target-lm32/translate.c +++ b/target-lm32/translate.c @@ -1011,9 +1011,10 @@ static void check_breakpoint(CPULM32State *env, DisasContext *dc) } /* generate intermediate code for basic block 'tb'. */ -static void gen_intermediate_code_internal(CPULM32State *env, -TranslationBlock *tb, int search_pc) +static void gen_intermediate_code_internal(LM32CPU *cpu, +TranslationBlock *tb, bool search_pc) { +CPULM32State *env = &cpu->env; struct DisasContext ctx, *dc = &ctx; uint16_t *gen_opc_end; uint32_t pc_start; @@ -1133,12 +1134,12 @@ static void gen_intermediate_code_internal(CPULM32State *env, void gen_intermediate_code(CPULM32State *env, struct TranslationBlock *tb) { -gen_intermediate_code_internal(env, tb, 0); +gen_intermediate_code_internal(lm32_env_get_cpu(env), tb, false); } void gen_intermediate_code_pc(CPULM32State *env, struct TranslationBlock *tb) { -gen_intermediate_code_internal(env, tb, 1); +gen_intermediate_code_internal(lm32_env_get_cpu(env), tb, true); } void lm32_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf, -- 1.8.1.4
[Qemu-devel] [PATCH RFC qom-cpu 18/41] target-ppc: Change gen_intermediate_code_internal() argument to PowerPCCPU
Also use bool type while at it. Prepares for moving singlestep_enabled field to CPUState. Signed-off-by: Andreas Färber --- target-ppc/translate.c | 9 + 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/target-ppc/translate.c b/target-ppc/translate.c index 3643863..eb96272 100644 --- a/target-ppc/translate.c +++ b/target-ppc/translate.c @@ -9726,10 +9726,11 @@ void ppc_cpu_dump_statistics(CPUState *cs, FILE*f, } /*/ -static inline void gen_intermediate_code_internal(CPUPPCState *env, +static inline void gen_intermediate_code_internal(PowerPCCPU *cpu, TranslationBlock *tb, - int search_pc) + bool search_pc) { +CPUPPCState *env = &cpu->env; DisasContext ctx, *ctxp = &ctx; opc_handler_t **table, *handler; target_ulong pc_start; @@ -9917,12 +9918,12 @@ static inline void gen_intermediate_code_internal(CPUPPCState *env, void gen_intermediate_code (CPUPPCState *env, struct TranslationBlock *tb) { -gen_intermediate_code_internal(env, tb, 0); +gen_intermediate_code_internal(ppc_env_get_cpu(env), tb, false); } void gen_intermediate_code_pc (CPUPPCState *env, struct TranslationBlock *tb) { -gen_intermediate_code_internal(env, tb, 1); +gen_intermediate_code_internal(ppc_env_get_cpu(env), tb, true); } void restore_state_to_opc(CPUPPCState *env, TranslationBlock *tb, int pc_pos) -- 1.8.1.4
[Qemu-devel] [PATCH RFC qom-cpu 31/41] gdbstub: Change GDBState::c_cpu to CPUState
Allows us to drop find_cpu(). Xtensa still needs env for its num_g_regs. Signed-off-by: Andreas Färber --- gdbstub.c | 68 +-- 1 file changed, 31 insertions(+), 37 deletions(-) diff --git a/gdbstub.c b/gdbstub.c index 81a8941..a8fafe2 100644 --- a/gdbstub.c +++ b/gdbstub.c @@ -287,7 +287,7 @@ enum RSState { RS_CHKSUM2, }; typedef struct GDBState { -CPUArchState *c_cpu; /* current CPU for step/continue ops */ +CPUState *c_cpu; /* current CPU for step/continue ops */ CPUArchState *g_cpu; /* current CPU for other ops */ CPUState *query_cpu; /* for q{f|s}ThreadInfo */ enum RSState state; /* parsing state */ @@ -1955,8 +1955,7 @@ static int gdb_breakpoint_insert(target_ulong addr, target_ulong len, int type) int err = 0; if (kvm_enabled()) { -return kvm_insert_breakpoint(ENV_GET_CPU(gdbserver_state->c_cpu), - addr, len, type); +return kvm_insert_breakpoint(gdbserver_state->c_cpu, addr, len, type); } switch (type) { @@ -1994,8 +1993,7 @@ static int gdb_breakpoint_remove(target_ulong addr, target_ulong len, int type) int err = 0; if (kvm_enabled()) { -return kvm_remove_breakpoint(ENV_GET_CPU(gdbserver_state->c_cpu), - addr, len, type); +return kvm_remove_breakpoint(gdbserver_state->c_cpu, addr, len, type); } switch (type) { @@ -2031,7 +2029,7 @@ static void gdb_breakpoint_remove_all(void) CPUArchState *env; if (kvm_enabled()) { -kvm_remove_all_breakpoints(ENV_GET_CPU(gdbserver_state->c_cpu)); +kvm_remove_all_breakpoints(gdbserver_state->c_cpu); return; } @@ -2046,7 +2044,7 @@ static void gdb_breakpoint_remove_all(void) static void gdb_set_cpu_pc(GDBState *s, target_ulong pc) { -CPUState *cpu = ENV_GET_CPU(s->c_cpu); +CPUState *cpu = s->c_cpu; CPUClass *cc = CPU_GET_CLASS(cpu); cpu_synchronize_state(cpu); @@ -2055,20 +2053,11 @@ static void gdb_set_cpu_pc(GDBState *s, target_ulong pc) } } -static CPUArchState *find_cpu(uint32_t thread_id) -{ -CPUState *cpu; - -cpu = qemu_get_cpu(thread_id); -if (cpu == NULL) { -return NULL; -} -return cpu->env_ptr; -} - static int gdb_handle_packet(GDBState *s, const char *line_buf) { +#ifdef TARGET_XTENSA CPUArchState *env; +#endif CPUState *cpu; const char *p; uint32_t thread; @@ -2087,7 +2076,7 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf) case '?': /* TODO: Make this return the correct value for user-mode. */ snprintf(buf, sizeof(buf), "T%02xthread:%02x;", GDB_SIGNAL_TRAP, - cpu_index(ENV_GET_CPU(s->c_cpu))); + cpu_index(s->c_cpu)); put_packet(s, buf); /* Remove all the breakpoints when this query is issued, * because gdb is doing and initial connect and the state @@ -2149,15 +2138,15 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf) } if (res) { if (res_thread != -1 && res_thread != 0) { -env = find_cpu(res_thread); -if (env == NULL) { +cpu = qemu_get_cpu(res_thread); +if (cpu == NULL) { put_packet(s, "E22"); break; } -s->c_cpu = env; +s->c_cpu = cpu; } if (res == 's') { -cpu_single_step(ENV_GET_CPU(s->c_cpu), sstep_flags); +cpu_single_step(s->c_cpu, sstep_flags); } s->signal = res_signal; gdb_continue(s); @@ -2185,7 +2174,7 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf) addr = strtoull(p, (char **)&p, 16); gdb_set_cpu_pc(s, addr); } -cpu_single_step(ENV_GET_CPU(s->c_cpu), sstep_flags); +cpu_single_step(s->c_cpu, sstep_flags); gdb_continue(s); return RS_IDLE; case 'F': @@ -2204,7 +2193,7 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf) p++; type = *p; if (s->current_syscall_cb) { -s->current_syscall_cb(ENV_GET_CPU(s->c_cpu), ret, err); +s->current_syscall_cb(s->c_cpu, ret, err); s->current_syscall_cb = NULL; } if (type == 'C') { @@ -2216,7 +2205,9 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf) break; case 'g': cpu_synchronize_state(ENV_GET_CPU(s->g_cpu)); +#ifdef TARGET_XTENSA env = s->g_cpu; +#endif len = 0; for (addr = 0; addr < num_g_regs; addr++) { reg_size = gdb_read_register(s->g_cpu, mem_buf + len, addr); @@ -2227,7 +22
[Qemu-devel] [PATCH RFC qom-cpu 19/41] target-s390x: Change gen_intermediate_code_internal() argument to S390CPU
Also use bool type while at it. Prepares for moving singlestep_enabled field to CPUState. Signed-off-by: Andreas Färber --- target-s390x/translate.c | 9 + 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/target-s390x/translate.c b/target-s390x/translate.c index cd9880e..cba7b87 100644 --- a/target-s390x/translate.c +++ b/target-s390x/translate.c @@ -4736,10 +4736,11 @@ static ExitStatus translate_one(CPUS390XState *env, DisasContext *s) return ret; } -static inline void gen_intermediate_code_internal(CPUS390XState *env, +static inline void gen_intermediate_code_internal(S390CPU *cpu, TranslationBlock *tb, - int search_pc) + bool search_pc) { +CPUS390XState *env = &cpu->env; DisasContext dc; target_ulong pc_start; uint64_t next_page_start; @@ -4872,12 +4873,12 @@ static inline void gen_intermediate_code_internal(CPUS390XState *env, void gen_intermediate_code (CPUS390XState *env, struct TranslationBlock *tb) { -gen_intermediate_code_internal(env, tb, 0); +gen_intermediate_code_internal(s390_env_get_cpu(env), tb, false); } void gen_intermediate_code_pc (CPUS390XState *env, struct TranslationBlock *tb) { -gen_intermediate_code_internal(env, tb, 1); +gen_intermediate_code_internal(s390_env_get_cpu(env), tb, true); } void restore_state_to_opc(CPUS390XState *env, TranslationBlock *tb, int pc_pos) -- 1.8.1.4
[Qemu-devel] [PATCH RFC qom-cpu 36/41] gdbstub: Change GDBState::g_cpu to CPUState
Use CPUState::env_ptr for Xtensa. This removes the last user of CPUArchState from gdb_set_stop_cpu(). Signed-off-by: Andreas Färber --- gdbstub.c | 35 +++ 1 file changed, 15 insertions(+), 20 deletions(-) diff --git a/gdbstub.c b/gdbstub.c index fa44550..7be2342 100644 --- a/gdbstub.c +++ b/gdbstub.c @@ -289,7 +289,7 @@ enum RSState { }; typedef struct GDBState { CPUState *c_cpu; /* current CPU for step/continue ops */ -CPUArchState *g_cpu; /* current CPU for other ops */ +CPUState *g_cpu; /* current CPU for other ops */ CPUState *query_cpu; /* for q{f|s}ThreadInfo */ enum RSState state; /* parsing state */ char line_buf[MAX_PACKET_LENGTH]; @@ -2207,30 +2207,28 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf) } break; case 'g': -cpu_synchronize_state(ENV_GET_CPU(s->g_cpu)); +cpu_synchronize_state(s->g_cpu); #ifdef TARGET_XTENSA -env = s->g_cpu; +env = s->g_cpu->env_ptr; #endif len = 0; for (addr = 0; addr < num_g_regs; addr++) { -reg_size = gdb_read_register(ENV_GET_CPU(s->g_cpu), - mem_buf + len, addr); +reg_size = gdb_read_register(s->g_cpu, mem_buf + len, addr); len += reg_size; } memtohex(buf, mem_buf, len); put_packet(s, buf); break; case 'G': -cpu_synchronize_state(ENV_GET_CPU(s->g_cpu)); +cpu_synchronize_state(s->g_cpu); #ifdef TARGET_XTENSA -env = s->g_cpu; +env = s->g_cpu->env_ptr; #endif registers = mem_buf; len = strlen(p) / 2; hextomem((uint8_t *)registers, p, len); for (addr = 0; addr < num_g_regs && len > 0; addr++) { -reg_size = gdb_write_register(ENV_GET_CPU(s->g_cpu), registers, - addr); +reg_size = gdb_write_register(s->g_cpu, registers, addr); len -= reg_size; registers += reg_size; } @@ -2241,8 +2239,7 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf) if (*p == ',') p++; len = strtoull(p, NULL, 16); -if (target_memory_rw_debug(ENV_GET_CPU(s->g_cpu), addr, mem_buf, len, - false) != 0) { +if (target_memory_rw_debug(s->g_cpu, addr, mem_buf, len, false) != 0) { put_packet (s, "E14"); } else { memtohex(buf, mem_buf, len); @@ -2257,7 +2254,7 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf) if (*p == ':') p++; hextomem(mem_buf, p, len); -if (target_memory_rw_debug(ENV_GET_CPU(s->g_cpu), addr, mem_buf, len, +if (target_memory_rw_debug(s->g_cpu, addr, mem_buf, len, true) != 0) { put_packet(s, "E14"); } else { @@ -2271,7 +2268,7 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf) if (!gdb_has_xml) goto unknown_command; addr = strtoull(p, (char **)&p, 16); -reg_size = gdb_read_register(ENV_GET_CPU(s->g_cpu), mem_buf, addr); +reg_size = gdb_read_register(s->g_cpu, mem_buf, addr); if (reg_size) { memtohex(buf, mem_buf, reg_size); put_packet(s, buf); @@ -2287,7 +2284,7 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf) p++; reg_size = strlen(p) / 2; hextomem(mem_buf, p, reg_size); -gdb_write_register(ENV_GET_CPU(s->g_cpu), mem_buf, addr); +gdb_write_register(s->g_cpu, mem_buf, addr); put_packet(s, "OK"); break; case 'Z': @@ -2328,7 +2325,7 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf) put_packet(s, "OK"); break; case 'g': -s->g_cpu = cpu->env_ptr; +s->g_cpu = cpu; put_packet(s, "OK"); break; default: @@ -2494,10 +2491,8 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf) void gdb_set_stop_cpu(CPUState *cpu) { -CPUArchState *env = cpu->env_ptr; - gdbserver_state->c_cpu = cpu; -gdbserver_state->g_cpu = env; +gdbserver_state->g_cpu = cpu; } #ifndef CONFIG_USER_ONLY @@ -2853,7 +2848,7 @@ static void gdb_accept(void) s = g_malloc0(sizeof(GDBState)); s->c_cpu = first_cpu; -s->g_cpu = first_cpu->env_ptr; +s->g_cpu = first_cpu; s->fd = fd; gdb_has_xml = 0; @@ -3038,7 +3033,7 @@ int gdbserver_start(const char *device) memset(s, 0, sizeof(GDBState)); } s->c_cpu = first_cpu; -s->g_cpu = first_cpu->env_ptr; +s->g_cpu = first_cpu; s->chr = chr; s->state = chr ? RS_IDLE : RS_INACTIVE; s->mon_chr = mon_chr; -- 1.8.1.4
[Qemu-devel] [PATCH RFC qom-cpu 40/41] gdbstub: Move num_g_regs to CPUState and NUM_CORE_REGS to CPUClass
As a side effect this should fix coprocessor register numbering for SMP. Signed-off-by: Andreas Färber --- gdbstub.c | 80 ++--- include/qom/cpu.h | 3 ++ qom/cpu.c | 9 + target-alpha/cpu.c | 1 + target-arm/cpu.c| 1 + target-cris/cpu.c | 2 ++ target-i386/cpu.c | 1 + target-lm32/cpu.c | 1 + target-m68k/cpu.c | 1 + target-microblaze/cpu.c | 1 + target-mips/cpu.c | 2 ++ target-openrisc/cpu.c | 1 + target-ppc/translate_init.c | 2 ++ target-s390x/cpu.c | 1 + target-sh4/cpu.c| 1 + target-sparc/cpu.c | 6 target-xtensa/cpu.c | 3 ++ target-xtensa/helper.c | 8 + 18 files changed, 61 insertions(+), 63 deletions(-) diff --git a/gdbstub.c b/gdbstub.c index d08cfd3..1a827c2 100644 --- a/gdbstub.c +++ b/gdbstub.c @@ -530,8 +530,6 @@ static const int gpr_map[16] = { #endif static const int gpr_map32[8] = { 0, 1, 2, 3, 4, 5, 6, 7 }; -#define NUM_CORE_REGS (CPU_NB_REGS * 2 + 25) - #define IDX_IP_REG CPU_NB_REGS #define IDX_FLAGS_REG (IDX_IP_REG + 1) #define IDX_SEG_REGS(IDX_FLAGS_REG + 1) @@ -702,7 +700,6 @@ static int cpu_gdb_write_register(CPUX86State *env, uint8_t *mem_buf, int n) historical mishap the FP registers appear in between core integer regs and PC, MSR, CR, and so forth. We hack round this by giving the FP regs zero size when talking to a newer gdb. */ -#define NUM_CORE_REGS 71 #if defined (TARGET_PPC64) #define GDB_CORE_XML "power64-core.xml" #else @@ -796,12 +793,6 @@ static int cpu_gdb_write_register(CPUPPCState *env, uint8_t *mem_buf, int n) #elif defined (TARGET_SPARC) -#if defined(TARGET_SPARC64) && !defined(TARGET_ABI32) -#define NUM_CORE_REGS 86 -#else -#define NUM_CORE_REGS 72 -#endif - #ifdef TARGET_ABI32 #define GET_REGA(val) GET_REG32(val) #else @@ -948,7 +939,6 @@ static int cpu_gdb_write_register(CPUSPARCState *env, uint8_t *mem_buf, int n) the FPA registers appear in between core integer regs and the CPSR. We hack round this by giving the FPA regs zero size when talking to a newer gdb. */ -#define NUM_CORE_REGS 26 #define GDB_CORE_XML "arm-core.xml" static int cpu_gdb_read_register(CPUARMState *env, uint8_t *mem_buf, int n) @@ -1017,8 +1007,6 @@ static int cpu_gdb_write_register(CPUARMState *env, uint8_t *mem_buf, int n) #elif defined (TARGET_M68K) -#define NUM_CORE_REGS 18 - #define GDB_CORE_XML "cf-core.xml" static int cpu_gdb_read_register(CPUM68KState *env, uint8_t *mem_buf, int n) @@ -1063,8 +1051,6 @@ static int cpu_gdb_write_register(CPUM68KState *env, uint8_t *mem_buf, int n) } #elif defined (TARGET_MIPS) -#define NUM_CORE_REGS 73 - static int cpu_gdb_read_register(CPUMIPSState *env, uint8_t *mem_buf, int n) { if (n < 32) { @@ -1165,8 +1151,6 @@ static int cpu_gdb_write_register(CPUMIPSState *env, uint8_t *mem_buf, int n) } #elif defined(TARGET_OPENRISC) -#define NUM_CORE_REGS (32 + 3) - static int cpu_gdb_read_register(CPUOpenRISCState *env, uint8_t *mem_buf, int n) { if (n < 32) { @@ -1195,9 +1179,10 @@ static int cpu_gdb_read_register(CPUOpenRISCState *env, uint8_t *mem_buf, int n) static int cpu_gdb_write_register(CPUOpenRISCState *env, uint8_t *mem_buf, int n) { +CPUClass *cc = CPU_GET_CLASS(openrisc_env_get_cpu(env)); uint32_t tmp; -if (n > NUM_CORE_REGS) { +if (n > cc->gdb_num_core_regs) { return 0; } @@ -1230,8 +1215,6 @@ static int cpu_gdb_write_register(CPUOpenRISCState *env, /* Hint: Use "set architecture sh4" in GDB to see fpu registers */ /* FIXME: We should use XML for this. */ -#define NUM_CORE_REGS 59 - static int cpu_gdb_read_register(CPUSH4State *env, uint8_t *mem_buf, int n) { switch (n) { @@ -1347,8 +1330,6 @@ static int cpu_gdb_write_register(CPUSH4State *env, uint8_t *mem_buf, int n) } #elif defined (TARGET_MICROBLAZE) -#define NUM_CORE_REGS (32 + 5) - static int cpu_gdb_read_register(CPUMBState *env, uint8_t *mem_buf, int n) { if (n < 32) { @@ -1361,10 +1342,12 @@ static int cpu_gdb_read_register(CPUMBState *env, uint8_t *mem_buf, int n) static int cpu_gdb_write_register(CPUMBState *env, uint8_t *mem_buf, int n) { +CPUClass *cc = CPU_GET_CLASS(mb_env_get_cpu(env)); uint32_t tmp; -if (n > NUM_CORE_REGS) +if (n > cc->gdb_num_core_regs) { return 0; +} tmp = ldl_p(mem_buf); @@ -1377,8 +1360,6 @@ static int cpu_gdb_write_register(CPUMBState *env, uint8_t *mem_buf, int n) } #elif defined (TARGET_CRIS) -#define NUM_CORE_REGS 49 - static int read_register_crisv10(CPUCRISState *env, uint8_t *mem_buf, int n) { @@ -1473,8 +1454,6 @@ static int cpu_gdb_write_register(CPUCRISState *env, uint8_t *mem_buf, int n) } #elif defined (TARGET_ALPHA) -#define NUM_CORE_REGS 67 - stati
Re: [Qemu-devel] [PATCH] RFCv3 kvm irqfd: support msimessage to irq translation in PHB
On 06/30/2013 12:28 AM, Anthony Liguori wrote: > On Sat, Jun 29, 2013 at 8:45 AM, Alexey Kardashevskiy wrote: >> On PPC64 systems MSI Messages are translated to system IRQ in a PCI >> host bridge. This is already supported for emulated MSI/MSIX but >> not for irqfd where the current QEMU allocates IRQ numbers from >> irqchip and maps MSIMessages to those IRQ in the host kernel. >> >> The patch extends irqfd support in order to avoid unnecessary >> mapping and reuse the one which already exists in a PCI host bridge. >> >> Specifically, a map_msi callback is added to PCIBus and pci_bus_map_msi() >> to PCI API. The latter returns -1 if a specific PHB does not provide >> with any trsnslation so the existing code will work. > > I think there's a bit of confusion here. The kernel needs a "virq" > number to create an eventfd. virq is just a KVM concept, it doesn't > correspond to anything useful in hardware. Yes, it does not. But... There is a global IRQ number space and PHBs convert MSIMessage to global IRQ, this is what our real hardware does on a ppc64-pseries host (if I do not confuse things again). And I am trying to follow the same principle here too. > On pseries, there is a 1-1 mapping between XICS IRQs and VIRQs and MSI > can be trivially mapped to a virq. > On x86, we need to call a special kernel function which essentially > creates an apic message->virq mapping such that we can deliver the > irqfd. > > So what this should look like is: > > 1) A PCI bus function to do the MSI -> virq mapping > 2) On x86 (and e500), this is implemented by calling > kvm_irqchip_add_msi_route() > 3) On pseries, this just returns msi->data > > Perhaps (2) can just be the default PCI bus implementation to simplify things. hw/pci/pci.c does not have any kvm code yet and I would like not to be the first person who tries adding this there :) But ok, I'll do it. >> Signed-off-by: Alexey Kardashevskiy >> >> --- >> >> Looks like we agreed that in general PHB is the right place for this, >> not KVM, so I am trying again. >> >> Probably something should be done to kvm_irqchip_update_msi_route() >> as well but I do not really understand what exactly. Any suggestions? >> >> >> --- >> hw/misc/vfio.c |7 +-- >> hw/pci/pci.c | 13 + >> hw/ppc/spapr_pci.c |6 ++ >> hw/virtio/virtio-pci.c |2 +- >> include/hw/pci/pci.h |4 >> include/hw/pci/pci_bus.h |1 + >> include/sysemu/kvm.h |2 +- >> kvm-all.c|7 ++- >> 8 files changed, 37 insertions(+), 5 deletions(-) >> >> diff --git a/hw/misc/vfio.c b/hw/misc/vfio.c >> index 52fb036..59911bb 100644 >> --- a/hw/misc/vfio.c >> +++ b/hw/misc/vfio.c >> @@ -624,7 +624,9 @@ static int vfio_msix_vector_do_use(PCIDevice *pdev, >> unsigned int nr, >> * Attempt to enable route through KVM irqchip, >> * default to userspace handling if unavailable. >> */ >> -vector->virq = msg ? kvm_irqchip_add_msi_route(kvm_state, *msg) : -1; >> + >> +vector->virq = msg ? >> +kvm_irqchip_add_msi_route(kvm_state, vdev->pdev.bus, *msg) : -1; > > This is wrong. You could call the bus function to map an MSI message > to a virq here. > >> if (vector->virq < 0 || >> kvm_irqchip_add_irqfd_notifier(kvm_state, &vector->interrupt, >> vector->virq) < 0) { >> @@ -792,7 +794,8 @@ retry: >> * Attempt to enable route through KVM irqchip, >> * default to userspace handling if unavailable. >> */ >> -vector->virq = kvm_irqchip_add_msi_route(kvm_state, msg); >> +vector->virq = kvm_irqchip_add_msi_route(kvm_state, vdev->pdev.bus, >> + msg); > > And here. > >> if (vector->virq < 0 || >> kvm_irqchip_add_irqfd_notifier(kvm_state, &vector->interrupt, >> vector->virq) < 0) { >> diff --git a/hw/pci/pci.c b/hw/pci/pci.c >> index 61b681a..543f172 100644 >> --- a/hw/pci/pci.c >> +++ b/hw/pci/pci.c >> @@ -1240,6 +1240,19 @@ void pci_device_set_intx_routing_notifier(PCIDevice >> *dev, >> dev->intx_routing_notifier = notifier; >> } >> >> +void pci_bus_set_map_msi_fn(PCIBus *bus, pci_map_msi_fn map_msi_fn) >> +{ >> +bus->map_msi = map_msi_fn; >> +} > > You don't need this function. You can do this overloading as part of > the PCI bus initialization in spapr_pci.c pci_bus_set_route_irq_fn is there already and I tried to follow the existing pattern (yeah, missed assert though). Or this is different? > > Regards, > > Anthony Liguori > >> +int pci_bus_map_msi(PCIBus *bus, MSIMessage msg) >> +{ >> +if (bus->map_msi) { >> +return bus->map_msi(bus, msg); >> +} >> +return -1; >> +} >> + >> /* >> * PCI-to-PCI bridge specification >> * 9.1: Interrupt routing. Table 9-1 >> diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c >> index 23db
Re: [Qemu-devel] [PATCH v4 07/10] qemu-ga: Add Windows VSS requester to quiesce applications and filesystems
On 6/28/13 14:01 , "Laszlo Ersek" wrote: >On 06/06/13 17:06, Tomoki Sekiyama wrote: > >> diff --git a/qga/vss-win32-requester.h b/qga/vss-win32-requester.h >> new file mode 100644 >> index 000..f180f56 >> --- /dev/null >> +++ b/qga/vss-win32-requester.h ... >>+HRESULT vss_init(void); > >Can you include the mingw header that defines the HRESULT type? As far >as I know we like to make headers standalone. I will make the return type gboolean, that represent if it is successful or not. It is used only in main.c, as 'if (FAILED(vss_init())) { ...'. >(OTOH I vaguely recall a patch where the order between a mingw header >and a (generated?) trace header could cause a build error... I think it >would be worth trying still.) > >> +void vss_deinit(void); >> +int vss_initialized(void); > >Since this is qemu-ga / qemu code, I think a "bool" return type would be >more usual. (The current prototype is correct too of course.) Will use gboolean here as well. >> +void qga_vss_fsfreeze_freeze(int *nr_volume, struct Error **err); >> +void qga_vss_fsfreeze_thaw(int *nr_volume, struct Error **err); > >Can you drop the "struct" word in these prototypes? Ok, I will also add a header for definition for "Error" (qapi/error.h). >> diff --git a/qga/vss-win32-requester.cpp b/qga/vss-win32-requester.cpp >> new file mode 100644 >> index 000..7784926 >> --- /dev/null >> +++ b/qga/vss-win32-requester.cpp ... >> +#include >> +#include > >Can you remove this #include and replace all assert() occurrences with >g_assert()? Sure. >> +static t_CreateVssBackupComponents _CreateVssBackupComponents; >> +static t_VssFreeSnapshotProperties _VssFreeSnapshotProperties; > >I apologize in advance for splitting hairs, but :) > > 17.4.3.1.2 Global names [lib.global.names]; p1 > > Certain sets of names and function signatures are always reserved to > the implementation: > > - Each name that contains a double underscore (__) or begins with an >underscore followed by an uppercase letter (2.11) is reserved to the >implementation for any use. > >Unless there's a pressing reason, could you drop the leading >underscores? Oh, I didn't know that. Without underscores, they conflict with function declared in the MinGW header. Maybe pCreateVssBackupComponents? >Can you decorate each of these static variables with a short comment? It >does get clear(er) what they are used for by reading the code, but the >comments would save others time. All right. >Also I'd recommend grouping them differently: > >- first group: long term objects related to VSSAPI.DLL and released > *only* in vss_deinit(): hLib, _CreateVssBackupComponents, > _VssFreeSnapshotProperties; > >- second group: objects that make sense only in preparation for, during, > and right after a freeze: pVssbc, pAsyncSnapshot, hEvent, hEvent2, > cFrozenVols. (You could even introduce a struct for these, but that's > just an idea.) OK. And making them a struct sounds like a good idea. >> + >> +GCC_FMT_ATTR(1, 2) >> +static void errmsg(const char *fmt, ...) I will remove this; fprintf(stderr,...) is good enough. >> + >> +static void error_set_win32(Error **errp, DWORD err, >> +ErrorClass eclass, const char *text) >> +{ ... >> + >> +/* set error message in UTF-8 encoding */ >> +msg = g_win32_error_message(err); > >Can we pass "err" (which is a HRESULT === DWORD === "long unsigned") to >g_win32_error_message()? The latter takes an "int". > >MSDN seems to imply there are different "error code spaces", see >HRESULT_FROM_WIN32(). Anyway I'll assume we can do this. g_win32_error_message is actually a wrapper for FormatMessage, and FormatMessage actually can handle hresult (at least, in most cases). >> +#define error_setg_win32(errp, err, text) \ >> +error_set_win32(errp, err, ERROR_CLASS_GENERIC_ERROR, text) > >This approach is fine in general for the VSS DLL I think, but for >qemu-ga.exe, I would propose a more flexible interface (could even >belong into "util/error.c", in an #ifdef _WIN32 block). It would imitate >error_setg_errno() in that it allowed the caller to pass in a format >string as well: > >(a) Create a copy of error_set_errno() with "errno"/"strerror" replaced >by "win32"/"g_win32_error_message": ... >(b) error_setg_win32() should imitate error_setg_errno(): ... >This is just a suggestion, but it would bring your code closer to "qemu >coding style", and render free-form error messages more convenient for >you (eg. you could drop the snprintf() stuff in >qga_vss_fsfreeze_freeze()). OK, I will take this way and split this into another patch. >> + >> +#define __chk(status, text, errp, err_label)\ ... >> +#define _chk(status, msg) __chk(status, "Failed to " msg, err, out) >> +#define chk(status) __chk(status, "Failed to " #status, err, out) > >I'd prefer if you hand-expanded these macros in qemu-ga code. The >error_setg_win32() version suggested above should make it easy to format >any error message. You'd have to open-co
[Qemu-devel] [PATCH 02/15] PPC: g3beige: Move secondary IDE bus to mac-io
On a real G3 Beige the secondary IDE bus lives on the mac-io chip, not on some random PCI device. Move it there to become more compatible. While at it, also clean up the IDE channel connection logic. Signed-off-by: Alexander Graf --- v1 -> v2: - fix IRQ mapping --- hw/ide/macio.c| 2 +- hw/misc/macio/macio.c | 95 +-- hw/ppc/mac_oldworld.c | 17 + 3 files changed, 64 insertions(+), 50 deletions(-) diff --git a/hw/ide/macio.c b/hw/ide/macio.c index a1952b0..7a1c573 100644 --- a/hw/ide/macio.c +++ b/hw/ide/macio.c @@ -363,7 +363,7 @@ static void macio_ide_register_types(void) type_register_static(&macio_ide_type_info); } -/* hd_table must contain 4 block drivers */ +/* hd_table must contain 2 block drivers */ void macio_ide_init_drives(MACIOIDEState *s, DriveInfo **hd_table) { int i; diff --git a/hw/misc/macio/macio.c b/hw/misc/macio/macio.c index fd4c8e5..d9971e2 100644 --- a/hw/misc/macio/macio.c +++ b/hw/misc/macio/macio.c @@ -51,11 +51,9 @@ typedef struct OldWorldMacIOState { /*< private >*/ MacIOState parent_obj; /*< public >*/ - -qemu_irq irqs[3]; - +qemu_irq irqs[5]; MacIONVRAMState nvram; -MACIOIDEState ide; +MACIOIDEState ide[2]; } OldWorldMacIOState; #define NEWWORLD_MACIO(obj) \ @@ -147,18 +145,32 @@ static int macio_common_initfn(PCIDevice *d) return 0; } +static int macio_initfn_ide(MacIOState *s, MACIOIDEState *ide, qemu_irq irq0, +qemu_irq irq1, int dmaid) +{ +SysBusDevice *sysbus_dev; + +sysbus_dev = SYS_BUS_DEVICE(ide); +sysbus_connect_irq(sysbus_dev, 0, irq0); +sysbus_connect_irq(sysbus_dev, 1, irq1); +macio_ide_register_dma(ide, s->dbdma, dmaid); +return qdev_init(DEVICE(ide)); +} + static int macio_oldworld_initfn(PCIDevice *d) { MacIOState *s = MACIO(d); OldWorldMacIOState *os = OLDWORLD_MACIO(d); SysBusDevice *sysbus_dev; +int i; +int cur_irq = 0; int ret = macio_common_initfn(d); if (ret < 0) { return ret; } sysbus_dev = SYS_BUS_DEVICE(&s->cuda); -sysbus_connect_irq(sysbus_dev, 0, os->irqs[0]); +sysbus_connect_irq(sysbus_dev, 0, os->irqs[cur_irq++]); ret = qdev_init(DEVICE(&os->nvram)); if (ret < 0) { @@ -174,23 +186,39 @@ static int macio_oldworld_initfn(PCIDevice *d) memory_region_add_subregion(&s->bar, 0x0, s->pic_mem); } -sysbus_dev = SYS_BUS_DEVICE(&os->ide); -sysbus_connect_irq(sysbus_dev, 0, os->irqs[1]); -sysbus_connect_irq(sysbus_dev, 1, os->irqs[2]); -macio_ide_register_dma(&os->ide, s->dbdma, 0x16); -ret = qdev_init(DEVICE(&os->ide)); -if (ret < 0) { -return ret; +/* IDE buses */ +for (i = 0; i < ARRAY_SIZE(os->ide); i++) { +qemu_irq irq0 = os->irqs[cur_irq++]; +qemu_irq irq1 = os->irqs[cur_irq++]; + +ret = macio_initfn_ide(s, &os->ide[i], irq0, irq1, 0x16 + (i * 4)); +if (ret < 0) { +return ret; +} } return 0; } +static void macio_init_ide(MacIOState *s, MACIOIDEState *ide, int index) +{ +gchar *name; + +object_initialize(ide, TYPE_MACIO_IDE); +qdev_set_parent_bus(DEVICE(ide), sysbus_get_default()); +memory_region_add_subregion(&s->bar, 0x1f000 + ((index + 1) * 0x1000), +&ide->mem); +name = g_strdup_printf("ide[%i]", index); +object_property_add_child(OBJECT(s), name, OBJECT(ide), NULL); +g_free(name); +} + static void macio_oldworld_init(Object *obj) { MacIOState *s = MACIO(obj); OldWorldMacIOState *os = OLDWORLD_MACIO(obj); DeviceState *dev; +int i; qdev_init_gpio_out(DEVICE(obj), os->irqs, ARRAY_SIZE(os->irqs)); @@ -199,10 +227,9 @@ static void macio_oldworld_init(Object *obj) qdev_prop_set_uint32(dev, "size", 0x2000); qdev_prop_set_uint32(dev, "it_shift", 4); -object_initialize(&os->ide, TYPE_MACIO_IDE); -qdev_set_parent_bus(DEVICE(&os->ide), sysbus_get_default()); -memory_region_add_subregion(&s->bar, 0x1f000 + (1 * 0x1000), &os->ide.mem); -object_property_add_child(obj, "ide", OBJECT(&os->ide), NULL); +for (i = 0; i < 2; i++) { +macio_init_ide(s, &os->ide[i], i); +} } static int macio_newworld_initfn(PCIDevice *d) @@ -210,35 +237,30 @@ static int macio_newworld_initfn(PCIDevice *d) MacIOState *s = MACIO(d); NewWorldMacIOState *ns = NEWWORLD_MACIO(d); SysBusDevice *sysbus_dev; +int i; +int cur_irq = 0; int ret = macio_common_initfn(d); if (ret < 0) { return ret; } sysbus_dev = SYS_BUS_DEVICE(&s->cuda); -sysbus_connect_irq(sysbus_dev, 0, ns->irqs[0]); +sysbus_connect_irq(sysbus_dev, 0, ns->irqs[cur_irq++]); if (s->pic_mem) { /* OpenPIC */ memory_region_add_subregion(&s->bar, 0x4, s->pic_mem); } -sysbus_dev = SYS_BUS_DEVICE(&ns->ide[0]); -sysbus_
[Qemu-devel] [PATCH 09/15] PPC: dbdma: Introduce kick function
The DBDMA engine really is running all the time, waiting for input. However we don't want to waste cycles constantly polling. So introduce a kick function that data providers can call to notify the DBDMA controller of new input. Signed-off-by: Alexander Graf --- hw/misc/macio/mac_dbdma.c | 5 + include/hw/ppc/mac_dbdma.h | 1 + 2 files changed, 6 insertions(+) diff --git a/hw/misc/macio/mac_dbdma.c b/hw/misc/macio/mac_dbdma.c index c2f15d8..6830a85 100644 --- a/hw/misc/macio/mac_dbdma.c +++ b/hw/misc/macio/mac_dbdma.c @@ -536,6 +536,11 @@ static void DBDMA_run_bh(void *opaque) DBDMA_run(s); } +void DBDMA_kick(DBDMAState *dbdma) +{ +qemu_bh_schedule(dbdma_bh); +} + void DBDMA_register_channel(void *dbdma, int nchan, qemu_irq irq, DBDMA_rw rw, DBDMA_flush flush, void *opaque) diff --git a/include/hw/ppc/mac_dbdma.h b/include/hw/ppc/mac_dbdma.h index 90be5d9..aaeab10 100644 --- a/include/hw/ppc/mac_dbdma.h +++ b/include/hw/ppc/mac_dbdma.h @@ -161,6 +161,7 @@ typedef struct { void DBDMA_register_channel(void *dbdma, int nchan, qemu_irq irq, DBDMA_rw rw, DBDMA_flush flush, void *opaque); +void DBDMA_kick(DBDMAState *dbdma); void* DBDMA_init (MemoryRegion **dbdma_mem); #endif -- 1.8.1.4
[Qemu-devel] [PATCH 01/15] PPC: Mac: Fix guest exported tbfreq values
We can tell the guest the frequency of its time base through fwcfg. However, we tell it a different value from the speed tb actually runs at. Let's fix it and make the tbfreq initialization and the fwcfg exposure use the same values. Signed-off-by: Alexander Graf --- hw/ppc/mac_newworld.c | 5 +++-- hw/ppc/mac_oldworld.c | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/hw/ppc/mac_newworld.c b/hw/ppc/mac_newworld.c index 3badfa3..253089a 100644 --- a/hw/ppc/mac_newworld.c +++ b/hw/ppc/mac_newworld.c @@ -71,6 +71,7 @@ #define MAX_IDE_BUS 2 #define CFG_ADDR 0xf510 +#define TBFREQ (100UL * 1000UL * 1000UL) /* debug UniNorth */ //#define DEBUG_UNIN @@ -191,7 +192,7 @@ static void ppc_core99_init(QEMUMachineInitArgs *args) env = &cpu->env; /* Set time-base frequency to 100 Mhz */ -cpu_ppc_tb_init(env, 100UL * 1000UL * 1000UL); +cpu_ppc_tb_init(env, TBFREQ); qemu_register_reset(ppc_core99_reset, cpu); } @@ -460,7 +461,7 @@ static void ppc_core99_init(QEMUMachineInitArgs *args) fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_KVM_PID, getpid()); #endif } else { -fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_TBFREQ, get_ticks_per_sec()); +fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_TBFREQ, TBFREQ); } /* Mac OS X requires a "known good" clock-frequency value; pass it one. */ fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_CLOCKFREQ, 26600); diff --git a/hw/ppc/mac_oldworld.c b/hw/ppc/mac_oldworld.c index 8faff30..2aab54c 100644 --- a/hw/ppc/mac_oldworld.c +++ b/hw/ppc/mac_oldworld.c @@ -45,6 +45,7 @@ #define MAX_IDE_BUS 2 #define CFG_ADDR 0xf510 +#define TBFREQ 1660UL static int fw_cfg_boot_set(void *opaque, const char *boot_device) { @@ -114,7 +115,7 @@ static void ppc_heathrow_init(QEMUMachineInitArgs *args) env = &cpu->env; /* Set time-base frequency to 16.6 Mhz */ -cpu_ppc_tb_init(env, 1660UL); +cpu_ppc_tb_init(env, TBFREQ); qemu_register_reset(ppc_heathrow_reset, cpu); } @@ -331,7 +332,7 @@ static void ppc_heathrow_init(QEMUMachineInitArgs *args) fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_KVM_PID, getpid()); #endif } else { -fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_TBFREQ, get_ticks_per_sec()); +fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_TBFREQ, TBFREQ); } /* Mac OS X requires a "known good" clock-frequency value; pass it one. */ fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_CLOCKFREQ, 26600); -- 1.8.1.4
[Qemu-devel] [PATCH 00/15] PPC: Mac OS X guest bringup
Recently there has been a lot of progress on the OpenBIOS side to get Mac OS X to boot. For a while now it seemed there was only very little to make it a fully working guest os in QEMU. This patch set is the result of this. With this I can successfully boot Mac OS X 10.2 to 10.4 with the g3beige machine all the way to the GUI. I was not able to boot 10.0 or 10.1, both of which crashed in interrupt controller registration. 10.5 does not include drivers for g3beige anymore. Everything as of 10.6 is x86 only. The mac99 target doesn't look quite as good, but also very close. FWIW only minor issues in our NVRAM layout and via-cuda emulation keep us from using that one. Please don't try to run this with KVM yet. Mac OS X uses mixed mode (half real, half paged) extensively, which happens to break badly in KVM. For reference, here are a few pictures: https://dl.dropboxusercontent.com/u/8976842/Screen%20Shot%202013-06-29%20at%2021.25.38.png https://dl.dropboxusercontent.com/u/8976842/Screen%20Shot%202013-06-29%20at%2005.21.03.png If you want to try this out, please apply the patches on top of my ppc-next queue. Or just use this git repo: git://github.com/agraf/qemu.git macos-v1 Enjoy! Alex Alexander Graf (15): PPC: Mac: Fix guest exported tbfreq values PPC: g3beige: Move secondary IDE bus to mac-io PPC: Macio: Replace tabs with spaces PPC: dbdma: Replace tabs with spaces PPC: Mac: Add debug prints in macio and dbdma code PPC: dbdma: Fix debug print PPC: dbdma: Allow new commands in RUN state PPC: dbdma: Move defines into header file PPC: dbdma: Introduce kick function PPC: dbdma: Move static bh variable to device struct PPC: dbdma: macio: Add DMA callback PPC: dbdma: Move processing to io PPC: dbdma: Wait for DMA until we have data PPC: dbdma: Support unaligned DMA access PPC: Update PPC OpenBIOS hw/ide/macio.c | 232 ++--- hw/misc/macio/mac_dbdma.c | 191 ++--- hw/misc/macio/macio.c | 95 +++ hw/ppc/mac.h | 3 + hw/ppc/mac_newworld.c | 5 +- hw/ppc/mac_oldworld.c | 22 ++--- include/hw/ppc/mac_dbdma.h | 124 pc-bios/openbios-ppc | Bin 733972 -> 1357906 bytes 8 files changed, 465 insertions(+), 207 deletions(-) -- 1.8.1.4
[Qemu-devel] [PATCH 03/15] PPC: Macio: Replace tabs with spaces
s/^I//g on the file. Signed-off-by: Alexander Graf --- hw/ide/macio.c | 8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/hw/ide/macio.c b/hw/ide/macio.c index 7a1c573..82409dc 100644 --- a/hw/ide/macio.c +++ b/hw/ide/macio.c @@ -55,7 +55,7 @@ static void pmac_ide_atapi_transfer_cb(void *opaque, int ret) s->packet_transfer_size -= s->io_buffer_size; s->io_buffer_index += s->io_buffer_size; - s->lba += s->io_buffer_index >> 11; +s->lba += s->io_buffer_index >> 11; s->io_buffer_index &= 0x7ff; } @@ -97,7 +97,7 @@ static void pmac_ide_transfer_cb(void *opaque, int ret) if (ret < 0) { m->aiocb = NULL; qemu_sglist_destroy(&s->sg); - ide_dma_error(s); +ide_dma_error(s); goto done; } @@ -136,11 +136,11 @@ static void pmac_ide_transfer_cb(void *opaque, int ret) switch (s->dma_cmd) { case IDE_DMA_READ: m->aiocb = dma_bdrv_read(s->bs, &s->sg, sector_num, -pmac_ide_transfer_cb, io); + pmac_ide_transfer_cb, io); break; case IDE_DMA_WRITE: m->aiocb = dma_bdrv_write(s->bs, &s->sg, sector_num, - pmac_ide_transfer_cb, io); + pmac_ide_transfer_cb, io); break; case IDE_DMA_TRIM: m->aiocb = dma_bdrv_io(s->bs, &s->sg, sector_num, -- 1.8.1.4
[Qemu-devel] [PATCH 05/15] PPC: Mac: Add debug prints in macio and dbdma code
The macio code is basically undebuggable as it stands today, with no debug prints anywhere whatsoever. DBDMA was better, but I needed a few more to create reasonable logs that tell me where breakage is. Add a DPRINTF macro in the macio source file and add a bunch of debug prints that are all disabled by default of course. Signed-off-by: Alexander Graf --- hw/ide/macio.c| 39 ++- hw/misc/macio/mac_dbdma.c | 12 ++-- 2 files changed, 48 insertions(+), 3 deletions(-) diff --git a/hw/ide/macio.c b/hw/ide/macio.c index 82409dc..5cbc923 100644 --- a/hw/ide/macio.c +++ b/hw/ide/macio.c @@ -30,6 +30,17 @@ #include +/* debug MACIO */ +// #define DEBUG_MACIO + +#ifdef DEBUG_MACIO +#define MACIO_DPRINTF(fmt, ...) \ +do { printf("MACIO: %s: " fmt , __func__, ## __VA_ARGS__); } while (0) +#else +#define MACIO_DPRINTF(fmt, ...) +#endif + + /***/ /* MacIO based PowerPC IDE */ @@ -48,6 +59,8 @@ static void pmac_ide_atapi_transfer_cb(void *opaque, int ret) goto done; } +MACIO_DPRINTF("io_buffer_size = %#x\n", s->io_buffer_size); + if (s->io_buffer_size > 0) { m->aiocb = NULL; qemu_sglist_destroy(&s->sg); @@ -59,15 +72,22 @@ static void pmac_ide_atapi_transfer_cb(void *opaque, int ret) s->io_buffer_index &= 0x7ff; } -if (s->packet_transfer_size <= 0) +/* end of transfer ? */ +if (s->packet_transfer_size <= 0) { +MACIO_DPRINTF("end of transfer\n"); ide_atapi_cmd_ok(s); +} +/* end of DMA ? */ if (io->len == 0) { +MACIO_DPRINTF("end of DMA\n"); goto done; } /* launch next transfer */ +MACIO_DPRINTF("io->len = %#x\n", io->len); + s->io_buffer_size = io->len; qemu_sglist_init(&s->sg, io->len / MACIO_PAGE_SIZE + 1, @@ -76,12 +96,17 @@ static void pmac_ide_atapi_transfer_cb(void *opaque, int ret) io->addr += io->len; io->len = 0; +MACIO_DPRINTF("sector_num=%d size=%d, cmd_cmd=%d\n", + (s->lba << 2) + (s->io_buffer_index >> 9), + s->packet_transfer_size, s->dma_cmd); + m->aiocb = dma_bdrv_read(s->bs, &s->sg, (int64_t)(s->lba << 2) + (s->io_buffer_index >> 9), pmac_ide_atapi_transfer_cb, io); return; done: +MACIO_DPRINTF("done DMA\n"); bdrv_acct_done(s->bs, &s->acct); io->dma_end(opaque); } @@ -95,6 +120,7 @@ static void pmac_ide_transfer_cb(void *opaque, int ret) int64_t sector_num; if (ret < 0) { +MACIO_DPRINTF("DMA error\n"); m->aiocb = NULL; qemu_sglist_destroy(&s->sg); ide_dma_error(s); @@ -102,6 +128,7 @@ static void pmac_ide_transfer_cb(void *opaque, int ret) } sector_num = ide_get_sector(s); +MACIO_DPRINTF("io_buffer_size = %#x\n", s->io_buffer_size); if (s->io_buffer_size > 0) { m->aiocb = NULL; qemu_sglist_destroy(&s->sg); @@ -113,12 +140,14 @@ static void pmac_ide_transfer_cb(void *opaque, int ret) /* end of transfer ? */ if (s->nsector == 0) { +MACIO_DPRINTF("end of transfer\n"); s->status = READY_STAT | SEEK_STAT; ide_set_irq(s->bus); } /* end of DMA ? */ if (io->len == 0) { +MACIO_DPRINTF("end of DMA\n"); goto done; } @@ -127,12 +156,18 @@ static void pmac_ide_transfer_cb(void *opaque, int ret) s->io_buffer_index = 0; s->io_buffer_size = io->len; + +MACIO_DPRINTF("io->len = %#x\n", io->len); + qemu_sglist_init(&s->sg, io->len / MACIO_PAGE_SIZE + 1, &address_space_memory); qemu_sglist_add(&s->sg, io->addr, io->len); io->addr += io->len; io->len = 0; +MACIO_DPRINTF("sector_num=%" PRId64 " n=%d, nsector=%d, cmd_cmd=%d\n", + sector_num, n, s->nsector, s->dma_cmd); + switch (s->dma_cmd) { case IDE_DMA_READ: m->aiocb = dma_bdrv_read(s->bs, &s->sg, sector_num, @@ -162,6 +197,8 @@ static void pmac_ide_transfer(DBDMA_io *io) MACIOIDEState *m = io->opaque; IDEState *s = idebus_active_if(&m->bus); +MACIO_DPRINTF("\n", __LINE__); + s->io_buffer_size = 0; if (s->drive_kind == IDE_CD) { bdrv_acct_start(s->bs, &s->acct, io->len, BDRV_ACCT_READ); diff --git a/hw/misc/macio/mac_dbdma.c b/hw/misc/macio/mac_dbdma.c index ab174f5..903604d 100644 --- a/hw/misc/macio/mac_dbdma.c +++ b/hw/misc/macio/mac_dbdma.c @@ -233,6 +233,7 @@ static void conditional_interrupt(DBDMA_channel *ch) return; case INTR_ALWAYS: /* always interrupt */ qemu_irq_raise(ch->irq); +DBDMA_DPRINTF("conditional_interrupt: raise\n"); return; } @@ -245,12 +246,16 @@ static void conditional_interrupt(DBDMA_channel *ch) switch(intr) { case INTR_IFSET: /* intr if condition bit
[Qemu-devel] [PATCH 06/15] PPC: dbdma: Fix debug print
There was a debug print that didn't compile for me because the format and the arguments weren't in sync. Fix it up. Signed-off-by: Alexander Graf --- hw/misc/macio/mac_dbdma.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/hw/misc/macio/mac_dbdma.c b/hw/misc/macio/mac_dbdma.c index 903604d..fb4cf23 100644 --- a/hw/misc/macio/mac_dbdma.c +++ b/hw/misc/macio/mac_dbdma.c @@ -720,7 +720,8 @@ static void dbdma_write(void *opaque, hwaddr addr, DBDMA_channel *ch = &s->channels[channel]; int reg = (addr - (channel << DBDMA_CHANNEL_SHIFT)) >> 2; -DBDMA_DPRINTF("writel 0x" TARGET_FMT_plx " <= 0x%08x\n", addr, value); +DBDMA_DPRINTF("writel 0x" TARGET_FMT_plx " <= 0x%08"PRIx64"\n", + addr, value); DBDMA_DPRINTF("channel 0x%x reg 0x%x\n", (uint32_t)addr >> DBDMA_CHANNEL_SHIFT, reg); -- 1.8.1.4
[Qemu-devel] [PATCH 14/15] PPC: dbdma: Support unaligned DMA access
The DBDMA engine really just reads bytes from a producing device (IDE in our case) and shoves these bytes into memory. It doesn't care whether any alignment takes place or not. Our code today however assumes that block accesses always happen on sector (512 byte) boundaries. This is a fair assumption for most cases. However, Mac OS X really likes to do unaligned, incomplete accesses that it finishes with the next DMA request. So we need to read / write the unaligned bits independent of the actual asynchronous request, because that one can only handle 512-byte-aligned data. We also need to cache these unaligned sectors until the next DMA request, at which point the data might be successfully flushed from the pipe. Signed-off-by: Alexander Graf --- hw/ide/macio.c | 128 ++--- include/hw/ppc/mac_dbdma.h | 3 ++ 2 files changed, 124 insertions(+), 7 deletions(-) diff --git a/hw/ide/macio.c b/hw/ide/macio.c index 095e1f1..202df06 100644 --- a/hw/ide/macio.c +++ b/hw/ide/macio.c @@ -51,11 +51,13 @@ static void pmac_ide_atapi_transfer_cb(void *opaque, int ret) DBDMA_io *io = opaque; MACIOIDEState *m = io->opaque; IDEState *s = idebus_active_if(&m->bus); +int unaligned; if (ret < 0) { m->aiocb = NULL; qemu_sglist_destroy(&s->sg); ide_atapi_io_error(s, ret); +io->remainder_len = 0; goto done; } @@ -80,8 +82,30 @@ static void pmac_ide_atapi_transfer_cb(void *opaque, int ret) s->io_buffer_index &= 0x7ff; } +s->io_buffer_size = io->len; + +MACIO_DPRINTF("remainder: %d io->len: %d size: %d\n", io->remainder_len, + io->len, s->packet_transfer_size); +if (io->remainder_len && io->len) { +/* guest wants the rest of its previous transfer */ +int remainder_len = MIN(io->remainder_len, io->len); + +MACIO_DPRINTF("copying remainder %d bytes\n", remainder_len); + +cpu_physical_memory_write(io->addr, io->remainder + 0x200 - + remainder_len, remainder_len); + +io->addr += remainder_len; +io->len -= remainder_len; +s->io_buffer_size = remainder_len; +io->remainder_len -= remainder_len; +/* treat remainder as individual transfer, start again */ +pmac_ide_atapi_transfer_cb(opaque, 0); +return; +} + /* end of transfer ? */ -if (s->packet_transfer_size <= 0) { +if (!s->packet_transfer_size) { MACIO_DPRINTF("end of transfer\n"); ide_atapi_cmd_ok(s); m->dma_active = false; @@ -95,14 +119,40 @@ static void pmac_ide_atapi_transfer_cb(void *opaque, int ret) /* launch next transfer */ -MACIO_DPRINTF("io->len = %#x\n", io->len); +/* handle unaligned accesses first, get them over with and only do the + remaining bulk transfer using our async DMA helpers */ +unaligned = io->len & 0x1ff; +if (unaligned) { +int sector_num = (s->lba << 2) + (s->io_buffer_index >> 9); +int nsector = io->len >> 9; -s->io_buffer_size = io->len; +MACIO_DPRINTF("precopying unaligned %d bytes to %#lx\n", + unaligned, io->addr + io->len - unaligned); + +bdrv_read(s->bs, sector_num + nsector, io->remainder, 1); +cpu_physical_memory_write(io->addr + io->len - unaligned, + io->remainder, unaligned); + +io->len -= unaligned; +} + +MACIO_DPRINTF("io->len = %#x\n", io->len); qemu_sglist_init(&s->sg, io->len / MACIO_PAGE_SIZE + 1, &address_space_memory); qemu_sglist_add(&s->sg, io->addr, io->len); -io->addr += io->len; +io->addr += s->io_buffer_size; +io->remainder_len = MIN(s->packet_transfer_size - s->io_buffer_size, +(0x200 - unaligned) & 0x1ff); +MACIO_DPRINTF("set remainder to: %d\n", io->remainder_len); + +/* We would read no data from the block layer, thus not get a callback. + Just fake completion manually. */ +if (!io->len) { +pmac_ide_atapi_transfer_cb(opaque, 0); +return; +} + io->len = 0; MACIO_DPRINTF("sector_num=%d size=%d, cmd_cmd=%d\n", @@ -125,14 +175,16 @@ static void pmac_ide_transfer_cb(void *opaque, int ret) DBDMA_io *io = opaque; MACIOIDEState *m = io->opaque; IDEState *s = idebus_active_if(&m->bus); -int n; +int n = 0; int64_t sector_num; +int unaligned; if (ret < 0) { MACIO_DPRINTF("DMA error\n"); m->aiocb = NULL; qemu_sglist_destroy(&s->sg); ide_dma_error(s); +io->remainder_len = 0; goto done; } @@ -155,8 +207,34 @@ static void pmac_ide_transfer_cb(void *opaque, int ret) s->nsector -= n; } +MACIO_DPRINTF("remainder: %d io->len: %d nsector: %d sector_num: %ld\n", + io->remainder_len, io->len, s->nsector, sector
[Qemu-devel] [PATCH 12/15] PPC: dbdma: Move processing to io
Soon we will introduce intermediate processing pauses which will allow the bottom half to restart a DMA request that couldn't be fulfilled yet. For that to work, move the processing variable into the io struct which is what DMA providers work with. Signed-off-by: Alexander Graf --- hw/misc/macio/mac_dbdma.c | 10 ++ include/hw/ppc/mac_dbdma.h | 3 ++- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/hw/misc/macio/mac_dbdma.c b/hw/misc/macio/mac_dbdma.c index 324ac54..91b9eaf 100644 --- a/hw/misc/macio/mac_dbdma.c +++ b/hw/misc/macio/mac_dbdma.c @@ -275,7 +275,9 @@ static void dbdma_end(DBDMA_io *io) conditional_branch(ch); wait: -ch->processing = 0; +/* Indicate that we're ready for a new DMA round */ +ch->io.processing = 0; + if ((ch->regs[DBDMA_STATUS] & RUN) && (ch->regs[DBDMA_STATUS] & ACTIVE)) channel_run(ch); @@ -301,7 +303,7 @@ static void start_output(DBDMA_channel *ch, int key, uint32_t addr, ch->io.is_last = is_last; ch->io.dma_end = dbdma_end; ch->io.is_dma_out = 1; -ch->processing = 1; +ch->io.processing = 1; if (ch->rw) { ch->rw(&ch->io); } @@ -327,7 +329,7 @@ static void start_input(DBDMA_channel *ch, int key, uint32_t addr, ch->io.is_last = is_last; ch->io.dma_end = dbdma_end; ch->io.is_dma_out = 0; -ch->processing = 1; +ch->io.processing = 1; if (ch->rw) { ch->rw(&ch->io); } @@ -525,7 +527,7 @@ static void DBDMA_run(DBDMAState *s) for (channel = 0; channel < DBDMA_CHANNELS; channel++) { DBDMA_channel *ch = &s->channels[channel]; uint32_t status = ch->regs[DBDMA_STATUS]; -if (!ch->processing && (status & RUN) && (status & ACTIVE)) { +if (!ch->io.processing && (status & RUN) && (status & ACTIVE)) { channel_run(ch); } } diff --git a/include/hw/ppc/mac_dbdma.h b/include/hw/ppc/mac_dbdma.h index eb8e0f0..8ad1b6e 100644 --- a/include/hw/ppc/mac_dbdma.h +++ b/include/hw/ppc/mac_dbdma.h @@ -37,6 +37,8 @@ struct DBDMA_io { int is_last; int is_dma_out; DBDMA_end dma_end; +/* DMA is in progress, don't start another one */ +int processing; }; /* @@ -148,7 +150,6 @@ typedef struct DBDMA_channel { DBDMA_rw rw; DBDMA_flush flush; dbdma_cmd current; -int processing; } DBDMA_channel; typedef struct { -- 1.8.1.4
[Qemu-devel] [PATCH 10/15] PPC: dbdma: Move static bh variable to device struct
The DBDMA controller has a bottom half to asynchronously process DMA request queues. This bh was stored as a gross static variable. Move it into the device struct instead. While at it, move all users of it to the new generic kick function. Signed-off-by: Alexander Graf --- hw/misc/macio/mac_dbdma.c | 24 +++- include/hw/ppc/mac_dbdma.h | 1 + 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/hw/misc/macio/mac_dbdma.c b/hw/misc/macio/mac_dbdma.c index 6830a85..324ac54 100644 --- a/hw/misc/macio/mac_dbdma.c +++ b/hw/misc/macio/mac_dbdma.c @@ -54,6 +54,11 @@ /* */ +static DBDMAState *dbdma_from_ch(DBDMA_channel *ch) +{ +return container_of(ch, DBDMAState, channels[ch->channel]); +} + #ifdef DEBUG_DBDMA static void dump_dbdma_cmd(dbdma_cmd *cmd) { @@ -248,7 +253,6 @@ static void conditional_branch(DBDMA_channel *ch) } } -static QEMUBH *dbdma_bh; static void channel_run(DBDMA_channel *ch); static void dbdma_end(DBDMA_io *io) @@ -365,7 +369,7 @@ static void load_word(DBDMA_channel *ch, int key, uint32_t addr, next(ch); wait: -qemu_bh_schedule(dbdma_bh); +DBDMA_kick(dbdma_from_ch(ch)); } static void store_word(DBDMA_channel *ch, int key, uint32_t addr, @@ -403,7 +407,7 @@ static void store_word(DBDMA_channel *ch, int key, uint32_t addr, next(ch); wait: -qemu_bh_schedule(dbdma_bh); +DBDMA_kick(dbdma_from_ch(ch)); } static void nop(DBDMA_channel *ch) @@ -420,7 +424,7 @@ static void nop(DBDMA_channel *ch) conditional_branch(ch); wait: -qemu_bh_schedule(dbdma_bh); +DBDMA_kick(dbdma_from_ch(ch)); } static void stop(DBDMA_channel *ch) @@ -538,7 +542,7 @@ static void DBDMA_run_bh(void *opaque) void DBDMA_kick(DBDMAState *dbdma) { -qemu_bh_schedule(dbdma_bh); +qemu_bh_schedule(dbdma->bh); } void DBDMA_register_channel(void *dbdma, int nchan, qemu_irq irq, @@ -594,10 +598,12 @@ dbdma_control_write(DBDMA_channel *ch) ch->regs[DBDMA_STATUS] = status; -if (status & ACTIVE) -qemu_bh_schedule(dbdma_bh); -if ((status & FLUSH) && ch->flush) +if (status & ACTIVE) { +DBDMA_kick(dbdma_from_ch(ch)); +} +if ((status & FLUSH) && ch->flush) { ch->flush(&ch->io); +} } static void dbdma_write(void *opaque, hwaddr addr, @@ -750,7 +756,7 @@ void* DBDMA_init (MemoryRegion **dbdma_mem) vmstate_register(NULL, -1, &vmstate_dbdma, s); qemu_register_reset(dbdma_reset, s); -dbdma_bh = qemu_bh_new(DBDMA_run_bh, s); +s->bh = qemu_bh_new(DBDMA_run_bh, s); return s; } diff --git a/include/hw/ppc/mac_dbdma.h b/include/hw/ppc/mac_dbdma.h index aaeab10..eb8e0f0 100644 --- a/include/hw/ppc/mac_dbdma.h +++ b/include/hw/ppc/mac_dbdma.h @@ -154,6 +154,7 @@ typedef struct DBDMA_channel { typedef struct { MemoryRegion mem; DBDMA_channel channels[DBDMA_CHANNELS]; +QEMUBH *bh; } DBDMAState; /* Externally callable functions */ -- 1.8.1.4
[Qemu-devel] [PATCH 07/15] PPC: dbdma: Allow new commands in RUN state
The DBDMA controller can not change its command stream while it's actively streaming data, true. But the fact that it's in RUN state doesn't actually indicate anything. It could just as well be in WAIT while in RUN. And then it's legal to change commands. This fixes a real world issue I've encountered with Mac OS X. Signed-off-by: Alexander Graf --- hw/misc/macio/mac_dbdma.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/hw/misc/macio/mac_dbdma.c b/hw/misc/macio/mac_dbdma.c index fb4cf23..566185d 100644 --- a/hw/misc/macio/mac_dbdma.c +++ b/hw/misc/macio/mac_dbdma.c @@ -725,11 +725,11 @@ static void dbdma_write(void *opaque, hwaddr addr, DBDMA_DPRINTF("channel 0x%x reg 0x%x\n", (uint32_t)addr >> DBDMA_CHANNEL_SHIFT, reg); -/* cmdptr cannot be modified if channel is RUN or ACTIVE */ +/* cmdptr cannot be modified if channel is ACTIVE */ -if (reg == DBDMA_CMDPTR_LO && -(ch->regs[DBDMA_STATUS] & (RUN | ACTIVE))) +if (reg == DBDMA_CMDPTR_LO && (ch->regs[DBDMA_STATUS] & ACTIVE)) { return; +} ch->regs[reg] = value; -- 1.8.1.4
[Qemu-devel] [PATCH 13/15] PPC: dbdma: Wait for DMA until we have data
We should only start processing DMA requests when we have data to process. Hold off working through the DMA shuffling until the IDE core told us that it's ready. This is required because the guest can program the DMA engine or the IDE transfer first. Both are legal. Signed-off-by: Alexander Graf --- hw/ide/macio.c | 19 +++ hw/ppc/mac.h | 1 + 2 files changed, 20 insertions(+) diff --git a/hw/ide/macio.c b/hw/ide/macio.c index bd1b972..095e1f1 100644 --- a/hw/ide/macio.c +++ b/hw/ide/macio.c @@ -59,6 +59,14 @@ static void pmac_ide_atapi_transfer_cb(void *opaque, int ret) goto done; } +if (!m->dma_active) { +MACIO_DPRINTF("waiting for data (%#x - %#x - %x)\n", + s->nsector, io->len, s->status); +/* data not ready yet, wait for the channel to get restarted */ +io->processing = 0; +return; +} + MACIO_DPRINTF("io_buffer_size = %#x\n", s->io_buffer_size); if (s->io_buffer_size > 0) { @@ -76,6 +84,7 @@ static void pmac_ide_atapi_transfer_cb(void *opaque, int ret) if (s->packet_transfer_size <= 0) { MACIO_DPRINTF("end of transfer\n"); ide_atapi_cmd_ok(s); +m->dma_active = false; } /* end of DMA ? */ @@ -127,6 +136,14 @@ static void pmac_ide_transfer_cb(void *opaque, int ret) goto done; } +if (!m->dma_active) { +MACIO_DPRINTF("waiting for data (%#x - %#x - %x)\n", + s->nsector, io->len, s->status); +/* data not ready yet, wait for the channel to get restarted */ +io->processing = 0; +return; +} + sector_num = ide_get_sector(s); MACIO_DPRINTF("io_buffer_size = %#x\n", s->io_buffer_size); if (s->io_buffer_size > 0) { @@ -143,6 +160,7 @@ static void pmac_ide_transfer_cb(void *opaque, int ret) MACIO_DPRINTF("end of transfer\n"); s->status = READY_STAT | SEEK_STAT; ide_set_irq(s->bus); +m->dma_active = false; } /* end of DMA ? */ @@ -379,6 +397,7 @@ static void ide_dbdma_start(IDEDMA *dma, IDEState *s, MACIOIDEState *m = container_of(dma, MACIOIDEState, dma); MACIO_DPRINTF("\n", __LINE__); +m->dma_active = true; DBDMA_kick(m->dbdma); } diff --git a/hw/ppc/mac.h b/hw/ppc/mac.h index 27c4ca3..1e578dd 100644 --- a/hw/ppc/mac.h +++ b/hw/ppc/mac.h @@ -133,6 +133,7 @@ typedef struct MACIOIDEState { BlockDriverAIOCB *aiocb; IDEDMA dma; void *dbdma; +bool dma_active; } MACIOIDEState; void macio_ide_init_drives(MACIOIDEState *ide, DriveInfo **hd_table); -- 1.8.1.4
[Qemu-devel] [PATCH 08/15] PPC: dbdma: Move defines into header file
We usually keep struct and constant definitions in header files. Move them there to stay consistent and to make access to fields easier. Signed-off-by: Alexander Graf --- hw/misc/macio/mac_dbdma.c | 117 include/hw/ppc/mac_dbdma.h | 118 + 2 files changed, 118 insertions(+), 117 deletions(-) diff --git a/hw/misc/macio/mac_dbdma.c b/hw/misc/macio/mac_dbdma.c index 566185d..c2f15d8 100644 --- a/hw/misc/macio/mac_dbdma.c +++ b/hw/misc/macio/mac_dbdma.c @@ -54,123 +54,6 @@ /* */ -/* - * DBDMA control/status registers. All little-endian. - */ - -#define DBDMA_CONTROL 0x00 -#define DBDMA_STATUS 0x01 -#define DBDMA_CMDPTR_HI 0x02 -#define DBDMA_CMDPTR_LO 0x03 -#define DBDMA_INTR_SEL0x04 -#define DBDMA_BRANCH_SEL 0x05 -#define DBDMA_WAIT_SEL0x06 -#define DBDMA_XFER_MODE 0x07 -#define DBDMA_DATA2PTR_HI 0x08 -#define DBDMA_DATA2PTR_LO 0x09 -#define DBDMA_RES10x0A -#define DBDMA_ADDRESS_HI 0x0B -#define DBDMA_BRANCH_ADDR_HI 0x0C -#define DBDMA_RES20x0D -#define DBDMA_RES30x0E -#define DBDMA_RES40x0F - -#define DBDMA_REGS16 -#define DBDMA_SIZE(DBDMA_REGS * sizeof(uint32_t)) - -#define DBDMA_CHANNEL_SHIFT 7 -#define DBDMA_CHANNEL_SIZE(1 << DBDMA_CHANNEL_SHIFT) - -#define DBDMA_CHANNELS(0x1000 >> DBDMA_CHANNEL_SHIFT) - -/* Bits in control and status registers */ - -#define RUN0x8000 -#define PAUSE 0x4000 -#define FLUSH 0x2000 -#define WAKE 0x1000 -#define DEAD 0x0800 -#define ACTIVE 0x0400 -#define BT 0x0100 -#define DEVSTAT0x00ff - -/* - * DBDMA command structure. These fields are all little-endian! - */ - -typedef struct dbdma_cmd { -uint16_t req_count; /* requested byte transfer count */ -uint16_t command;/* command word (has bit-fields) */ -uint32_t phy_addr; /* physical data address */ -uint32_t cmd_dep;/* command-dependent field */ -uint16_t res_count; /* residual count after completion */ -uint16_t xfer_status;/* transfer status */ -} dbdma_cmd; - -/* DBDMA command values in command field */ - -#define COMMAND_MASK0xf000 -#define OUTPUT_MORE 0x/* transfer memory data to stream */ -#define OUTPUT_LAST 0x1000/* ditto followed by end marker */ -#define INPUT_MORE 0x2000/* transfer stream data to memory */ -#define INPUT_LAST 0x3000/* ditto, expect end marker */ -#define STORE_WORD 0x4000/* write word (4 bytes) to device reg */ -#define LOAD_WORD 0x5000/* read word (4 bytes) from device reg */ -#define DBDMA_NOP 0x6000/* do nothing */ -#define DBDMA_STOP 0x7000/* suspend processing */ - -/* Key values in command field */ - -#define KEY_MASK0x0700 -#define KEY_STREAM0 0x/* usual data stream */ -#define KEY_STREAM1 0x0100/* control/status stream */ -#define KEY_STREAM2 0x0200/* device-dependent stream */ -#define KEY_STREAM3 0x0300/* device-dependent stream */ -#define KEY_STREAM4 0x0400/* reserved */ -#define KEY_REGS0x0500/* device register space */ -#define KEY_SYSTEM 0x0600/* system memory-mapped space */ -#define KEY_DEVICE 0x0700/* device memory-mapped space */ - -/* Interrupt control values in command field */ - -#define INTR_MASK 0x0030 -#define INTR_NEVER 0x/* don't interrupt */ -#define INTR_IFSET 0x0010/* intr if condition bit is 1 */ -#define INTR_IFCLR 0x0020/* intr if condition bit is 0 */ -#define INTR_ALWAYS 0x0030/* always interrupt */ - -/* Branch control values in command field */ - -#define BR_MASK 0x000c -#define BR_NEVER0x/* don't branch */ -#define BR_IFSET0x0004/* branch if condition bit is 1 */ -#define BR_IFCLR0x0008/* branch if condition bit is 0 */ -#define BR_ALWAYS 0x000c/* always branch */ - -/* Wait control values in command field */ - -#define WAIT_MASK 0x0003 -#define WAIT_NEVER 0x/* don't wait */ -#define WAIT_IFSET 0x0001/* wait if condition bit is 1 */ -#define WAIT_IFCLR 0x0002/* wait if condition bit is 0 */ -#define WAIT_ALWAYS 0x0003/* always wait */ - -typedef struct DBDMA_channel { -int channel; -uint32_t regs[DBDMA_REGS]; -qemu_irq irq; -DBDMA_io io; -DBDMA_rw rw; -DBDMA_flush flush; -dbdma_cmd current; -int processing; -} DBDMA_channel; - -typedef struct { -MemoryRegion mem; -DBDMA_channel channels[DBDMA_CHANNELS]; -} DBDMAState; - #ifdef DEBUG_DBDMA static void dump_dbdma_cmd(dbdma_cmd *cmd) { diff --git a/include/hw/ppc/mac_dbdma.h b/inc
[Qemu-devel] [PATCH 04/15] PPC: dbdma: Replace tabs with spaces
s/^I//g on the file with a few manual tweaks to align things. Signed-off-by: Alexander Graf --- hw/misc/macio/mac_dbdma.c | 102 +++--- 1 file changed, 51 insertions(+), 51 deletions(-) diff --git a/hw/misc/macio/mac_dbdma.c b/hw/misc/macio/mac_dbdma.c index 2fc7f87..ab174f5 100644 --- a/hw/misc/macio/mac_dbdma.c +++ b/hw/misc/macio/mac_dbdma.c @@ -85,75 +85,75 @@ /* Bits in control and status registers */ -#define RUN0x8000 -#define PAUSE 0x4000 -#define FLUSH 0x2000 -#define WAKE 0x1000 -#define DEAD 0x0800 -#define ACTIVE 0x0400 -#define BT 0x0100 -#define DEVSTAT0x00ff +#define RUN0x8000 +#define PAUSE 0x4000 +#define FLUSH 0x2000 +#define WAKE 0x1000 +#define DEAD 0x0800 +#define ACTIVE 0x0400 +#define BT 0x0100 +#define DEVSTAT0x00ff /* * DBDMA command structure. These fields are all little-endian! */ typedef struct dbdma_cmd { -uint16_t req_count; /* requested byte transfer count */ -uint16_t command;/* command word (has bit-fields) */ -uint32_t phy_addr; /* physical data address */ -uint32_t cmd_dep;/* command-dependent field */ -uint16_t res_count; /* residual count after completion */ -uint16_t xfer_status; /* transfer status */ +uint16_t req_count; /* requested byte transfer count */ +uint16_t command;/* command word (has bit-fields) */ +uint32_t phy_addr; /* physical data address */ +uint32_t cmd_dep;/* command-dependent field */ +uint16_t res_count; /* residual count after completion */ +uint16_t xfer_status;/* transfer status */ } dbdma_cmd; /* DBDMA command values in command field */ #define COMMAND_MASK0xf000 -#define OUTPUT_MORE0x /* transfer memory data to stream */ -#define OUTPUT_LAST0x1000 /* ditto followed by end marker */ -#define INPUT_MORE 0x2000 /* transfer stream data to memory */ -#define INPUT_LAST 0x3000 /* ditto, expect end marker */ -#define STORE_WORD 0x4000 /* write word (4 bytes) to device reg */ -#define LOAD_WORD 0x5000 /* read word (4 bytes) from device reg */ -#define DBDMA_NOP 0x6000 /* do nothing */ -#define DBDMA_STOP 0x7000 /* suspend processing */ +#define OUTPUT_MORE 0x/* transfer memory data to stream */ +#define OUTPUT_LAST 0x1000/* ditto followed by end marker */ +#define INPUT_MORE 0x2000/* transfer stream data to memory */ +#define INPUT_LAST 0x3000/* ditto, expect end marker */ +#define STORE_WORD 0x4000/* write word (4 bytes) to device reg */ +#define LOAD_WORD 0x5000/* read word (4 bytes) from device reg */ +#define DBDMA_NOP 0x6000/* do nothing */ +#define DBDMA_STOP 0x7000/* suspend processing */ /* Key values in command field */ #define KEY_MASK0x0700 -#define KEY_STREAM00x /* usual data stream */ -#define KEY_STREAM10x0100 /* control/status stream */ -#define KEY_STREAM20x0200 /* device-dependent stream */ -#define KEY_STREAM30x0300 /* device-dependent stream */ -#define KEY_STREAM40x0400 /* reserved */ -#define KEY_REGS 0x0500 /* device register space */ -#define KEY_SYSTEM 0x0600 /* system memory-mapped space */ -#define KEY_DEVICE 0x0700 /* device memory-mapped space */ +#define KEY_STREAM0 0x/* usual data stream */ +#define KEY_STREAM1 0x0100/* control/status stream */ +#define KEY_STREAM2 0x0200/* device-dependent stream */ +#define KEY_STREAM3 0x0300/* device-dependent stream */ +#define KEY_STREAM4 0x0400/* reserved */ +#define KEY_REGS0x0500/* device register space */ +#define KEY_SYSTEM 0x0600/* system memory-mapped space */ +#define KEY_DEVICE 0x0700/* device memory-mapped space */ /* Interrupt control values in command field */ #define INTR_MASK 0x0030 -#define INTR_NEVER 0x /* don't interrupt */ -#define INTR_IFSET 0x0010 /* intr if condition bit is 1 */ -#define INTR_IFCLR 0x0020 /* intr if condition bit is 0 */ -#define INTR_ALWAYS0x0030 /* always interrupt */ +#define INTR_NEVER 0x/* don't interrupt */ +#define INTR_IFSET 0x0010/* intr if condition bit is 1 */ +#define INTR_IFCLR 0x0020/* intr if condition bit is 0 */ +#define INTR_ALWAYS 0x0030/* always interrupt */ /* Branch control values in command field */ #define BR_MASK 0x000c -#define BR_NEVER 0x /* don't branch */ -#define BR_IFSET 0x0004 /* branch if condition bit is 1 */ -#define BR_IFCLR 0x0008 /* branch if condition bit is 0 */ -#define BR_ALWAYS 0x000c /* always branch */ +#define BR_NEVER0x/* don't branch */ +#define BR_IFSET
[Qemu-devel] [PATCH 11/15] PPC: dbdma: macio: Add DMA callback
We need to know when the IDE core starts a DMA transfer. Add a notifier function so we have the chance to start transmitting data. Signed-off-by: Alexander Graf --- hw/ide/macio.c | 40 hw/ppc/mac.h | 2 ++ 2 files changed, 42 insertions(+) diff --git a/hw/ide/macio.c b/hw/ide/macio.c index 5cbc923..bd1b972 100644 --- a/hw/ide/macio.c +++ b/hw/ide/macio.c @@ -359,11 +359,50 @@ static void macio_ide_reset(DeviceState *dev) ide_bus_reset(&d->bus); } +static int ide_nop(IDEDMA *dma) +{ +return 0; +} + +static int ide_nop_int(IDEDMA *dma, int x) +{ +return 0; +} + +static void ide_nop_restart(void *opaque, int x, RunState y) +{ +} + +static void ide_dbdma_start(IDEDMA *dma, IDEState *s, +BlockDriverCompletionFunc *cb) +{ +MACIOIDEState *m = container_of(dma, MACIOIDEState, dma); + +MACIO_DPRINTF("\n", __LINE__); +DBDMA_kick(m->dbdma); +} + +static const IDEDMAOps dbdma_ops = { +.start_dma = ide_dbdma_start, +.start_transfer = ide_nop, +.prepare_buf= ide_nop_int, +.rw_buf = ide_nop_int, +.set_unit = ide_nop_int, +.add_status = ide_nop_int, +.set_inactive = ide_nop, +.restart_cb = ide_nop_restart, +.reset = ide_nop, +}; + static void macio_ide_realizefn(DeviceState *dev, Error **errp) { MACIOIDEState *s = MACIO_IDE(dev); ide_init2(&s->bus, s->irq); + +/* Register DMA callbacks */ +s->dma.ops = &dbdma_ops; +s->bus.dma = &s->dma; } static void macio_ide_initfn(Object *obj) @@ -414,6 +453,7 @@ void macio_ide_init_drives(MACIOIDEState *s, DriveInfo **hd_table) void macio_ide_register_dma(MACIOIDEState *s, void *dbdma, int channel) { +s->dbdma = dbdma; DBDMA_register_channel(dbdma, channel, s->dma_irq, pmac_ide_transfer, pmac_ide_flush, s); } diff --git a/hw/ppc/mac.h b/hw/ppc/mac.h index 54efaed..27c4ca3 100644 --- a/hw/ppc/mac.h +++ b/hw/ppc/mac.h @@ -131,6 +131,8 @@ typedef struct MACIOIDEState { MemoryRegion mem; IDEBus bus; BlockDriverAIOCB *aiocb; +IDEDMA dma; +void *dbdma; } MACIOIDEState; void macio_ide_init_drives(MACIOIDEState *ide, DriveInfo **hd_table); -- 1.8.1.4
[Qemu-devel] [PATCH 16/32] ppc: do not register IABR SPR twice for 603e
From: Hervé Poussineau IABR SPR is already registered in gen_spr_603(), called from init_proc_603E(). Signed-off-by: Hervé Poussineau Reviewed-by: Andreas Färber Signed-off-by: Alexander Graf --- target-ppc/translate_init.c | 5 - 1 file changed, 5 deletions(-) diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c index 3811633..f365ad8 100644 --- a/target-ppc/translate_init.c +++ b/target-ppc/translate_init.c @@ -4957,11 +4957,6 @@ static void init_proc_603E (CPUPPCState *env) SPR_NOACCESS, SPR_NOACCESS, &spr_read_generic, &spr_write_generic, 0x); -/* XXX : not implemented */ -spr_register(env, SPR_IABR, "IABR", - SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, - 0x); /* Memory management */ gen_low_BATs(env); gen_6xx_7xx_soft_tlb(env, 64, 2); -- 1.8.1.4
[Qemu-devel] [PATCH 06/32] KVM: PIC: Only commit irq routing when necessary
The current logic updates KVM's view of our interrupt map every time we change it. While this is nice and bullet proof, it slows things down badly for me. QEMU spends about 3 seconds on every start telling KVM what news it has on its routing maps. Instead, let's just synchronize the whole irq routing map as a whole when we're done constructing it. For things that change during runtime, we can still update the routing table on demand. Signed-off-by: Alexander Graf --- hw/i386/kvm/ioapic.c | 1 + include/sysemu/kvm.h | 1 + kvm-all.c| 6 +++--- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/hw/i386/kvm/ioapic.c b/hw/i386/kvm/ioapic.c index a3bd519..abfac3d 100644 --- a/hw/i386/kvm/ioapic.c +++ b/hw/i386/kvm/ioapic.c @@ -40,6 +40,7 @@ void kvm_pc_setup_irq_routing(bool pci_enabled) } } } +kvm_irqchip_commit_routes(s); } } diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h index 0a6e62a..a14cfe9 100644 --- a/include/sysemu/kvm.h +++ b/include/sysemu/kvm.h @@ -230,6 +230,7 @@ int kvm_set_irq(KVMState *s, int irq, int level); int kvm_irqchip_send_msi(KVMState *s, MSIMessage msg); void kvm_irqchip_add_irq_route(KVMState *s, int gsi, int irqchip, int pin); +void kvm_irqchip_commit_routes(KVMState *s); void kvm_put_apic_state(DeviceState *d, struct kvm_lapic_state *kapic); void kvm_get_apic_state(DeviceState *d, struct kvm_lapic_state *kapic); diff --git a/kvm-all.c b/kvm-all.c index 76435f5..c757dd2 100644 --- a/kvm-all.c +++ b/kvm-all.c @@ -985,7 +985,7 @@ void kvm_init_irq_routing(KVMState *s) kvm_arch_init_irq_routing(s); } -static void kvm_irqchip_commit_routes(KVMState *s) +void kvm_irqchip_commit_routes(KVMState *s) { int ret; @@ -1019,8 +1019,6 @@ static void kvm_add_routing_entry(KVMState *s, new->u = entry->u; set_gsi(s, entry->gsi); - -kvm_irqchip_commit_routes(s); } static int kvm_update_routing_entry(KVMState *s, @@ -1171,6 +1169,7 @@ int kvm_irqchip_send_msi(KVMState *s, MSIMessage msg) route->kroute.u.msi.data = le32_to_cpu(msg.data); kvm_add_routing_entry(s, &route->kroute); +kvm_irqchip_commit_routes(s); QTAILQ_INSERT_TAIL(&s->msi_hashtab[kvm_hash_msi(msg.data)], route, entry); @@ -1203,6 +1202,7 @@ int kvm_irqchip_add_msi_route(KVMState *s, MSIMessage msg) kroute.u.msi.data = le32_to_cpu(msg.data); kvm_add_routing_entry(s, &kroute); +kvm_irqchip_commit_routes(s); return virq; } -- 1.8.1.4
[Qemu-devel] [PATCH 26/32] PPC: Fix GDB read on code area for PPC6xx
From: Fabien Chouteau On PPC 6xx, data and code have separated TLBs. Until now QEMU was only looking at data TLBs, which is not good when GDB wants to read code. This patch adds a second call to get_physical_address() with an ACCESS_CODE type of access when the first call with ACCESS_INT fails. Signed-off-by: Fabien Chouteau Signed-off-by: Alexander Graf --- target-ppc/mmu_helper.c | 10 +- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/target-ppc/mmu_helper.c b/target-ppc/mmu_helper.c index 34330dc..385b67a 100644 --- a/target-ppc/mmu_helper.c +++ b/target-ppc/mmu_helper.c @@ -1431,7 +1431,15 @@ hwaddr cpu_get_phys_page_debug(CPUPPCState *env, target_ulong addr) } if (unlikely(get_physical_address(env, &ctx, addr, 0, ACCESS_INT) != 0)) { -return -1; + +/* Some MMUs have separate TLBs for code and data. If we only try an + * ACCESS_INT, we may not be able to read instructions mapped by code + * TLBs, so we also try a ACCESS_CODE. + */ +if (unlikely(get_physical_address(env, &ctx, addr, 0, + ACCESS_CODE) != 0)) { +return -1; +} } return ctx.raddr & TARGET_PAGE_MASK; -- 1.8.1.4
[Qemu-devel] [PATCH 02/32] KVM: Export kvm_init_irq_routing
On PPC, we can have different types of interrupt controllers, so we really only know that we are going to use one when we created it. Export kvm_init_irq_routing() to common code, so that we don't have to call kvm_irqchip_create(). Signed-off-by: Alexander Graf --- include/sysemu/kvm.h | 1 + kvm-all.c| 4 ++-- kvm-stub.c | 4 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h index 24c8e95..0a6e62a 100644 --- a/include/sysemu/kvm.h +++ b/include/sysemu/kvm.h @@ -312,4 +312,5 @@ int kvm_irqchip_add_irqfd_notifier(KVMState *s, EventNotifier *n, int virq); int kvm_irqchip_remove_irqfd_notifier(KVMState *s, EventNotifier *n, int virq); void kvm_pc_gsi_handler(void *opaque, int n, int level); void kvm_pc_setup_irq_routing(bool pci_enabled); +void kvm_init_irq_routing(KVMState *s); #endif diff --git a/kvm-all.c b/kvm-all.c index 82ecebb..a5ab2a3 100644 --- a/kvm-all.c +++ b/kvm-all.c @@ -954,7 +954,7 @@ static void clear_gsi(KVMState *s, unsigned int gsi) s->used_gsi_bitmap[gsi / 32] &= ~(1U << (gsi % 32)); } -static void kvm_init_irq_routing(KVMState *s) +void kvm_init_irq_routing(KVMState *s) { int gsi_count, i; @@ -1242,7 +1242,7 @@ static int kvm_irqchip_assign_irqfd(KVMState *s, int fd, int virq, bool assign) #else /* !KVM_CAP_IRQ_ROUTING */ -static void kvm_init_irq_routing(KVMState *s) +void kvm_init_irq_routing(KVMState *s) { } diff --git a/kvm-stub.c b/kvm-stub.c index 5457fe8..dec7a83 100644 --- a/kvm-stub.c +++ b/kvm-stub.c @@ -122,6 +122,10 @@ int kvm_irqchip_add_msi_route(KVMState *s, MSIMessage msg) return -ENOSYS; } +void kvm_init_irq_routing(KVMState *s) +{ +} + void kvm_irqchip_release_virq(KVMState *s, int virq) { } -- 1.8.1.4
[Qemu-devel] [PATCH 03/32] KVM: MSI: Swap payload to native endianness
The usual MSI injection mechanism writes msi.data into memory using an le32 wrapper. So on big endian guests, this swaps msg.data into the expected byte order. For irqfd however, we don't swap the payload right now, rendering in-kernel MPIC emulation broken on PowerPC. Swap msg.data to the correct endianness whenever we touch it. Signed-off-by: Alexander Graf --- kvm-all.c | 10 +- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/kvm-all.c b/kvm-all.c index a5ab2a3..76435f5 100644 --- a/kvm-all.c +++ b/kvm-all.c @@ -1131,7 +1131,7 @@ static KVMMSIRoute *kvm_lookup_msi_route(KVMState *s, MSIMessage msg) QTAILQ_FOREACH(route, &s->msi_hashtab[hash], entry) { if (route->kroute.u.msi.address_lo == (uint32_t)msg.address && route->kroute.u.msi.address_hi == (msg.address >> 32) && -route->kroute.u.msi.data == msg.data) { +route->kroute.u.msi.data == le32_to_cpu(msg.data)) { return route; } } @@ -1146,7 +1146,7 @@ int kvm_irqchip_send_msi(KVMState *s, MSIMessage msg) if (s->direct_msi) { msi.address_lo = (uint32_t)msg.address; msi.address_hi = msg.address >> 32; -msi.data = msg.data; +msi.data = le32_to_cpu(msg.data); msi.flags = 0; memset(msi.pad, 0, sizeof(msi.pad)); @@ -1168,7 +1168,7 @@ int kvm_irqchip_send_msi(KVMState *s, MSIMessage msg) route->kroute.flags = 0; route->kroute.u.msi.address_lo = (uint32_t)msg.address; route->kroute.u.msi.address_hi = msg.address >> 32; -route->kroute.u.msi.data = msg.data; +route->kroute.u.msi.data = le32_to_cpu(msg.data); kvm_add_routing_entry(s, &route->kroute); @@ -1200,7 +1200,7 @@ int kvm_irqchip_add_msi_route(KVMState *s, MSIMessage msg) kroute.flags = 0; kroute.u.msi.address_lo = (uint32_t)msg.address; kroute.u.msi.address_hi = msg.address >> 32; -kroute.u.msi.data = msg.data; +kroute.u.msi.data = le32_to_cpu(msg.data); kvm_add_routing_entry(s, &kroute); @@ -1220,7 +1220,7 @@ int kvm_irqchip_update_msi_route(KVMState *s, int virq, MSIMessage msg) kroute.flags = 0; kroute.u.msi.address_lo = (uint32_t)msg.address; kroute.u.msi.address_hi = msg.address >> 32; -kroute.u.msi.data = msg.data; +kroute.u.msi.data = le32_to_cpu(msg.data); return kvm_update_routing_entry(s, &kroute); } -- 1.8.1.4
[Qemu-devel] [PATCH 01/32] KVM: Don't assume that mpstate exists with in-kernel PIC always
On PPC, we don't support MP state. So far it's not necessary and I'm not convinced yet that we really need to support it ever. However, the current idle logic in QEMU assumes that an in-kernel PIC also means we support MP state. This assumption is not true anymore. Let's split up the two cases into two different variables. That way PPC can expose an in-kernel PIC, while not implementing MP state. Signed-off-by: Alexander Graf CC: Jan Kiszka --- cpus.c | 2 +- include/sysemu/kvm.h | 10 ++ kvm-all.c| 2 ++ 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/cpus.c b/cpus.c index 86571f9..20958e5 100644 --- a/cpus.c +++ b/cpus.c @@ -71,7 +71,7 @@ static bool cpu_thread_is_idle(CPUState *cpu) return true; } if (!cpu->halted || qemu_cpu_has_work(cpu) || -kvm_async_interrupts_enabled()) { +kvm_halt_in_kernel()) { return false; } return true; diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h index fe8bc40..24c8e95 100644 --- a/include/sysemu/kvm.h +++ b/include/sysemu/kvm.h @@ -42,6 +42,7 @@ extern bool kvm_allowed; extern bool kvm_kernel_irqchip; extern bool kvm_async_interrupts_allowed; +extern bool kvm_halt_in_kernel_allowed; extern bool kvm_irqfds_allowed; extern bool kvm_msi_via_irqfd_allowed; extern bool kvm_gsi_routing_allowed; @@ -73,6 +74,14 @@ extern bool kvm_readonly_mem_allowed; #define kvm_async_interrupts_enabled() (kvm_async_interrupts_allowed) /** + * kvm_halt_in_kernel + * + * Returns: true if halted cpus should still get a KVM_RUN ioctl to run + * inside of kernel space. This only works if MP state is implemented. + */ +#define kvm_halt_in_kernel() (kvm_halt_in_kernel_allowed) + +/** * kvm_irqfds_enabled: * * Returns: true if we can use irqfds to inject interrupts into @@ -110,6 +119,7 @@ extern bool kvm_readonly_mem_allowed; #define kvm_enabled() (0) #define kvm_irqchip_in_kernel() (false) #define kvm_async_interrupts_enabled() (false) +#define kvm_halt_in_kernel() (false) #define kvm_irqfds_enabled() (false) #define kvm_msi_via_irqfd_enabled() (false) #define kvm_gsi_routing_allowed() (false) diff --git a/kvm-all.c b/kvm-all.c index 7a1684e..82ecebb 100644 --- a/kvm-all.c +++ b/kvm-all.c @@ -107,6 +107,7 @@ struct KVMState KVMState *kvm_state; bool kvm_kernel_irqchip; bool kvm_async_interrupts_allowed; +bool kvm_halt_in_kernel_allowed; bool kvm_irqfds_allowed; bool kvm_msi_via_irqfd_allowed; bool kvm_gsi_routing_allowed; @@ -1303,6 +1304,7 @@ static int kvm_irqchip_create(KVMState *s) * interrupt delivery (though the reverse is not necessarily true) */ kvm_async_interrupts_allowed = true; +kvm_halt_in_kernel_allowed = true; kvm_init_irq_routing(s); -- 1.8.1.4
[Qemu-devel] [PULL 00/32] ppc patch queue 2013-06-30
Hi Blue / Aurelien, This is my current patch queue for ppc. Please pull. Alex The following changes since commit ffeec223b55ea696567ed544016824199cd7c7bc: Merge remote-tracking branch 'mjt/trivial-patches' into staging (2013-06-28 15:48:35 -0500) are available in the git repository at: git://github.com/agraf/qemu.git ppc-for-upstream for you to fetch changes up to 0b4f507cd58c554f3bd8c5f4d7ad34cd1d863532: PPC: Ignore writes to L2CR (2013-06-30 03:43:40 +0200) Alexander Graf (12): KVM: Don't assume that mpstate exists with in-kernel PIC always KVM: Export kvm_init_irq_routing KVM: MSI: Swap payload to native endianness KVM: PIC: Only commit irq routing when necessary PPC: Add non-kvm stub file Graphics: Switch to 800x600x32 as default mode PPC: Introduce an alias cache for faster lookups PPC: Add clock-frequency export for Mac machines PPC: Newworld: Add uninorth token register PPC: Newworld: Add second uninorth control register set mac-io: Add escc-legacy memory alias region PPC: Ignore writes to L2CR Alexey Kardashevskiy (1): target-ppc kvm: save cr register Andreas Färber (8): intc/openpic: QOM'ify intc/openpic: Convert to QOM realize intc/openpic_kvm: Fix QOM and build issues mpc8544_guts: Fix MemoryRegion name mpc8544_guts: QOM'ify mpc8544_guts: Turn qdev initfn into instance_init target-ppc: Drop redundant flags assignments from CPU families target-ppc: Introduce unrealizefn for PowerPCCPU Anthony Liguori (1): spapr-rtas: add CPU argument to RTAS calls Bharat Bhushan (1): booke_ppc: limit booke timer to max when timeout overflow David Gibson (2): target-ppc: Change default machine for 64-bit pseries: Update MAINTAINERS information Fabien Chouteau (2): PPC: Add dump_mmu() for 6xx PPC: Fix GDB read on code area for PPC6xx Hervé Poussineau (1): ppc: do not register IABR SPR twice for 603e Scott Wood (3): openpic: factor out some common defines into openpic.h PPC: e500: factor out mpic init code kvm/openpic: in-kernel mpic support Stefan Weil (1): pseries: Fix compiler warning (conversion of pointer to integral value) MAINTAINERS| 5 +- arch_init.c| 2 +- cpus.c | 2 +- default-configs/ppc-softmmu.mak| 1 + default-configs/ppc64-softmmu.mak | 1 + default-configs/ppcemb-softmmu.mak | 1 + hw/i386/kvm/ioapic.c | 1 + hw/intc/Makefile.objs | 1 + hw/intc/openpic.c | 89 +++-- hw/intc/openpic_kvm.c | 264 + hw/misc/macio/macio.c | 47 +++ hw/nvram/spapr_nvram.c | 4 +- hw/ppc/e500.c | 125 ++ hw/ppc/mac_newworld.c | 24 +++- hw/ppc/mac_oldworld.c | 2 + hw/ppc/mpc8544_guts.c | 32 ++--- hw/ppc/ppc_booke.c | 24 +++- hw/ppc/spapr.c | 3 +- hw/ppc/spapr_events.c | 2 +- hw/ppc/spapr_hcall.c | 2 +- hw/ppc/spapr_pci.c | 13 +- hw/ppc/spapr_rtas.c| 21 +-- hw/ppc/spapr_vio.c | 6 +- hw/ppc/xics.c | 12 +- include/hw/ppc/openpic.h | 14 ++ include/hw/ppc/ppc.h | 1 + include/hw/ppc/spapr.h | 5 +- include/sysemu/kvm.h | 12 ++ kvm-all.c | 22 ++-- kvm-stub.c | 4 + target-ppc/Makefile.objs | 1 + target-ppc/cpu-models.c| 2 +- target-ppc/cpu-models.h| 3 +- target-ppc/cpu.h | 4 +- target-ppc/kvm-stub.c | 18 +++ target-ppc/kvm.c | 5 + target-ppc/mmu_helper.c| 102 +- target-ppc/translate_init.c| 120 - 38 files changed, 792 insertions(+), 205 deletions(-) create mode 100644 hw/intc/openpic_kvm.c create mode 100644 target-ppc/kvm-stub.c
[Qemu-devel] [PATCH 12/32] mpc8544_guts: Fix MemoryRegion name
From: Andreas Färber 6544 -> 8544 Signed-off-by: Andreas Färber Signed-off-by: Alexander Graf --- hw/ppc/mpc8544_guts.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/ppc/mpc8544_guts.c b/hw/ppc/mpc8544_guts.c index 193beab..98540a4 100644 --- a/hw/ppc/mpc8544_guts.c +++ b/hw/ppc/mpc8544_guts.c @@ -115,7 +115,7 @@ static int mpc8544_guts_initfn(SysBusDevice *dev) s = FROM_SYSBUS(GutsState, SYS_BUS_DEVICE(dev)); memory_region_init_io(&s->iomem, &mpc8544_guts_ops, s, - "mpc6544.guts", MPC8544_GUTS_MMIO_SIZE); + "mpc8544.guts", MPC8544_GUTS_MMIO_SIZE); sysbus_init_mmio(dev, &s->iomem); return 0; -- 1.8.1.4
[Qemu-devel] [PATCH 29/32] PPC: Newworld: Add uninorth token register
Mac OS X expects the uninorth control register set to contain one register that always reads back what it writes in. Expose that. This is just a temporary hack. Eventually, we want to expose the uninorth (/uni-n in device tree) as a separate QOM device. Signed-off-by: Alexander Graf --- hw/ppc/mac_newworld.c | 13 +++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/hw/ppc/mac_newworld.c b/hw/ppc/mac_newworld.c index c6889d1..7b512ca 100644 --- a/hw/ppc/mac_newworld.c +++ b/hw/ppc/mac_newworld.c @@ -87,6 +87,9 @@ static void unin_write(void *opaque, hwaddr addr, uint64_t value, unsigned size) { UNIN_DPRINTF("write addr " TARGET_FMT_plx " val %"PRIx64"\n", addr, value); +if (addr == 0x0) { +*(int*)opaque = value; +} } static uint64_t unin_read(void *opaque, hwaddr addr, unsigned size) @@ -94,6 +97,11 @@ static uint64_t unin_read(void *opaque, hwaddr addr, unsigned size) uint32_t value; value = 0; +switch (addr) { +case 0: +value = *(int*)opaque; +} + UNIN_DPRINTF("readl addr " TARGET_FMT_plx " val %x\n", addr, value); return value; @@ -162,6 +170,7 @@ static void ppc_core99_init(QEMUMachineInitArgs *args) int machine_arch; SysBusDevice *s; DeviceState *dev; +int *token = g_new(int, 1); linux_boot = (kernel_filename != NULL); @@ -279,8 +288,8 @@ static void ppc_core99_init(QEMUMachineInitArgs *args) /* Register 8 MB of ISA IO space */ isa_mmio_init(0xf200, 0x0080); -/* UniN init */ -memory_region_init_io(unin_memory, &unin_ops, NULL, "unin", 0x1000); +/* UniN init: XXX should be a real device */ +memory_region_init_io(unin_memory, &unin_ops, token, "unin", 0x1000); memory_region_add_subregion(get_system_memory(), 0xf800, unin_memory); openpic_irqs = g_malloc0(smp_cpus * sizeof(qemu_irq *)); -- 1.8.1.4
[Qemu-devel] [PATCH 07/32] PPC: Add non-kvm stub file
There are cases where a kvm provided function is called from generic hw code that doesn't know whether kvm is available or not. Provide a stub file which can provide simple replacement functions for those cases. Signed-off-by: Alexander Graf Reviewed-by: Paolo Bonzini --- target-ppc/Makefile.objs | 1 + target-ppc/kvm-stub.c| 12 2 files changed, 13 insertions(+) create mode 100644 target-ppc/kvm-stub.c diff --git a/target-ppc/Makefile.objs b/target-ppc/Makefile.objs index 2c43c34..6e78cb3 100644 --- a/target-ppc/Makefile.objs +++ b/target-ppc/Makefile.objs @@ -5,6 +5,7 @@ obj-y += machine.o mmu_helper.o mmu-hash32.o obj-$(TARGET_PPC64) += mmu-hash64.o endif obj-$(CONFIG_KVM) += kvm.o kvm_ppc.o +obj-$(CONFIG_NO_KVM) += kvm-stub.o obj-y += excp_helper.o obj-y += fpu_helper.o obj-y += int_helper.o diff --git a/target-ppc/kvm-stub.c b/target-ppc/kvm-stub.c new file mode 100644 index 000..0f5c27d --- /dev/null +++ b/target-ppc/kvm-stub.c @@ -0,0 +1,12 @@ +/* + * QEMU KVM PPC specific function stubs + * + * Copyright Freescale Inc. 2013 + * + * Author: Alexander Graf + * + * 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 "qemu-common.h" -- 1.8.1.4
[Qemu-devel] [PATCH 32/32] PPC: Ignore writes to L2CR
The L2CR register contains a number of bits that either impose configuration which we can't deal with or mean "something is in progress until the bit is 0 again". Since we don't model the former and we do want to accomodate guests using the latter semantics, let's just ignore writes to L2CR. That way guests always read back 0 and are usually happy with that. Signed-off-by: Alexander Graf --- target-ppc/translate_init.c | 22 +++--- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c index 45b4053..ba2ee15 100644 --- a/target-ppc/translate_init.c +++ b/target-ppc/translate_init.c @@ -1381,7 +1381,7 @@ static void gen_spr_74xx (CPUPPCState *env) /* XXX : not implemented */ spr_register(env, SPR_L2CR, "L2CR", SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, + &spr_read_generic, NULL, 0x); /* Not strictly an SPR */ vscr_init(env, 0x0001); @@ -5169,7 +5169,7 @@ static void init_proc_750 (CPUPPCState *env) /* XXX : not implemented */ spr_register(env, SPR_L2CR, "L2CR", SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, + &spr_read_generic, NULL, 0x); /* Time base */ gen_tbl(env); @@ -5232,7 +5232,7 @@ static void init_proc_750cl (CPUPPCState *env) /* XXX : not implemented */ spr_register(env, SPR_L2CR, "L2CR", SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, + &spr_read_generic, NULL, 0x); /* Time base */ gen_tbl(env); @@ -5418,7 +5418,7 @@ static void init_proc_750cx (CPUPPCState *env) /* XXX : not implemented */ spr_register(env, SPR_L2CR, "L2CR", SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, + &spr_read_generic, NULL, 0x); /* Time base */ gen_tbl(env); @@ -5485,7 +5485,7 @@ static void init_proc_750fx (CPUPPCState *env) /* XXX : not implemented */ spr_register(env, SPR_L2CR, "L2CR", SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, + &spr_read_generic, NULL, 0x); /* Time base */ gen_tbl(env); @@ -5557,7 +5557,7 @@ static void init_proc_750gx (CPUPPCState *env) /* XXX : not implemented (XXX: different from 750fx) */ spr_register(env, SPR_L2CR, "L2CR", SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, + &spr_read_generic, NULL, 0x); /* Time base */ gen_tbl(env); @@ -5693,7 +5693,7 @@ static void init_proc_755 (CPUPPCState *env) /* XXX : not implemented */ spr_register(env, SPR_L2CR, "L2CR", SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, + &spr_read_generic, NULL, 0x); /* XXX : not implemented */ spr_register(env, SPR_L2PMCR, "L2PMCR", @@ -6524,7 +6524,7 @@ static void init_proc_970 (CPUPPCState *env) /* XXX : not implemented */ spr_register(env, SPR_L2CR, "L2CR", SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, + &spr_read_generic, NULL, 0x); /* Memory management */ /* XXX: not correct */ @@ -6624,7 +6624,7 @@ static void init_proc_970FX (CPUPPCState *env) /* XXX : not implemented */ spr_register(env, SPR_L2CR, "L2CR", SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, + &spr_read_generic, NULL, 0x); /* Memory management */ /* XXX: not correct */ @@ -6736,7 +6736,7 @@ static void init_proc_970GX (CPUPPCState *env) /* XXX : not implemented */ spr_register(env, SPR_L2CR, "L2CR", SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, + &spr_read_generic, NULL, 0x); /* Memory management */ /* XXX: not correct */ @@ -6836,7 +6836,7 @@ static void init_proc_970MP (CPUPPCState *env) /* XXX : not implemented */ spr_register(env, SPR_L2CR, "L2CR", SPR_NOACCESS, SPR_NOACCESS, - &spr_read_generic, &spr_write_generic, + &spr_read_generic, NULL, 0x); /* Memory management */ /* XXX: not correct */ -- 1.8.1.4