Compare commits

...
126 Commits
Author SHA1 Message Date
Anthony Liguori 8db972cfa4 Update version for 1.2.0
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
2012-09-05 07:50:01 -05:00
Ian Campbell 3eea5498ca console: bounds check whenever changing the cursor due to an escape code
This is XSA-17 / CVE-2012-3515

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
2012-09-04 10:26:17 -05:00
Paolo Bonzini de188751da qemu-timer: properly arm alarm timer for timers set by device initialization
QEMU will hang when fed the following command-line

  qemu-system-mips -kernel vmlinux-2.6.32-5-4kc-malta -append "console=ttyS0" -nographic -net none

The -net none is important otherwise it seems some events are generated
causing the things to work. When it doesn't work, the guest hangs when
measuring the CPU frequency, after the following line:

  [    0.000000] NR_IRQS:256

Pressing a key on the serial port unblocks it, hinting that the problem
is due to the recent elimination of the 1 second timeout in the main
loop.

The problem is that because init_timer_alarm sets the timer's pending
flag to true, the alarm timer is never armed until after the first time
through the main loop.  Thus the bug started when QEMU started testing
the pending flag in qemu_mod_timer (commit 1828be3, more alarm timer
cleanup, 2010-03-10).

But actually, it isn't true at all that a timer is pending when the
alarm timer is created, and the real bug has been latent forever: the
fix is to remove the bogus setting of pending flag.

Reported-by: Aurelien Jarno <aurelien@aurel32.net>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Jan Kiszka <jan.kiszka@siemens.com>
Tested-by: Aurelien Jarno <aurelien@aurel32.net>
Tested-by: Michael Tokarev <mjt@tls.msk.ru>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
2012-09-04 12:30:28 +02:00
Max Filippov e7eee62a90 target-xtensa: return ENOSYS for unimplemented simcalls
This prevents guest from proceeding with uninitialised garbage returned
from unimplemented simcalls.

Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
2012-09-01 10:39:10 +00:00
Anthony Liguori 0232cd355d Update version to 1.2.0-rc3
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
2012-08-31 10:50:46 -05:00
Stefan Weil 8bd6b06d7b console: Fix warning from clang (and potential crash)
ccc-analyzer reports this warning:

console.c:1090:29: warning: Dereference of null pointer
        if (active_console->cursor_timer) {
                            ^

Function console_select allows active_console to be NULL,
but would crash when accessing cursor_timer. Fix this.

Reviewed-by: Jan Kiszka <jan.kiszka@siemens.com>
Signed-off-by: Stefan Weil <sw@weilnetz.de>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
2012-08-31 10:05:22 -05:00
Anthony Liguori 23aec6005a Merge remote-tracking branch 'kraxel/usb.61' into staging
* kraxel/usb.61:
  uas: move transfer kickoff
  ehci: Fix interrupt endpoints no longer working
  ehci: handle TD deactivation of inflight packets
  ehci: add ehci_cancel_queue()
  ehci: simplify ehci_state_executing
  ehci: Remove unnecessary ehci_flush_qh call
  ehci: Schedule async-bh when IAAD bit gets set
  ehci: Fix NULL ptr deref when unplugging an USB dev with an iso stream active
  usb: unique packet ids
  usb: Halt ep queue en cancel pending packets on a packet error
  fix info qtree indention
2012-08-31 10:04:54 -05:00
Anthony Liguori cdedd9d867 Merge remote-tracking branch 'kwolf/for-anthony' into staging
* kwolf/for-anthony:
  qemu-iotests: add backing file smaller than image test case
  stream: complete early if end of backing file is reached
  qed: refuse unaligned zero writes with a backing file
2012-08-31 10:04:18 -05:00
Gerd Hoffmann 347e40ffe6 uas: move transfer kickoff
Kick next scsi transfer from request release callback instead of command
completion callback, otherwise we might get stuck in case scsi_req_unref()
doesn't release the request instantly due to someone else holding a
reference too.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2012-08-31 15:47:57 +02:00
Hans de Goede adf478342b ehci: Fix interrupt endpoints no longer working
One of the recent changes (likely the addition of queuing support) has broken
interrupt endpoints, this patch fixes this.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
2012-08-31 15:47:57 +02:00
Gerd Hoffmann 287fd3f1dd ehci: handle TD deactivation of inflight packets
Check the TDs of inflight packets, cancel
packets in case the guest clears the active bit.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2012-08-31 15:47:35 +02:00
Gerd Hoffmann c7cdca3b85 ehci: add ehci_cancel_queue()
Factor out function to cancel all packets of a queue.
No behavior change.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2012-08-31 12:02:15 +02:00
Hans de Goede 574ef17191 ehci: simplify ehci_state_executing
ehci_state_executing does not need to check for p->usb_status == USB_RET_ASYNC
or USB_RET_PROCERR, since ehci_execute_complete already does a similar check
and will trigger an assert if either value is encountered.

USB_RET_ASYNC should never be the packet status when execute_complete runs
for obvious reasons, and USB_RET_PROCERR is only used by ehci_state_execute /
ehci_execute not by ehci_state_executing / ehci_execute_complete.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2012-08-31 12:02:15 +02:00
Hans de Goede 53dd6f7032 ehci: Remove unnecessary ehci_flush_qh call
ehci_qh_do_overlay() already calls ehci_flush_qh() before it returns, calling
it twice is useless.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2012-08-31 11:58:03 +02:00
Hans de Goede a1c3e4b839 ehci: Schedule async-bh when IAAD bit gets set
After the "ehci: Print a warning when a queue unexpectedly contains packets
on cancel" commit. Under certain reproducable conditions I was getting the
following message: "EHCI: Warning queue not empty on queue reset".

After aprox. 8 hours of debugging I've finally found the cause. The Linux EHCI
driver has an IAAD watchdog, to work around certain EHCI hardware sometimes
not acknowledging the doorbell at all. This watchdog has a timeout of 10 ms,
which is less then the time between 2 runs through the async schedule when
async_stepdown is at its highest value.

Thus the watchdog can trigger, after which Linux clears the IAAD bit and
re-uses the QH. IOW we were not properly detecting the unlink of the qh, due
to us missing (ignoring for more then 10 ms) the IAAD command, which triggered
the warning.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
2012-08-31 11:58:03 +02:00
Hans de Goede 7ce86aa1aa ehci: Fix NULL ptr deref when unplugging an USB dev with an iso stream active
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
2012-08-31 11:57:41 +02:00
Gerd Hoffmann e983395d30 usb: unique packet ids
This patch adds IDs to usb packets.  Those IDs are (a) supposed to be
unique for the lifecycle of a packet (from packet setup until the packet
is either completed or canceled) and (b) stable across migration.

uhci, ohci, ehci and xhci use the guest physical address of the transfer
descriptor for this.

musb needs a different approach because there is no transfer descriptor.
But musb also doesn't support pipelining, so we have never more than one
packet per endpoint in flight.  So we go create an ID based on endpoint
and device address.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2012-08-31 11:57:23 +02:00
Hans de Goede 0132b4b659 usb: Halt ep queue en cancel pending packets on a packet error
For controllers which queue up more then 1 packet at a time, we must halt the
ep queue, and inside the controller code cancel all pending packets on an
error.

There are multiple reasons for this:
1) Guests expect the controllers to halt ep queues on error, so that they
get the opportunity to cancel transfers which the scheduled after the failing
one, before processing continues

2) Not cancelling queued up packets after a failed transfer also messes up
the controller state machine, in the case of EHCI causing the following
assert to trigger: "assert(p->qtdaddr == q->qtdaddr)" at hcd-ehci.c:2075

3) For bulk endpoints with pipelining enabled (redirection to a real USB
device), we must cancel all the transfers after this a failed one so that:
a) If they've completed already, they are not processed further causing more
   stalls to be reported, originating from the same failed transfer
b) If still in flight, they are cancelled before the guest does
   a clear stall, otherwise the guest and device can loose sync!

Note this patch only touches the ehci and uhci controller changes, since AFAIK
no other controllers actually queue up multiple transfer. If I'm wrong on this
other controllers need to be updated too!

Also note that this patch was heavily tested with the ehci code, where I had
a reproducer for a device causing a transfer to fail. The uhci code is not
tested with actually failing transfers and could do with a thorough review!

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2012-08-31 11:55:17 +02:00
Gerd Hoffmann da9fbe76a0 fix info qtree indention
Without the patch bus properties are are not in line with the other
properties:

[ ... ]
  dev: fw_cfg, id ""
    ctl_iobase = 0x510
    data_iobase = 0x511
      irq 0
      mmio ffffffffffffffff/0000000000000002
      mmio ffffffffffffffff/0000000000000001
[ ... ]

With the patch applied everything is lined up properly:

[ ... ]
  dev: fw_cfg, id ""
    ctl_iobase = 0x510
    data_iobase = 0x511
    irq 0
    mmio ffffffffffffffff/0000000000000002
    mmio ffffffffffffffff/0000000000000001
[ ... ]

Needed to make the autotest qtree parser happy.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2012-08-31 10:16:11 +02:00
Stefan Weil b834b5081d w32: Fix broken build
Commit ef8621b1a3 added an include
file which is not available for MinGW compilations.

Signed-off-by: Stefan Weil <sw@weilnetz.de>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
2012-08-30 16:36:21 -05:00
Anthony Liguori c9a238e700 Update version for 1.2.0-rc2
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
2012-08-30 07:45:28 -05:00
Stefan Weil 5bb0b62e75 scsi-disk: Fix typo (uint32 -> uint32_t)
Cc: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Stefan Weil <sw@weilnetz.de>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
2012-08-29 17:47:44 -05:00
Michael S. Tsirkin 3cac001e5a msix: make [un]use vectors on reset/load optional
The facility to use/unuse vectors dynamically is helpful
for virtio but little else: everyone just seems to use
vectors in their init function.

Avoid clearing msix vector use info on reset and load.
For virtio, clear it explicitly.
This should fix regressions reported with ivshmem - though
I didn't test this, I verified that virtio keeps
working like it did.

Tested-by: Cam Macdonell <cam@cs.ualberta.ca>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
2012-08-29 17:46:26 -05:00
Michael S. Tsirkin bc9a839d56 kvm: get/set PV EOI MSR
Support get/set of new PV EOI MSR, for migration.
Add an optional section for MSR value - send it
out in case MSR was changed from the default value (0).

Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
2012-08-29 10:51:28 -05:00
Michael S. Tsirkin 651682dcf5 linux-headers: update to 3.6-rc3
Update linux-headers to version present in Linux 3.6-rc3.
Header asm-x96_64/kvm_para.h update is needed for the new PV EOI
feature.

Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
2012-08-29 10:51:28 -05:00
Anthony Liguori ef8621b1a3 target-i386: disable pv eoi to fix migration across QEMU versions
We have a problem with how we handle migration with KVM paravirt features.
We unconditionally enable paravirt features regardless of whether we know how
to migrate them.

We also don't tie paravirt features to specific machine types so an old QEMU on
a new kernel would expose features that never existed.

The 1.2 cycle is over and as things stand, migration is broken.  Michael has
another series that adds support for migrating PV EOI and attempts to make it
work correctly for different machine types.

After speaking with Michael on IRC, we agreed to take this patch plus 1 & 4
from his series.  This makes sure QEMU can migrate PV EOI if it's enabled, but
does not enable it by default.

This also means that we won't unconditionally enable new features for guests
future proofing us from this happening again in the future.

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
2012-08-29 10:51:20 -05:00
Gleb Natapov 4d09d37c6a reset PMBA and PMREGMISC PIIX4 registers.
The bug causes Windows + OVMF hang after reboot since OVMF
checks PMREGMISC to see if IO space is enabled and skip
configuration if it is.

Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Gleb Natapov <gleb@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
2012-08-29 09:30:31 -05:00
Stefan Weil 4bdb1a3059 qemu-ga: Fix null pointer passed to unlink in failure branch
Clang reports this warning:

Null pointer passed as an argument to a 'nonnull' parameter

Reviewed-by: Luiz Capitulino <lcapitulino@redhat.com>
Signed-off-by: Stefan Weil <sw@weilnetz.de>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
2012-08-29 08:25:55 -05:00
Jan Kiszka 7e2a62d82a memory: Fix copy&paste mistake in memory_region_iorange_write
The last argument of find_portio is "write", so this must be true here.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
2012-08-29 08:25:37 -05:00
Cam Macdonell 7e7de876ae ivshmem: remove redundant ioeventfd configuration
setup_ioeventfds() is unnecessary and actually causes a segfault when used
ioeventfd=on is used on the command-line.  Since ioeventfds are handled within
the memory API, it can be removed.

Signed-off-by: Cam Macdonell <cam@cs.ualberta.ca>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
2012-08-29 08:23:50 -05:00
Peter Maydell 998a74bcda hw/arm_gic.c: Define .class_size in arm_gic_info TypeInfo
Add the missing .class_size definition to the arm_gic_info TypeInfo.
This fixes the memory corruption and possible segfault that otherwise
results when the class struct is allocated at too small a size and
the class init function writes off the end of it.

Reported-by: Adam Lackorzynski <adam@os.inf.tu-dresden.de>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
2012-08-29 08:23:40 -05:00
Stefan Hajnoczi 774a8850d7 qemu-iotests: add backing file smaller than image test case
This new test case checks that streaming completes successfully when the
backing file is smaller than the image file.

Signed-off-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2012-08-29 15:23:35 +02:00
Stefan Hajnoczi 571cd9dcc7 stream: complete early if end of backing file is reached
It is possible to create an image that is larger than its backing file.
Reading beyond the end of the backing file produces zeroes if no writes
have been made to those sectors in the image file.

This patch finishes streaming early when the end of the backing file is
reached.  Without this patch the block job hangs and continually tries
to stream the first sectors beyond the end of the backing file.

To reproduce the hung block job bug:

  $ qemu-img create -f qcow2 backing.qcow2 128M
  $ qemu-img create -f qcow2 -o backing_file=backing.qcow2 image.qcow2 6G
  $ qemu -drive if=virtio,cache=none,file=image.qcow2
  (qemu) block_stream virtio0
  (qemu) info block-jobs

The qemu-iotests 030 streaming test still passes.

Signed-off-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2012-08-29 15:23:35 +02:00
Stefan Hajnoczi ef72f76e58 qed: refuse unaligned zero writes with a backing file
Zero writes have cluster granularity in QED.  Therefore they can only be
used to zero entire clusters.

If the zero write request leaves sectors untouched, zeroing the entire
cluster would obscure the backing file.  Instead return -ENOTSUP, which
is handled by block.c:bdrv_co_do_write_zeroes() and falls back to a
regular write.

The qemu-iotests 034 test cases covers this scenario.

Signed-off-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2012-08-29 15:23:35 +02:00
Anthony Liguori 1e2778d59d Merge remote-tracking branch 'bonzini/scsi-next' into staging
* bonzini/scsi-next:
  iscsi: Set number of blocks to 0 for blank CDROM devices
  scsi: more fixes to properties for passthrough devices
  esp: support 24-bit DMA
  megasas: Add 'hba_serial' property
2012-08-29 08:23:18 -05:00
Anthony Liguori 7dd6f4b250 Merge remote-tracking branch 'riku/linux-user-for-upstream' into staging
* riku/linux-user-for-upstream:
  linux-user: Clarify "Unable to reserve guest address space" error
  linux-user: fix emulation of getdents
  linux-user: arg_table need not have global scope
2012-08-29 08:22:02 -05:00
Aurelien Jarno 18fec301cd tcg/mips: fix broken CONFIG_TCG_PASS_AREG0 code
The CONFIG_TCG_PASS_AREG0 code for calling ld/st helpers was
broken in that it did not respect the ABI requirement that 64
bit values were passed in even-odd register pairs. The simplest
way to fix this is to implement some new utility functions
for marshalling function arguments into the correct registers
and stack, so that the code which sets up the address and
data arguments does not need to care whether there has been
a preceding env argument.

Based on commit 9716ef3b for ARM by Peter Maydell.

Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
2012-08-28 20:38:39 +02:00
Aurelien Jarno ce67604048 Update OpenBIOS PPC image
Update OpenBIOS PPC image to SVN r1063 to fix issues introduced by
commit 9e56edcf. The code change in this revision only affects PPC,
so OpenBIOS SPARC images are not updated.

Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
2012-08-28 20:38:39 +02:00
Aurelien Jarno 54cddd21b0 target-ppc: fix altivec instructions
Altivec instructions are not working anymore in PowerPC emulation,
following commit d15f74fb, which inverted two registers in the call
to helper. Fix that.

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Andreas Färber <afaerber@suse.de>
Acked-by: Blue Swirl <blauwirbel@gmail.com>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
2012-08-28 18:49:22 +02:00
munkyu.im 13ef70f64e audio/winwave: previous audio buffer should be flushed
Winwave audio backend has problem with pausing and restart audio out.
Unlike other backends, Winwave pausing API does not flush audio buffer.
As a result, the previous audio data are played in front of
user expected sound when user restart audio.
So changes it to waveOutReset()

Signed-off-by: Munkyu Im <munkyu.im@samsung.com>
Signed-off-by: malc <av1474@comtv.ru>
2012-08-28 19:11:28 +04:00
Ronnie Sahlberg 135b908878 iscsi: Set number of blocks to 0 for blank CDROM devices
The number of blocks of the device is used to compute the device size
in bdrv_getlength()/iscsi_getlength().
For MMC devices, the ReturnedLogicalBlockAddress in the READCAPACITY10
has a special meaning when it is 0.
In this case it does not mean that LBA 0 is the last accessible LBA,
and thus the device has 1 readable block, but instead it means that the
disc is blank and there are no readable blocks.

This change ensures that when the iSCSI LUN is loaded with a blank
DVD-R disk or similar that bdrv_getlength() will return the correct
size of the device as 0 bytes.

Signed-off-by: Ronnie Sahlberg <ronniesahlberg@gmail.com>
2012-08-28 14:50:08 +02:00
Paolo Bonzini 0f1da449ec scsi: more fixes to properties for passthrough devices
Commit 0384783 (scsi-block: remove properties that are not relevant for
passthrough, 2012-07-09) removed one property that should have been
left there, "bootindex".

It also did not touch scsi-generic, while it should have.

Fix both problems.

Reported-by: Alexandre DERUMIER <aderumier@odiso.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2012-08-28 14:50:08 +02:00
Paolo Bonzini 9ea73f8b10 esp: support 24-bit DMA
SeaBIOS will issue requests for more than 64k when loading a CD-ROM
image into memory.  Support the TCHI register from the AMD PCscsi
spec.

Acked-by: Hervé Poussineau <hpoussin@reactos.org>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2012-08-28 14:49:59 +02:00
Hannes Reinecke fb6541571e megasas: Add 'hba_serial' property
Add a 'hba_serial' property to the megasas driver. Originally
it would be using a pointer value which would break migration.

Reported-by: Stefan Weil <sw@weilnetz.de>
Cc: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Hannes Reinecke <hare@suse.de>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2012-08-28 12:48:39 +02:00
Eric Johnson 36c6711bbe target-mips: allow microMIPS SWP and SDP to have RD equal to BASE
The microMIPS SWP and SDP instructions do not modify GPRs.  So their
behavior is well defined when RD equals BASE.  The MIPS Architecture
Verification Programs (AVPs) check that they work as expected.  This
is required for AVPs to pass.

Signed-off-by: Eric Johnson <ericj@mips.com>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
2012-08-27 22:18:02 +02:00
Eric Johnson 2e15497c5b target-mips: add privilege level check to several Cop0 instructions
The MIPS Architecture Verification Programs (AVPs) check privileged
instructions for the required privilege level.  These changes are needed
to pass the AVP suite.

Signed-off-by: Eric Johnson <ericj@mips.com>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
2012-08-27 22:17:59 +02:00
malc 08406b035e Revert "fix some debug printf format strings"
This reverts commit 145c7c880f.

Signed-off-by: malc <av1474@comtv.ru>
2012-08-27 18:33:24 +04:00
malc 9f227bc358 Revert "vl: fix -hdachs/-hda argument order parsing issues"
This reverts commit 7764ae9671.

Signed-off-by: malc <av1474@comtv.ru>
2012-08-27 18:33:22 +04:00
malc e4558dcae8 Revert "qemu-options.hx: mention retrace= VGA option"
This reverts commit 39dda26062.

Signed-off-by: malc <av1474@comtv.ru>
2012-08-27 18:33:21 +04:00
malc df8002103c Revert "vga: add some optional CGA compatibility hacks"
This reverts commit 482f7bf86b.

Signed-off-by: malc <av1474@comtv.ru>
2012-08-27 18:33:20 +04:00
malc 4f213879f3 Revert "i8259: add -no-spurious-interrupt-hack option"
This reverts commit f278d4947f.

Signed-off-by: malc <av1474@comtv.ru>
2012-08-27 18:33:12 +04:00
Richard Henderson b316728836 mips-linux-user: Always support rdhwr.
The kernel will emulate this instruction if it's not supported
natively.  This insn is used for TLS, among other things, and
so is required by modern glibc.

Signed-off-by: Richard Henderson <rth@twiddle.net>
Cc: Riku Voipio <riku.voipio@iki.fi>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
2012-08-27 12:17:40 +02:00
Richard Henderson 0516867450 target-mips: Streamline indexed cp1 memory addressing.
We've already eliminated both base and index being zero.

Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
2012-08-27 12:17:39 +02:00
Richard Sandiford 13d24f4972 Fix order of CVT.PS.S operands
The FS input to CVT.PS.S is the high half and FT is the low half.
tcg_gen_concat_i32_i64 takes the low half first, so the operands
were in the wrong order.

Signed-off-by: Richard Sandiford <rdsandiford@googlemail.com>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
2012-08-27 12:03:18 +02:00
Richard Sandiford d22d728987 Fix operands of RECIP2.S and RECIP2.PS
Read the second input operand of RECIP2.S and RECIP2.PS from FT rather
than FD.  RECIP2.D is already correct.

Signed-off-by: Richard Sandiford <rdsandiford@googlemail.com>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
2012-08-27 12:03:17 +02:00
Peter Maydell 097b8cb840 linux-user: Clarify "Unable to reserve guest address space" error
Now that we default to reserving nearly 4GB of RAM for the guest
address space when running a 32 bit linux-user guest on 64 bit
hosts, users are much more likely to run into it. Reword the
message to be more informative about what failed and provide
suggestions for how to fix things.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Riku Voipio <riku.voipio@linaro.org>
2012-08-27 10:18:01 +03:00
Dmitry V. Levin 333858b77c linux-user: fix emulation of getdents
In case when TARGET_ABI_BITS == 32 && HOST_LONG_BITS == 64, the last
byte of the target dirent structure (aka d_type byte) was never copied
from the host dirent structure, thus breaking everything that relies
on valid d_type value, e.g. glob(3).

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Dmitry V. Levin <ldv@altlinux.org>
Signed-off-by: Riku Voipio <riku.voipio@linaro.org>
2012-08-27 10:17:30 +03:00
Jim Meyering 42644cee08 linux-user: arg_table need not have global scope
Declare arg_table to be "static const", and adjust the two users
to also be const.

Signed-off-by: Jim Meyering <meyering@redhat.com>
Signed-off-by: Riku Voipio <riku.voipio@linaro.org>
2012-08-27 10:13:17 +03:00
Aurelien Jarno d03c98d80f tcg/ia64: fix and optimize ld/st slow path
Store slow path has been broken in e141ab52d:
- the arguments are shifted before the last one (mem_index) is written.
- the shift is done for both slow and fast paths.

Fix that. Also optimize a bit by bundling the move together. This still
can be optimized, but it's better to wait for a decision to be taken on
the arguments order.

Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
2012-08-26 21:10:37 +02:00
Aurelien Jarno 18d445b443 tcg/ia64: fix prologue/epilogue
Prologue and epilogue code has been broken in cea5f9a28.

Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
2012-08-26 21:10:28 +02:00
Peter Maydell 9716ef3b1b tcg/arm: Fix broken CONFIG_TCG_PASS_AREG0 code
The CONFIG_TCG_PASS_AREG0 code for calling ld/st helpers was
broken in that it did not respect the ABI requirement that 64
bit values were passed in even-odd register pairs. The simplest
way to fix this is to implement some new utility functions
for marshalling function arguments into the correct registers
and stack, so that the code which sets up the address and
data arguments does not need to care whether there has been
a preceding env argument.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
2012-08-26 18:14:46 +00:00
Matthew Ogilvie f278d4947f i8259: add -no-spurious-interrupt-hack option
This patch provides a way to optionally suppress spurious interrupts,
as a workaround for systems described below:

Some old operating systems do not handle spurious interrupts well,
and qemu tends to generate them significantly more often than
real hardware.

Examples:
  - Microport UNIX System V/386 v 2.1 (ca 1987)
    (The main problem I'm fixing: Without this patch, it panics
    sporadically when accessing the hard disk.)
  - AT&T UNIX System V/386 Release 4.0 Version 2.1a (ca 1991)
    See screenshot in "QEMU Official OS Support List":
    http://www.claunia.com/qemu/objectManager.php?sClass=application&iId=9
    (I don't have this system to test.)
  - A report about OS/2 boot lockup from 2004 by Hampa Hug:
    http://lists.nongnu.org/archive/html/qemu-devel/2004-09/msg00367.html
    (My patch was partially inspired by his.)
    Also: http://lists.nongnu.org/archive/html/qemu-devel/2005-06/msg00243.html
    (I don't have this system to test.)

Signed-off-by: Matthew Ogilvie <mmogilvi_qemu@miniinfo.net>
Signed-off-by: malc <av1474@comtv.ru>
2012-08-24 07:44:39 +04:00
Matthew Ogilvie 482f7bf86b vga: add some optional CGA compatibility hacks
This patch adds some optional compatibility hacks (default
disabled) to allow Microport UNIX to function under qemu.

I've tried to structure it to be easy to add more hacks for other
old CGA programs, if anyone ever needs them.

Microport UNIX System V/386 v 2.1 (ca 1987) tries to program
the CGA registers directly with neither the assistance of BIOS, nor
with proper handling of EGA/VGA-only registers.  Note that it didn't
work on real VGA hardware, either (although in that case, the most
obvious problems seemed to be out-of-range hsync and/or vsync
signalling, rather than the issues in this patch).

Eventually real MDA and/or CGA support might provide an alternative to
this patch, although a hybrid approach like this patch might still
be useful in marginal cases.

Signed-off-by: Matthew Ogilvie <mmogilvi_qemu@miniinfo.net>
Signed-off-by: malc <av1474@comtv.ru>
2012-08-24 07:44:39 +04:00
Matthew Ogilvie 39dda26062 qemu-options.hx: mention retrace= VGA option
The feature was added in commit cb5a7aa8c3 Sep 2008.
My description is based on "Better VGA retrace emulation (needed
for some DOS games/demos)" from
http://www.boblycat.org/~malc/code/patches/qemu/index.html

Signed-off-by: Matthew Ogilvie <mmogilvi_qemu@miniinfo.net>
Signed-off-by: malc <av1474@comtv.ru>
2012-08-24 07:44:38 +04:00
Matthew Ogilvie 7764ae9671 vl: fix -hdachs/-hda argument order parsing issues
Without this patch, the -hdachs argument had to occur either
BEFORE the corresponding "-hda" option, or AFTER the plain
disk image name (if neither -hda nor -drive is used).  Otherwise
it would effectively be ignored.

Option -hdachs still has no effect on -drive, but that seems best.

Signed-off-by: Matthew Ogilvie <mmogilvi_qemu@miniinfo.net>
Signed-off-by: malc <av1474@comtv.ru>
2012-08-24 07:44:38 +04:00
Matthew Ogilvie 5c73b757e3 target-i386/translate.c: mov to/from crN/drN: ignore mod bits
> This instruction is always treated as a register-to-register (MOD = 11)
> instruction, regardless of the encoding of the MOD field in the MODR/M
> byte.

Also, Microport UNIX System V/386 v 2.1 (ca 1987) runs fine on
real Intel 386 and 486 CPU's (at least), but does not run in qemu without
this patch.

Signed-off-by: Matthew Ogilvie <mmogilvi_qemu@miniinfo.net>
Signed-off-by: malc <av1474@comtv.ru>
2012-08-24 07:44:37 +04:00
Matthew Ogilvie 145c7c880f fix some debug printf format strings
These are normally ifdefed out and don't matter.  But if you enable
them, they ought to be correct.

Signed-off-by: Matthew Ogilvie <mmogilvi_qemu@miniinfo.net>
Signed-off-by: malc <av1474@comtv.ru>
2012-08-24 07:44:37 +04:00
Paolo Bonzini 98609cd8fc ivshmem: fix memory_region_del_eventfd assertion failure
We do not register ioeventfds unless the IVSHMEM_IOEVENTFD feature
is set.  The same feature must be checked before releasing the eventfds.
Regression introduced by commit 563027c (ivshmem: use EventNotifier and
memory API, 2012-07-05).

Reported-by: Cam Macdonnell <cam@cs.ualberta.ca>
Tested-by: Cam Macdonnell <cam@cs.ualberta.ca>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
2012-08-23 20:19:59 -05:00
Paolo Bonzini da5a44e8b0 qom: object_delete should unparent the object first
object_deinit is only called when the reference count goes to zero,
and yet tries to do an object_unparent.  Now, object_unparent
either does nothing or it will decrease the reference count.
Because we know the reference count is zero, the object_unparent
call in object_deinit is useless.

Instead, we need to disconnect the object from its parent just
before we remove the last reference apart from the parent's.  This
happens in object_delete.  Once we do this, all calls to
object_unparent peppered through QEMU can go away.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
2012-08-23 20:19:59 -05:00
Anthony Liguori 26efaca377 monitor: don't try to initialize json parser when monitor is HMP
Reported-by: Michael Roth <mdroth@linux.vnet.ibm.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
2012-08-23 20:19:59 -05:00
Stefan Weil 6fc97fafce target-mips: Fix some helper functions (VR54xx multiplication)
Commits b5dc7732e1 and
be24bb4f30 optimized the code
and removed the correct setting of t0. Fix this.

gcc-4.7 detected this bug because parameter arg1 was unused
but set in set_HIT0_LO and set_HI_LOT0.

Cc: Aurelien Jarno <aurelien@aurel32.net>
Signed-off-by: Stefan Weil <sw@weilnetz.de>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
2012-08-24 01:03:26 +02:00
Meador Inge 94159135cb target-mips: Enable access to required RDHWR hardware registers
While running in the usermode emulator all of the required*
MIPS32r2 RDHWR hardware registers should be accessible (the
Linux kernel enables access to these same registers).  Note
that these registers are still enabled when the MIPS ISA is
not release 2.  This is OK since the Linux kernel emulates
access to them when they are not available in hardware.

* There is also the ULR register which is only recommended
  for full release 2 compliance.  Incidentally, accessing
  this register in the current implementation works fine
  without flipping its access bit.

Signed-off-by: Meador Inge <meadori@codesourcery.com>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
2012-08-23 17:21:05 +02:00
Anthony Liguori 58617a795c monitor: move json init from OPEN event to init
At some point in the past, the OPEN event was changed to be issued from a
bottom half.  This creates a small window whereas a data callback registered in
init may be invoked before the OPEN event has been issued.

This is reproducible with:

 echo "{'execute': 'qmp_capabilities'}" | qemu-system-x86_64 -M none -qmp stdio

We can fix this for the monitor by moving the parser initialization to init.

The remaining state that is set in OPEN appears harmless.

Reported-by: Daniel Berrange <berrange@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
2012-08-23 08:03:21 -05:00
Anthony Liguori b4a738bf93 boards: add a 'none' machine type to all platforms
This allows any QEMU binary to be executed with:

  $QEMU_BINARY -M none -qmp stdio

Without errors from missing options that are required by various boards.  This
also provides a mode that we can use in the future to construct machines
entirely through QMP commands.

Cc: Daniel Berrange <berrange@redhat.com>
Cc: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
2012-08-22 16:29:41 -05:00
Anthony Liguori af506c7036 Update version for 1.2.0-rc1 release
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
2012-08-22 15:45:05 -05:00
Anthony Liguori 86759aa89d Merge remote-tracking branch 'qmp/queue/qmp' into staging
* qmp/queue/qmp:
  migration: move total_time from ram stats to migration info
  monitor: avoid declaring unused variables
  qapi: Fix memory leak
2012-08-22 13:33:15 -05:00
Anthony Liguori b100fcfe49 Merge remote-tracking branch 'sstabellini/xen-fixes-20120822' into staging
* sstabellini/xen-fixes-20120822:
  xen-all.c: fix multiply issue for int and uint types
  Fix invalidate if memory requested was not bucket aligned
2012-08-22 13:31:39 -05:00
Anthony Liguori a9b670b139 Merge remote-tracking branch 'bonzini/scsi-next' into staging
* bonzini/scsi-next:
  virtio-scsi: add backwards-compatibility properties for 1.1 and earlier machines
  iscsi: fix races between task completion and abort
  iscsi: simplify iscsi_schedule_bh
  iscsi: move iscsi_schedule_bh and iscsi_readv_writev_bh_cb
  Revert "iscsi: Fix NULL dereferences / races between task completion and abort"
2012-08-22 13:31:17 -05:00
Anthony Liguori 7b2f89c435 Merge remote-tracking branch 'kwolf/for-anthony' into staging
* kwolf/for-anthony:
  virtio-blk: hide VIRTIO_BLK_F_CONFIG_WCE from old machine types
  Documentation: Warn against qemu-img on active image
  vmdk: Read footer for streamOptimized images
  vmdk: Fix header structure

Conflicts:
	hw/virtio-blk.c
2012-08-22 13:01:05 -05:00
Anthony Liguori b6825cd79c Merge remote-tracking branch 'kraxel/usb.59' into staging
* kraxel/usb.59:
  ehci: Fix setting of halt bit from usbcmd register updates
  ehci: fix Interrupt Threshold Control implementation
  usb: update uas product id
  usb: async control xfer fixup
2012-08-22 12:53:18 -05:00
Daniel P. Berrange 99afc91d6c qapi: add 'query-target' command to return target arch
Add a 'query-target' QAPI command to allow management applications
to determine what target architecture a QEMU binary is emulating
without having to parse the binary name or -help output

  $ qmp-shell -p /tmp/qemu
  (QEMU) query-target
  {   u'return': {   u'arch': u'x86_64' }}

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
2012-08-22 10:47:17 -05:00
Andreas Färber 67c332fd12 pci: Tidy up PCI host bridges
Adopt the QOM parent field name and enforce QOM-style access via casts.
Don't just typedef PCIHostState, either use it directly or embed it.

Signed-off-by: Andreas Färber <afaerber@suse.de>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
2012-08-22 10:47:17 -05:00
Andreas Färber 8558d942b6 pci: Derive PCI host bridges from TYPE_PCI_HOST_BRIDGE
Use PCIHostState and PCI_HOST_BRIDGE() where appropriate.

Signed-off-by: Andreas Färber <afaerber@suse.de>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
2012-08-22 10:47:17 -05:00
Andreas Färber b44ff9d430 pci_host: Turn into SysBus-derived QOM type
The preceding commits fixed misuses of FROM_SYSBUS() that led people to
add a bogus busdev field. For qdev the field order was less relevant but
for QOM the PCIHostState field (including the SysBusDevice actually
initialized with a value) must be placed first within the state struct.

To facilitate accessing the PCIHostState fields, derive all PCI host
bridges from TYPE_PCI_HOST_BRIDGE rather than TYPE_SYS_BUS_DEVICE.

We can now access PCIHostState QOM-style, with PCI_HOST_BRIDGE() macro.

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
Signed-off-by: Wanpeng Li <liwanp@linux.vnet.ibm.com>
Signed-off-by: Andreas Färber <andreas.faerber@web.de>
Signed-off-by: Andreas Färber <afaerber@suse.de>
Acked-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
2012-08-22 10:47:17 -05:00
Andreas Färber 57fd7b7fce unin_pci: QOM'ify UniNorth PCI host bridges
Introduce type constants and cast macros.
Avoid accessing parent fields directly.

Signed-off-by: Andreas Färber <afaerber@suse.de>
Acked-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
2012-08-22 10:47:17 -05:00
Andreas Färber 8c9f64df3d spapr_pci: QOM'ify sPAPR PCI host bridge
Introduce type constant. Introduce cast macro to drop bogus busdev field
that would've broken SYS_BUS_DEVICE(). Avoid accessing parent fields
directly.

Free the identifier phb as acronym for PCI_HOST_BRIDGE.

Updated against conflicting merge from branch 'agraf/ppc-for-upstream'
(0d16fdd732), which removed busdev field
differently, moved some code around and added new occurrences of 'phb'.

Signed-off-by: Andreas Färber <afaerber@suse.de>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
2012-08-22 10:47:17 -05:00
Andreas Färber 03a6b66770 prep_pci: QOM'ify Raven PCI host bridge
Introduce type constant and cast macro. Avoid accessing parent fields
directly.

Also add missing space and braces.

Signed-off-by: Andreas Färber <afaerber@suse.de>
Acked-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
2012-08-22 10:47:17 -05:00
Andreas Färber 9c1a61f0e5 ppce500_pci: QOM'ify e500 PCI host bridge
Introduce type constant and cast macro. Avoid accessing parent fields
directly.

Signed-off-by: Andreas Färber <afaerber@suse.de>
Acked-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
2012-08-22 10:47:16 -05:00
Andreas Färber 42c281a283 ppc4xx_pci: QOM'ify ppc4xx PCI host bridge
Introduce type constant and cast macro. Avoid accessing its parent field
directly.

Signed-off-by: Andreas Färber <afaerber@suse.de>
Acked-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
2012-08-22 10:47:16 -05:00
Andreas Färber 8d43d7e591 gt64xxx: QOM'ify GT64120 PCI host bridge
Introduce type constant. Introduce cast macro to drop dummy busdev field
used with FROM_SYSBUS() macro that would've broken SYS_BUS_DEVICE().
Avoid accessing DeviceState indirectly through PCIHostState.

Signed-off-by: Andreas Färber <afaerber@suse.de>
Acked-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
2012-08-22 10:47:16 -05:00
Andreas Färber 0e655047c5 grackle_pci: QOM'ify Grackle PCI host bridge
Introduce type constant. Introduce cast macro to drop dummy busdev field
used with FROM_SYSBUS() that would've broken SYS_BUS_DEVICE().
Avoid accessing parent fields directly.

Drop no-op reset function.

Signed-off-by: Andreas Färber <afaerber@suse.de>
Acked-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
2012-08-22 10:47:16 -05:00
Andreas Färber ab61536737 dec_pci: QOM'ify DEC 21154 PCI-PCI bridge
Introduce type constant. Introduce cast macro and drop dummy busdev
field used with FROM_SYSBUS() that would've broken SYS_BUS_DEVICE().
Avoid accessing parent fields directly.

Signed-off-by: Andreas Färber <afaerber@suse.de>
Acked-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
2012-08-22 10:47:15 -05:00
Andreas Färber c5589ee974 bonito: QOM'ify Bonito PCI host bridge
Introduce type constant. Avoid accessing DeviceState or SysBusDevice
indirectly through PCIHostState field.

Drop global state by passing BonitoState as opaque and adding the IRQs
and a pointer to PCIBonitoState to its state.

Signed-off-by: Andreas Färber <afaerber@suse.de>
Acked-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
2012-08-22 10:47:15 -05:00
Andreas Färber 94dd91d651 alpha_typhoon: QOM'ify Typhoon PCI host bridge
Introduce type constant and cast macro. Don't access DeviceState
or PCIHostState indirectly through parent fields.

Signed-off-by: Andreas Färber <afaerber@suse.de>
Acked-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
2012-08-22 10:47:15 -05:00
Andreas Färber 4240abff5a pci: Make host bridge TypeInfos const
During the QOM migration they were amended with further info but this is
no longer the case. All static TypeInfos can be const these days.

Signed-off-by: Andreas Färber <afaerber@suse.de>
Acked-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
2012-08-22 10:47:15 -05:00
Stefan Hajnoczi ea776abca6 virtio-blk: hide VIRTIO_BLK_F_CONFIG_WCE from old machine types
QEMU has a policy of keeping a stable guest device ABI.  When new guest device
features are introduced they must not change hardware info seen by existing
guests.  This is important because operating systems or applications may
"fingerprint" the hardware and refuse to run when the hardware changes.  To
always get the latest guest device ABI, run with x86 machine type "pc".

This patch hides the new VIRTIO_BLK_F_CONFIG_WCE virtio feature bit from
existing machine types.  Only pc-1.2 and later will expose this feature
by default.

For more info on the VIRTIO_BLK_F_CONFIG_WCE feature bit, see:

  commit 13e3dce068
  Author: Paolo Bonzini <pbonzini@redhat.com>
  Date:   Thu Aug 9 16:07:19 2012 +0200

      virtio-blk: support VIRTIO_BLK_F_CONFIG_WCE

      Also rename VIRTIO_BLK_F_WCACHE to VIRTIO_BLK_F_WCE for consistency with
      the spec.

      Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
      Signed-off-by: Kevin Wolf <kwolf@redhat.com>

Anthony Liguori <aliguori@us.ibm.com> reported:

  This broke qemu-test because it changed the pc-1.0 machine type:

  Setting guest RANDOM seed to 47167
  *** Running tests ***
  Running test /tests/finger-print.sh...		OK
  --- fingerprints/pc-1.0.x86_64	2011-12-18 13:08:40.000000000 -0600
  +++ fingerprint.txt	2012-08-12 13:30:48.000000000 -0500
  @@ -55,7 +55,7 @@
   /sys/bus/pci/devices/0000:00:06.0/subsystem_device=0x0002
   /sys/bus/pci/devices/0000:00:06.0/class=0x010000
   /sys/bus/pci/devices/0000:00:06.0/revision=0x00
  -/sys/bus/pci/devices/0000:00:06.0/virtio/host-features=0x710006d4
  +/sys/bus/pci/devices/0000:00:06.0/virtio/host-features=0x71000ed4
   /sys/class/dmi/id/bios_vendor=Bochs
   /sys/class/dmi/id/bios_date=01/01/2007
   /sys/class/dmi/id/bios_version=Bochs
  Guest fingerprint changed for pc-1.0!

Reported-by: Anthony Liguori <aliguori@us.ibm.com>
Signed-off-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
2012-08-22 10:47:14 -05:00
Jim Meyering 15d9e3bc6a softmmu-semi: fix lock_user* functions not to deref NULL upon OOM
Return NULL upon malloc failure.

Signed-off-by: Jim Meyering <meyering@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
2012-08-22 10:47:14 -05:00
Jim Meyering 396bef4b38 arm-semi: don't leak 1KB user string lock buffer upon TARGET_SYS_OPEN
Always call unlock_user before returning.

Signed-off-by: Jim Meyering <meyering@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
2012-08-22 10:47:14 -05:00
Jim Meyering a7e47d4bfc sheepdog: don't leak socket file descriptor upon connection failure
Signed-off-by: Jim Meyering <meyering@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
2012-08-22 10:47:14 -05:00
Jim Meyering 0d07fe47d4 linux-user: do_msgrcv: don't leak host_mb upon TARGET_EFAULT failure
Also, use g_malloc to avoid NULL-deref upon OOM.

Signed-off-by: Jim Meyering <meyering@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
2012-08-22 10:47:14 -05:00
Jim Meyering 4144f122b4 qemu-ga: don't leak a file descriptor upon failed lockf
Signed-off-by: Jim Meyering <meyering@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
2012-08-22 10:47:14 -05:00
Dongxiao Xu 14d4018372 xen-all.c: fix multiply issue for int and uint types
If the two multiply operands are int and uint types separately,
the int type will be transformed to uint firstly, which is not the
intent in our code piece. The fix is to add (int64_t) transform
for the uint type before the multiply.

Signed-off-by: Dongxiao Xu <dongxiao.xu@intel.com>
Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
2012-08-22 10:17:43 +00:00
Frediano Ziglio 27b7652ef5 Fix invalidate if memory requested was not bucket aligned
When memory is mapped in qemu_map_cache with lock != 0 a reverse mapping
is created pointing to the virtual address of location requested.
The cached mapped entry is saved in last_address_vaddr with the memory
location of the base virtual address (without bucket offset).
However when this entry is invalidated the virtual address saved in the
reverse mapping is used. This cause that the mapping is freed but the
last_address_vaddr is not reset.

Signed-off-by: Frediano Ziglio <frediano.ziglio@citrix.com>
Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
2012-08-22 10:17:04 +00:00
Jan Kiszka 0ec64507a5 i82378: Remove bogus MMIO coalescing
This MMIO area is an entry gate to legacy PC ISA devices, addressed via
PIO over there. Quite a few of the PIO ports have side effects on access
like starting/stopping timers that must be executed properly ordered
/wrt the CPU. So we have to remove the coalescing mark.

Acked-by: Hervé Poussineau <hpoussin@reactos.org>
Acked-by: Andreas Färber <andreas.faerber@web.de>
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
2012-08-21 15:18:24 -05:00
Alexey Kardashevskiy 55ce75faf2 eventfd: making it thread safe
QEMU uses IO handlers to run select() in the main loop.
The handlers list is managed by qemu_set_fd_handler() helper
which works fine when called from the main thread as it is
called when select() is not waiting.

However IO handlers list can be changed in the thread other than
the main one doing os_host_main_loop_wait(), for example, as a result
of a hypercall which changes PCI config space (VFIO on POWER is the case)
and enables/disabled MSI/MSIX which closes/creates eventfd handles.
As the main loop should be waiting on the newly created eventfds,
it has to be restarted.

The patch adds the qemu_notify_event() call to interrupt select()
to make main_loop() restart select() with the updated IO handlers
list.

Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
2012-08-21 15:16:29 -05:00
Juan Quintela 7aa939af39 migration: move total_time from ram stats to migration info
Signed-off-by: Juan Quintela <quintela@redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
2012-08-21 15:06:24 -03:00
Blue Swirl b2dc64c391 monitor: avoid declaring unused variables
Some variables are only used on !win32, declare
them only when used.

This avoids a warning in mingw32 build:
  CC    i386-softmmu/monitor.o
/src/qemu/monitor.c: In function 'monitor_fdset_get_fd':
/src/qemu/monitor.c:2575: warning: unused variable 'mon_fd_flags'
/src/qemu/monitor.c:2574: warning: unused variable 'mon_fdset_fd'
/src/qemu/monitor.c:2573: warning: unused variable 'mon_fdset'

Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
Reviewed-by: Stefan Weil <sw@weilnetz.de>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
2012-08-20 14:42:49 -03:00
Stefan Weil e36c87667a qapi: Fix memory leak
valgrind report:

==24534== 232 bytes in 2 blocks are definitely lost in loss record 1,245 of 1,601
==24534==    at 0x4824F20: malloc (vg_replace_malloc.c:236)
==24534==    by 0x293C88: malloc_and_trace (vl.c:2281)
==24534==    by 0x489AD99: ??? (in /lib/libglib-2.0.so.0.2400.1)
==24534==    by 0x489B23B: g_malloc0 (in /lib/libglib-2.0.so.0.2400.1)
==24534==    by 0x2B4EFC: opts_visitor_new (opts-visitor.c:376)
==24534==    by 0x29DEA5: net_client_init (net.c:708)
==24534==    by 0x29E6C7: net_init_client (net.c:966)
==24534==    by 0x2C2179: qemu_opts_foreach (qemu-option.c:1114)
==24534==    by 0x29E85B: net_init_clients (net.c:1008)
==24534==    by 0x296F40: main (vl.c:3463)

Signed-off-by: Stefan Weil <sw@weilnetz.de>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
2012-08-20 11:05:08 -03:00
Paolo Bonzini 07a5298c30 virtio-scsi: add backwards-compatibility properties for 1.1 and earlier machines
Hotplug and parameter change are new in 1.2, disable them via compat
properties for pc-1.1 and earlier.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2012-08-20 15:58:47 +02:00
Paolo Bonzini 1bd075f29e iscsi: fix races between task completion and abort
This patch fixes two main issues with block/iscsi.c:

1) iscsi_task_mgmt_abort_task_async calls iscsi_scsi_task_cancel which
was also directly called in iscsi_aio_cancel

2) a race between task completion and task abortion could happen cause
the scsi_free_scsi_task were done before iscsi_schedule_bh has finished.
To fix this, all the freeing of IscsiTasks and releasing of the AIOCBs
is centralized in iscsi_bh_cb, independent of whether the SCSI command
has completed or was cancelled.

3) iscsi_aio_cancel was not synchronously waiting for the end of the
command.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2012-08-20 15:58:47 +02:00
Paolo Bonzini cfb3f5064a iscsi: simplify iscsi_schedule_bh
It is always used with the same callback, remove the argument.  And
its return value is never used, assume allocation succeeds.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2012-08-20 15:58:47 +02:00
Paolo Bonzini 27cbd828c6 iscsi: move iscsi_schedule_bh and iscsi_readv_writev_bh_cb
Put these functions at the beginning, to avoid forward references
in the next patches.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2012-08-20 15:58:47 +02:00
Paolo Bonzini b209091957 Revert "iscsi: Fix NULL dereferences / races between task completion and abort"
This reverts commit 64e69e8092.  The commit
returned immediately from iscsi_aio_cancel, risking corruption in case the
following happens:

    guest                  qemu                 target
  =========================================================================
    send write 1 -------->
                           send write 1 -------->
    cancel write 1 ------>
                           cancel write 1 ------>
       <------------------ cancellation processed
    send write 2 -------->
                           send write 2 -------->
                               <---------------- completed write 2
       <------------------ completed write 2
                               <---------------- completed write 1
                               <---------------- cancellation not done

Here, the guest would see write 2 superseding write 1, when in fact the
outcome could have been the opposite.  The right behavior is to return
only after the target says whether the cancellation was done or not, and
it will be implemented by the next three patches.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2012-08-20 15:50:45 +02:00
Blue Swirl 682527c004 Update OpenBIOS images
Update OpenBIOS images to SVN r1062. Build with GCC 4.6.0
in order to avoid boot problems introduced by GCC 4.7.[01].

Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
2012-08-19 13:39:31 +00:00
Markus Armbruster e89001f72e pc: Fix RTC CMOS info on RAM for ram_size < 1MiB
pc_cmos_init() always claims 640KiB base memory, and ram_size - 1MiB
extended memory.  The latter can underflow to "lots of extended
memory".  Fix both, and clean up some.

Note: SeaBIOS currently requires 1MiB of RAM, and doesn't check
whether it got enough.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
2012-08-18 16:54:23 +00:00
Markus Armbruster ff96101552 vl: Round argument of -m up to multiple of 8KiB
Partial pages make little sense and don't work.  Ensure the RAM size
is a multiple of any possible target's page size.

Fixes

    $ qemu-system-x86_64 -nodefaults -S -vnc :0 -m 0.8
    qemu-system-x86_64: /work/armbru/qemu/exec.c:2255: register_subpage: Assertion `existing->mr->subpage || existing->mr == &io_mem_unassigned' failed.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
2012-08-18 16:53:21 +00:00
Gerd Hoffmann d83c951cce scsi: fix warning
hw/scsi-bus.c:758: warning: ‘xfer’ may be used uninitialized in this
function

Isn't true, but older gcc versions (for example 4.1 as shipped in rhel5)
are not clever enougth to figure, so sprinkle in a default: line to make
them happy.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
2012-08-18 08:50:09 +00:00
Gerd Hoffmann 5f893b4e9c Avoid asprintf() which is not available on mingw
Use g_strdup_printf() instead.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Stefan Weil <sw@weilnetz.de>
Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
2012-08-18 08:49:27 +00:00
Stefan Hajnoczi eec7f96c2c virtio-blk: hide VIRTIO_BLK_F_CONFIG_WCE from old machine types
QEMU has a policy of keeping a stable guest device ABI.  When new guest device
features are introduced they must not change hardware info seen by existing
guests.  This is important because operating systems or applications may
"fingerprint" the hardware and refuse to run when the hardware changes.  To
always get the latest guest device ABI, run with x86 machine type "pc".

This patch hides the new VIRTIO_BLK_F_CONFIG_WCE virtio feature bit from
existing machine types.  Only pc-1.2 and later will expose this feature
by default.

For more info on the VIRTIO_BLK_F_CONFIG_WCE feature bit, see:

  commit 13e3dce068
  Author: Paolo Bonzini <pbonzini@redhat.com>
  Date:   Thu Aug 9 16:07:19 2012 +0200

      virtio-blk: support VIRTIO_BLK_F_CONFIG_WCE

      Also rename VIRTIO_BLK_F_WCACHE to VIRTIO_BLK_F_WCE for consistency with
      the spec.

      Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
      Signed-off-by: Kevin Wolf <kwolf@redhat.com>

Anthony Liguori <aliguori@us.ibm.com> reported:

  This broke qemu-test because it changed the pc-1.0 machine type:

  Setting guest RANDOM seed to 47167
  *** Running tests ***
  Running test /tests/finger-print.sh...		OK
  --- fingerprints/pc-1.0.x86_64	2011-12-18 13:08:40.000000000 -0600
  +++ fingerprint.txt	2012-08-12 13:30:48.000000000 -0500
  @@ -55,7 +55,7 @@
   /sys/bus/pci/devices/0000:00:06.0/subsystem_device=0x0002
   /sys/bus/pci/devices/0000:00:06.0/class=0x010000
   /sys/bus/pci/devices/0000:00:06.0/revision=0x00
  -/sys/bus/pci/devices/0000:00:06.0/virtio/host-features=0x710006d4
  +/sys/bus/pci/devices/0000:00:06.0/virtio/host-features=0x71000ed4
   /sys/class/dmi/id/bios_vendor=Bochs
   /sys/class/dmi/id/bios_date=01/01/2007
   /sys/class/dmi/id/bios_version=Bochs
  Guest fingerprint changed for pc-1.0!

Reported-by: Anthony Liguori <aliguori@us.ibm.com>
Signed-off-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2012-08-17 21:29:24 +02:00
Kevin Wolf 48467328c6 Documentation: Warn against qemu-img on active image
People have repeatedly expected that you can do things like snapshotting
an image with qemu-img while a qemu instance is running. Maybe we need
to consider locking the files while they are in use, but having a
warning in the qemu-img manpage is doable for 1.2 and can't hurt anyway.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2012-08-17 21:29:15 +02:00
Kevin Wolf 65bd155c73 vmdk: Read footer for streamOptimized images
The footer takes precedence over the header when it exists. It contains
the real grain directory offset that is missing in the header. Without
this patch, streamOptimized images with a footer cannot be read.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
Reviewed-by: Jeff Cody <jcody@redhat.com>
2012-08-17 13:27:02 +02:00
Kevin Wolf 7a736bfa4e vmdk: Fix header structure
Commit bb45ded9 swapped gd_offset and rgd_offset. This is wrong.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2012-08-17 11:14:19 +02:00
Hans de Goede 47d073cc3b ehci: Fix setting of halt bit from usbcmd register updates
This fixes linux guests started without any USB devices not seeing newly
plugged devices until "lsusb" is done inside the guest.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2012-08-16 11:48:25 +02:00
Gerd Hoffmann 6d3b6d3d2d ehci: fix Interrupt Threshold Control implementation
First, not all interrupts are subject to Interrupt Threshold Control,
some of them must be delivered without delay.

Second, Interrupt Threshold Control state must be part of vmstate,
otherwise we might loose IRQs on migration.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2012-08-16 08:39:50 +02:00
Gerd Hoffmann 0daf53047d usb: update uas product id
Pick other product id to fix clash with audio.

Current usage list (after applying this patch):

46f4:0001 -- usb-storage
46f4:0002 -- usb-audio
46f4:0003 -- usb-uas

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2012-08-16 08:39:49 +02:00
Gerd Hoffmann c19537a114 usb: async control xfer fixup
Need to clear p->result after copying setup data using usb_packet_copy()
because we'll reuse the USBPacket for the data transfer.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2012-08-16 08:39:49 +02:00
106 changed files with 1521 additions and 883 deletions

No files matched your search

+1 -1
View File
@@ -1 +1 @@
1.1.90
1.2.0
+11
View File
@@ -44,6 +44,7 @@
#include "exec-memory.h"
#include "hw/pcspk.h"
#include "qemu/page_cache.h"
#include "qmp-commands.h"
#ifdef DEBUG_ARCH_INIT
#define DPRINTF(fmt, ...) \
@@ -1080,3 +1081,13 @@ int xen_available(void)
return 0;
#endif
}
TargetInfo *qmp_query_target(Error **errp)
{
TargetInfo *info = g_malloc0(sizeof(*info));
info->arch = TARGET_TYPE;
return info;
}
+3 -9
View File
@@ -349,21 +349,15 @@ static int winwave_ctl_out (HWVoiceOut *hw, int cmd, ...)
else {
hw->poll_mode = 0;
}
if (wave->paused) {
mr = waveOutRestart (wave->hwo);
if (mr != MMSYSERR_NOERROR) {
winwave_logerr (mr, "waveOutRestart");
}
wave->paused = 0;
}
wave->paused = 0;
}
return 0;
case VOICE_DISABLE:
if (!wave->paused) {
mr = waveOutPause (wave->hwo);
mr = waveOutReset (wave->hwo);
if (mr != MMSYSERR_NOERROR) {
winwave_logerr (mr, "waveOutPause");
winwave_logerr (mr, "waveOutReset");
}
else {
wave->paused = 1;
+69 -60
View File
@@ -72,14 +72,44 @@ struct IscsiTask {
int complete;
};
static void
iscsi_bh_cb(void *p)
{
IscsiAIOCB *acb = p;
qemu_bh_delete(acb->bh);
if (acb->canceled == 0) {
acb->common.cb(acb->common.opaque, acb->status);
}
if (acb->task != NULL) {
scsi_free_scsi_task(acb->task);
acb->task = NULL;
}
qemu_aio_release(acb);
}
static void
iscsi_schedule_bh(IscsiAIOCB *acb)
{
if (acb->bh) {
return;
}
acb->bh = qemu_bh_new(iscsi_bh_cb, acb);
qemu_bh_schedule(acb->bh);
}
static void
iscsi_abort_task_cb(struct iscsi_context *iscsi, int status, void *command_data,
void *private_data)
{
IscsiAIOCB *acb = (IscsiAIOCB *)private_data;
IscsiAIOCB *acb = private_data;
scsi_free_scsi_task(acb->task);
acb->task = NULL;
acb->status = -ECANCELED;
iscsi_schedule_bh(acb);
}
static void
@@ -88,15 +118,19 @@ iscsi_aio_cancel(BlockDriverAIOCB *blockacb)
IscsiAIOCB *acb = (IscsiAIOCB *)blockacb;
IscsiLun *iscsilun = acb->iscsilun;
if (acb->status != -EINPROGRESS) {
return;
}
acb->canceled = 1;
acb->common.cb(acb->common.opaque, -ECANCELED);
/* send a task mgmt call to the target to cancel the task on the target
* this also cancels the task in libiscsi
*/
/* send a task mgmt call to the target to cancel the task on the target */
iscsi_task_mgmt_abort_task_async(iscsilun->iscsi, acb->task,
iscsi_abort_task_cb, &acb);
iscsi_abort_task_cb, acb);
while (acb->status == -EINPROGRESS) {
qemu_aio_wait();
}
}
static AIOPool iscsi_aio_pool = {
@@ -163,41 +197,6 @@ iscsi_process_write(void *arg)
}
static int
iscsi_schedule_bh(QEMUBHFunc *cb, IscsiAIOCB *acb)
{
acb->bh = qemu_bh_new(cb, acb);
if (!acb->bh) {
error_report("oom: could not create iscsi bh");
return -EIO;
}
qemu_bh_schedule(acb->bh);
return 0;
}
static void
iscsi_readv_writev_bh_cb(void *p)
{
IscsiAIOCB *acb = p;
qemu_bh_delete(acb->bh);
if (!acb->canceled) {
acb->common.cb(acb->common.opaque, acb->status);
}
qemu_aio_release(acb);
if (acb->canceled) {
return;
}
scsi_free_scsi_task(acb->task);
acb->task = NULL;
}
static void
iscsi_aio_write16_cb(struct iscsi_context *iscsi, int status,
void *command_data, void *opaque)
@@ -208,8 +207,7 @@ iscsi_aio_write16_cb(struct iscsi_context *iscsi, int status,
g_free(acb->buf);
if (acb->canceled) {
qemu_aio_release(acb);
if (acb->canceled != 0) {
return;
}
@@ -220,7 +218,7 @@ iscsi_aio_write16_cb(struct iscsi_context *iscsi, int status,
acb->status = -EIO;
}
iscsi_schedule_bh(iscsi_readv_writev_bh_cb, acb);
iscsi_schedule_bh(acb);
}
static int64_t sector_qemu2lun(int64_t sector, IscsiLun *iscsilun)
@@ -249,6 +247,8 @@ iscsi_aio_writev(BlockDriverState *bs, int64_t sector_num,
acb->qiov = qiov;
acb->canceled = 0;
acb->bh = NULL;
acb->status = -EINPROGRESS;
/* XXX we should pass the iovec to write16 to avoid the extra copy */
/* this will allow us to get rid of 'buf' completely */
@@ -305,8 +305,7 @@ iscsi_aio_read16_cb(struct iscsi_context *iscsi, int status,
trace_iscsi_aio_read16_cb(iscsi, status, acb, acb->canceled);
if (acb->canceled) {
qemu_aio_release(acb);
if (acb->canceled != 0) {
return;
}
@@ -317,7 +316,7 @@ iscsi_aio_read16_cb(struct iscsi_context *iscsi, int status,
acb->status = -EIO;
}
iscsi_schedule_bh(iscsi_readv_writev_bh_cb, acb);
iscsi_schedule_bh(acb);
}
static BlockDriverAIOCB *
@@ -343,6 +342,8 @@ iscsi_aio_readv(BlockDriverState *bs, int64_t sector_num,
acb->qiov = qiov;
acb->canceled = 0;
acb->bh = NULL;
acb->status = -EINPROGRESS;
acb->read_size = qemu_read_size;
acb->buf = NULL;
@@ -417,8 +418,7 @@ iscsi_synccache10_cb(struct iscsi_context *iscsi, int status,
{
IscsiAIOCB *acb = opaque;
if (acb->canceled) {
qemu_aio_release(acb);
if (acb->canceled != 0) {
return;
}
@@ -429,7 +429,7 @@ iscsi_synccache10_cb(struct iscsi_context *iscsi, int status,
acb->status = -EIO;
}
iscsi_schedule_bh(iscsi_readv_writev_bh_cb, acb);
iscsi_schedule_bh(acb);
}
static BlockDriverAIOCB *
@@ -444,6 +444,8 @@ iscsi_aio_flush(BlockDriverState *bs,
acb->iscsilun = iscsilun;
acb->canceled = 0;
acb->bh = NULL;
acb->status = -EINPROGRESS;
acb->task = iscsi_synchronizecache10_task(iscsi, iscsilun->lun,
0, 0, 0, 0,
@@ -467,8 +469,7 @@ iscsi_unmap_cb(struct iscsi_context *iscsi, int status,
{
IscsiAIOCB *acb = opaque;
if (acb->canceled) {
qemu_aio_release(acb);
if (acb->canceled != 0) {
return;
}
@@ -479,7 +480,7 @@ iscsi_unmap_cb(struct iscsi_context *iscsi, int status,
acb->status = -EIO;
}
iscsi_schedule_bh(iscsi_readv_writev_bh_cb, acb);
iscsi_schedule_bh(acb);
}
static BlockDriverAIOCB *
@@ -496,6 +497,8 @@ iscsi_aio_discard(BlockDriverState *bs,
acb->iscsilun = iscsilun;
acb->canceled = 0;
acb->bh = NULL;
acb->status = -EINPROGRESS;
list[0].lba = sector_qemu2lun(sector_num, iscsilun);
list[0].num = nb_sectors * BDRV_SECTOR_SIZE / iscsilun->block_size;
@@ -523,8 +526,7 @@ iscsi_aio_ioctl_cb(struct iscsi_context *iscsi, int status,
{
IscsiAIOCB *acb = opaque;
if (acb->canceled) {
qemu_aio_release(acb);
if (acb->canceled != 0) {
return;
}
@@ -552,7 +554,7 @@ iscsi_aio_ioctl_cb(struct iscsi_context *iscsi, int status,
memcpy(acb->ioh->sbp, &acb->task->datain.data[2], ss);
}
iscsi_schedule_bh(iscsi_readv_writev_bh_cb, acb);
iscsi_schedule_bh(acb);
}
static BlockDriverAIOCB *iscsi_aio_ioctl(BlockDriverState *bs,
@@ -570,6 +572,8 @@ static BlockDriverAIOCB *iscsi_aio_ioctl(BlockDriverState *bs,
acb->iscsilun = iscsilun;
acb->canceled = 0;
acb->bh = NULL;
acb->status = -EINPROGRESS;
acb->buf = NULL;
acb->ioh = buf;
@@ -717,7 +721,12 @@ iscsi_readcapacity10_cb(struct iscsi_context *iscsi, int status,
}
itask->iscsilun->block_size = rc10->block_size;
itask->iscsilun->num_blocks = rc10->lba + 1;
if (rc10->lba == 0) {
/* blank disk loaded */
itask->iscsilun->num_blocks = 0;
} else {
itask->iscsilun->num_blocks = rc10->lba + 1;
}
itask->bs->total_sectors = itask->iscsilun->num_blocks *
itask->iscsilun->block_size / BDRV_SECTOR_SIZE ;
+11
View File
@@ -1363,10 +1363,21 @@ static int coroutine_fn bdrv_qed_co_write_zeroes(BlockDriverState *bs,
int nb_sectors)
{
BlockDriverAIOCB *blockacb;
BDRVQEDState *s = bs->opaque;
QEDWriteZeroesCB cb = { .done = false };
QEMUIOVector qiov;
struct iovec iov;
/* Refuse if there are untouched backing file sectors */
if (bs->backing_hd) {
if (qed_offset_into_cluster(s, sector_num * BDRV_SECTOR_SIZE) != 0) {
return -ENOTSUP;
}
if (qed_offset_into_cluster(s, nb_sectors * BDRV_SECTOR_SIZE) != 0) {
return -ENOTSUP;
}
}
/* Zero writes start without an I/O buffer. If a buffer becomes necessary
* then it will be allocated during request processing.
*/
+1
View File
@@ -485,6 +485,7 @@ static int connect_to_sdog(const char *addr, const char *port)
if (errno == EINTR) {
goto reconnect;
}
close(fd);
break;
}
+6
View File
@@ -122,6 +122,12 @@ wait:
* known-unallocated area [sector_num, sector_num+n). */
ret = bdrv_co_is_allocated_above(bs->backing_hd, base,
sector_num, n, &n);
/* Finish early if end of backing file has been reached */
if (ret == 0 && n == 0) {
n = end - sector_num;
}
copy = (ret == 1);
}
trace_stream_one_iteration(s, sector_num, n, ret);
+57 -1
View File
@@ -35,6 +35,7 @@
#define VMDK4_FLAG_RGD (1 << 1)
#define VMDK4_FLAG_COMPRESS (1 << 16)
#define VMDK4_FLAG_MARKER (1 << 17)
#define VMDK4_GD_AT_END 0xffffffffffffffffULL
typedef struct {
uint32_t version;
@@ -57,8 +58,8 @@ typedef struct {
int64_t desc_offset;
int64_t desc_size;
int32_t num_gtes_per_gte;
int64_t gd_offset;
int64_t rgd_offset;
int64_t gd_offset;
int64_t grain_offset;
char filler[1];
char check_bytes[4];
@@ -115,6 +116,13 @@ typedef struct VmdkGrainMarker {
uint8_t data[0];
} VmdkGrainMarker;
enum {
MARKER_END_OF_STREAM = 0,
MARKER_GRAIN_TABLE = 1,
MARKER_GRAIN_DIRECTORY = 2,
MARKER_FOOTER = 3,
};
static int vmdk_probe(const uint8_t *buf, int buf_size, const char *filename)
{
uint32_t magic;
@@ -451,6 +459,54 @@ static int vmdk_open_vmdk4(BlockDriverState *bs,
if (header.capacity == 0 && header.desc_offset) {
return vmdk_open_desc_file(bs, flags, header.desc_offset << 9);
}
if (le64_to_cpu(header.gd_offset) == VMDK4_GD_AT_END) {
/*
* The footer takes precedence over the header, so read it in. The
* footer starts at offset -1024 from the end: One sector for the
* footer, and another one for the end-of-stream marker.
*/
struct {
struct {
uint64_t val;
uint32_t size;
uint32_t type;
uint8_t pad[512 - 16];
} QEMU_PACKED footer_marker;
uint32_t magic;
VMDK4Header header;
uint8_t pad[512 - 4 - sizeof(VMDK4Header)];
struct {
uint64_t val;
uint32_t size;
uint32_t type;
uint8_t pad[512 - 16];
} QEMU_PACKED eos_marker;
} QEMU_PACKED footer;
ret = bdrv_pread(file,
bs->file->total_sectors * 512 - 1536,
&footer, sizeof(footer));
if (ret < 0) {
return ret;
}
/* Some sanity checks for the footer */
if (be32_to_cpu(footer.magic) != VMDK4_MAGIC ||
le32_to_cpu(footer.footer_marker.size) != 0 ||
le32_to_cpu(footer.footer_marker.type) != MARKER_FOOTER ||
le64_to_cpu(footer.eos_marker.val) != 0 ||
le32_to_cpu(footer.eos_marker.size) != 0 ||
le32_to_cpu(footer.eos_marker.type) != MARKER_END_OF_STREAM)
{
return -EINVAL;
}
header = footer.header;
}
l1_entry_sectors = le32_to_cpu(header.num_gtes_per_gte)
* le64_to_cpu(header.granularity);
if (l1_entry_sectors == 0) {
Vendored
+6 -1
View File
@@ -3834,14 +3834,19 @@ case "$target_arch2" in
;;
esac
upper() {
echo "$@"| LC_ALL=C tr '[a-z]' '[A-Z]'
}
echo "TARGET_SHORT_ALIGNMENT=$target_short_alignment" >> $config_target_mak
echo "TARGET_INT_ALIGNMENT=$target_int_alignment" >> $config_target_mak
echo "TARGET_LONG_ALIGNMENT=$target_long_alignment" >> $config_target_mak
echo "TARGET_LLONG_ALIGNMENT=$target_llong_alignment" >> $config_target_mak
echo "TARGET_ARCH=$TARGET_ARCH" >> $config_target_mak
target_arch_name="`echo $TARGET_ARCH | LC_ALL=C tr '[a-z]' '[A-Z]'`"
target_arch_name="`upper $TARGET_ARCH`"
echo "TARGET_$target_arch_name=y" >> $config_target_mak
echo "TARGET_ARCH2=$target_arch2" >> $config_target_mak
echo "TARGET_TYPE=TARGET_TYPE_`upper $target_arch2`" >> $config_target_mak
echo "TARGET_BASE_ARCH=$TARGET_BASE_ARCH" >> $config_target_mak
if [ "$TARGET_ABI_DIR" = "" ]; then
TARGET_ABI_DIR=$TARGET_ARCH
+29 -30
View File
@@ -850,6 +850,26 @@ static void console_clear_xy(TextConsole *s, int x, int y)
update_xy(s, x, y);
}
/* set cursor, checking bounds */
static void set_cursor(TextConsole *s, int x, int y)
{
if (x < 0) {
x = 0;
}
if (y < 0) {
y = 0;
}
if (y >= s->height) {
y = s->height - 1;
}
if (x >= s->width) {
x = s->width - 1;
}
s->x = x;
s->y = y;
}
static void console_putchar(TextConsole *s, int ch)
{
TextCell *c;
@@ -921,7 +941,8 @@ static void console_putchar(TextConsole *s, int ch)
s->esc_params[s->nb_esc_params] * 10 + ch - '0';
}
} else {
s->nb_esc_params++;
if (s->nb_esc_params < MAX_ESC_PARAMS)
s->nb_esc_params++;
if (ch == ';')
break;
#ifdef DEBUG_CONSOLE
@@ -935,59 +956,37 @@ static void console_putchar(TextConsole *s, int ch)
if (s->esc_params[0] == 0) {
s->esc_params[0] = 1;
}
s->y -= s->esc_params[0];
if (s->y < 0) {
s->y = 0;
}
set_cursor(s, s->x, s->y - s->esc_params[0]);
break;
case 'B':
/* move cursor down */
if (s->esc_params[0] == 0) {
s->esc_params[0] = 1;
}
s->y += s->esc_params[0];
if (s->y >= s->height) {
s->y = s->height - 1;
}
set_cursor(s, s->x, s->y + s->esc_params[0]);
break;
case 'C':
/* move cursor right */
if (s->esc_params[0] == 0) {
s->esc_params[0] = 1;
}
s->x += s->esc_params[0];
if (s->x >= s->width) {
s->x = s->width - 1;
}
set_cursor(s, s->x + s->esc_params[0], s->y);
break;
case 'D':
/* move cursor left */
if (s->esc_params[0] == 0) {
s->esc_params[0] = 1;
}
s->x -= s->esc_params[0];
if (s->x < 0) {
s->x = 0;
}
set_cursor(s, s->x - s->esc_params[0], s->y);
break;
case 'G':
/* move cursor to column */
s->x = s->esc_params[0] - 1;
if (s->x < 0) {
s->x = 0;
}
set_cursor(s, s->esc_params[0] - 1, s->y);
break;
case 'f':
case 'H':
/* move cursor to row, column */
s->x = s->esc_params[1] - 1;
if (s->x < 0) {
s->x = 0;
}
s->y = s->esc_params[0] - 1;
if (s->y < 0) {
s->y = 0;
}
set_cursor(s, s->esc_params[1] - 1, s->esc_params[0] - 1);
break;
case 'J':
switch (s->esc_params[0]) {
@@ -1087,7 +1086,7 @@ void console_select(unsigned int index)
if (s) {
DisplayState *ds = s->ds;
if (active_console->cursor_timer) {
if (active_console && active_console->cursor_timer) {
qemu_del_timer(active_console->cursor_timer);
}
active_console = s;
+2 -2
View File
@@ -149,6 +149,8 @@ void hmp_info_migrate(Monitor *mon)
if (info->has_status) {
monitor_printf(mon, "Migration status: %s\n", info->status);
monitor_printf(mon, "total time: %" PRIu64 " milliseconds\n",
info->total_time);
}
if (info->has_ram) {
@@ -158,8 +160,6 @@ void hmp_info_migrate(Monitor *mon)
info->ram->remaining >> 10);
monitor_printf(mon, "total ram: %" PRIu64 " kbytes\n",
info->ram->total >> 10);
monitor_printf(mon, "total time: %" PRIu64 " milliseconds\n",
info->ram->total_time);
monitor_printf(mon, "duplicate: %" PRIu64 " pages\n",
info->ram->duplicate);
monitor_printf(mon, "normal: %" PRIu64 " pages\n",
+2
View File
@@ -134,6 +134,8 @@ hw-obj-$(CONFIG_DP8393X) += dp8393x.o
hw-obj-$(CONFIG_DS1225Y) += ds1225y.o
hw-obj-$(CONFIG_MIPSNET) += mipsnet.o
hw-obj-y += null-machine.o
# Sound
sound-obj-y =
sound-obj-$(CONFIG_SB16) += sb16.o
+3 -3
View File
@@ -305,7 +305,6 @@ static void acpi_piix_eject_slot(PIIX4PMState *s, unsigned slots)
if (pc->no_hotplug) {
slot_free = false;
} else {
object_unparent(OBJECT(dev));
qdev_free(qdev);
}
}
@@ -353,6 +352,9 @@ static void piix4_reset(void *opaque)
pci_conf[0x5a] = 0;
pci_conf[0x5b] = 0;
pci_conf[0x40] = 0x01; /* PM io base read only bit */
pci_conf[0x80] = 0;
if (s->kvm_enabled) {
/* Mark SMM as already inited (until KVM supports SMM). */
pci_conf[0x5B] = 0x02;
@@ -392,8 +394,6 @@ static int piix4_pm_initfn(PCIDevice *dev)
pci_conf[0x09] = 0x00;
pci_conf[0x3d] = 0x01; // interrupt pin 1
pci_conf[0x40] = 0x01; /* PM io base read only bit */
/* APM */
apm_init(&s->apm, apm_ctrl_changed, s);
+16 -10
View File
@@ -15,6 +15,8 @@
#include "exec-memory.h"
#define TYPE_TYPHOON_PCI_HOST_BRIDGE "typhoon-pcihost"
typedef struct TyphoonCchip {
MemoryRegion region;
uint64_t misc;
@@ -40,8 +42,12 @@ typedef struct TyphoonPchip {
TyphoonWindow win[4];
} TyphoonPchip;
#define TYPHOON_PCI_HOST_BRIDGE(obj) \
OBJECT_CHECK(TyphoonState, (obj), TYPE_TYPHOON_PCI_HOST_BRIDGE)
typedef struct TyphoonState {
PCIHostState host;
PCIHostState parent_obj;
TyphoonCchip cchip;
TyphoonPchip pchip;
MemoryRegion dchip_region;
@@ -700,16 +706,16 @@ PCIBus *typhoon_init(ram_addr_t ram_size, ISABus **isa_bus,
MemoryRegion *addr_space = get_system_memory();
MemoryRegion *addr_space_io = get_system_io();
DeviceState *dev;
PCIHostState *p;
TyphoonState *s;
PCIHostState *phb;
PCIBus *b;
int i;
dev = qdev_create(NULL, "typhoon-pcihost");
dev = qdev_create(NULL, TYPE_TYPHOON_PCI_HOST_BRIDGE);
qdev_init_nofail(dev);
p = FROM_SYSBUS(PCIHostState, sysbus_from_qdev(dev));
s = container_of(p, TyphoonState, host);
s = TYPHOON_PCI_HOST_BRIDGE(dev);
phb = PCI_HOST_BRIDGE(dev);
/* Remember the CPUs so that we can deliver interrupts to them. */
for (i = 0; i < 4; i++) {
@@ -763,10 +769,10 @@ PCIBus *typhoon_init(ram_addr_t ram_size, ISABus **isa_bus,
memory_region_add_subregion(addr_space, 0x801fc000000ULL,
&s->pchip.reg_io);
b = pci_register_bus(&s->host.busdev.qdev, "pci",
b = pci_register_bus(dev, "pci",
typhoon_set_irq, sys_map_irq, s,
&s->pchip.reg_mem, addr_space_io, 0, 64);
s->host.bus = b;
phb->bus = b;
/* Pchip0 PCI special/interrupt acknowledge, 0x801.F800.0000, 64MB. */
memory_region_init_io(&s->pchip.reg_iack, &alpha_pci_iack_ops, b,
@@ -817,9 +823,9 @@ static void typhoon_pcihost_class_init(ObjectClass *klass, void *data)
dc->no_user = 1;
}
static TypeInfo typhoon_pcihost_info = {
.name = "typhoon-pcihost",
.parent = TYPE_SYS_BUS_DEVICE,
static const TypeInfo typhoon_pcihost_info = {
.name = TYPE_TYPHOON_PCI_HOST_BRIDGE,
.parent = TYPE_PCI_HOST_BRIDGE,
.instance_size = sizeof(TyphoonState),
.class_init = typhoon_pcihost_class_init,
};
+1
View File
@@ -703,6 +703,7 @@ static TypeInfo arm_gic_info = {
.parent = TYPE_ARM_GIC_COMMON,
.instance_size = sizeof(gic_state),
.class_init = arm_gic_class_init,
.class_size = sizeof(ARMGICClass),
};
static void arm_gic_register_types(void)
+93 -59
View File
@@ -180,11 +180,14 @@
#define PCI_ADDR(busno,devno,funno,regno) \
((((busno)<<16)&0xff0000) + (((devno)<<11)&0xf800) + (((funno)<<8)&0x700) + (regno))
typedef PCIHostState BonitoState;
#define TYPE_BONITO_PCI_HOST_BRIDGE "Bonito-pcihost"
typedef struct BonitoState BonitoState;
typedef struct PCIBonitoState
{
PCIDevice dev;
BonitoState *pcihost;
uint32_t regs[BONITO_REGS];
@@ -218,7 +221,16 @@ typedef struct PCIBonitoState
} PCIBonitoState;
PCIBonitoState * bonito_state;
#define BONITO_PCI_HOST_BRIDGE(obj) \
OBJECT_CHECK(BonitoState, (obj), TYPE_BONITO_PCI_HOST_BRIDGE)
struct BonitoState {
PCIHostState parent_obj;
qemu_irq *pic;
PCIBonitoState *pci_dev;
};
static void bonito_writel(void *opaque, target_phys_addr_t addr,
uint64_t val, unsigned size)
@@ -314,9 +326,10 @@ static void bonito_pciconf_writel(void *opaque, target_phys_addr_t addr,
uint64_t val, unsigned size)
{
PCIBonitoState *s = opaque;
PCIDevice *d = PCI_DEVICE(s);
DPRINTF("bonito_pciconf_writel "TARGET_FMT_plx" val %x\n", addr, val);
s->dev.config_write(&s->dev, addr, val, 4);
d->config_write(d, addr, val, 4);
}
static uint64_t bonito_pciconf_readl(void *opaque, target_phys_addr_t addr,
@@ -324,9 +337,10 @@ static uint64_t bonito_pciconf_readl(void *opaque, target_phys_addr_t addr,
{
PCIBonitoState *s = opaque;
PCIDevice *d = PCI_DEVICE(s);
DPRINTF("bonito_pciconf_readl "TARGET_FMT_plx"\n", addr);
return s->dev.config_read(&s->dev, addr, 4);
return d->config_read(d, addr, 4);
}
/* north bridge PCI configure space. 0x1fe0 0000 - 0x1fe0 00ff */
@@ -402,6 +416,7 @@ static const MemoryRegionOps bonito_cop_ops = {
static uint32_t bonito_sbridge_pciaddr(void *opaque, target_phys_addr_t addr)
{
PCIBonitoState *s = opaque;
PCIHostState *phb = PCI_HOST_BRIDGE(s->pcihost);
uint32_t cfgaddr;
uint32_t idsel;
uint32_t devno;
@@ -423,13 +438,13 @@ static uint32_t bonito_sbridge_pciaddr(void *opaque, target_phys_addr_t addr)
regno = (cfgaddr & BONITO_PCICONF_REG_MASK) >> BONITO_PCICONF_REG_OFFSET;
if (idsel == 0) {
fprintf(stderr, "error in bonito pci config address" TARGET_FMT_plx
fprintf(stderr, "error in bonito pci config address " TARGET_FMT_plx
",pcimap_cfg=%x\n", addr, s->regs[BONITO_PCIMAP_CFG]);
exit(1);
}
pciaddr = PCI_ADDR(pci_bus_num(s->pcihost->bus), devno, funno, regno);
pciaddr = PCI_ADDR(pci_bus_num(phb->bus), devno, funno, regno);
DPRINTF("cfgaddr %x pciaddr %x busno %x devno %d funno %d regno %d\n",
cfgaddr, pciaddr, pci_bus_num(s->pcihost->bus), devno, funno, regno);
cfgaddr, pciaddr, pci_bus_num(phb->bus), devno, funno, regno);
return pciaddr;
}
@@ -438,6 +453,8 @@ static void bonito_spciconf_writeb(void *opaque, target_phys_addr_t addr,
uint32_t val)
{
PCIBonitoState *s = opaque;
PCIDevice *d = PCI_DEVICE(s);
PCIHostState *phb = PCI_HOST_BRIDGE(s->pcihost);
uint32_t pciaddr;
uint16_t status;
@@ -449,24 +466,26 @@ static void bonito_spciconf_writeb(void *opaque, target_phys_addr_t addr,
}
/* set the pci address in s->config_reg */
s->pcihost->config_reg = (pciaddr) | (1u << 31);
pci_data_write(s->pcihost->bus, s->pcihost->config_reg, val & 0xff, 1);
phb->config_reg = (pciaddr) | (1u << 31);
pci_data_write(phb->bus, phb->config_reg, val & 0xff, 1);
/* clear PCI_STATUS_REC_MASTER_ABORT and PCI_STATUS_REC_TARGET_ABORT */
status = pci_get_word(s->dev.config + PCI_STATUS);
status = pci_get_word(d->config + PCI_STATUS);
status &= ~(PCI_STATUS_REC_MASTER_ABORT | PCI_STATUS_REC_TARGET_ABORT);
pci_set_word(s->dev.config + PCI_STATUS, status);
pci_set_word(d->config + PCI_STATUS, status);
}
static void bonito_spciconf_writew(void *opaque, target_phys_addr_t addr,
uint32_t val)
{
PCIBonitoState *s = opaque;
PCIDevice *d = PCI_DEVICE(s);
PCIHostState *phb = PCI_HOST_BRIDGE(s->pcihost);
uint32_t pciaddr;
uint16_t status;
DPRINTF("bonito_spciconf_writew "TARGET_FMT_plx" val %x\n", addr, val);
assert((addr&0x1)==0);
assert((addr & 0x1) == 0);
pciaddr = bonito_sbridge_pciaddr(s, addr);
@@ -475,24 +494,26 @@ static void bonito_spciconf_writew(void *opaque, target_phys_addr_t addr,
}
/* set the pci address in s->config_reg */
s->pcihost->config_reg = (pciaddr) | (1u << 31);
pci_data_write(s->pcihost->bus, s->pcihost->config_reg, val, 2);
phb->config_reg = (pciaddr) | (1u << 31);
pci_data_write(phb->bus, phb->config_reg, val, 2);
/* clear PCI_STATUS_REC_MASTER_ABORT and PCI_STATUS_REC_TARGET_ABORT */
status = pci_get_word(s->dev.config + PCI_STATUS);
status = pci_get_word(d->config + PCI_STATUS);
status &= ~(PCI_STATUS_REC_MASTER_ABORT | PCI_STATUS_REC_TARGET_ABORT);
pci_set_word(s->dev.config + PCI_STATUS, status);
pci_set_word(d->config + PCI_STATUS, status);
}
static void bonito_spciconf_writel(void *opaque, target_phys_addr_t addr,
uint32_t val)
{
PCIBonitoState *s = opaque;
PCIDevice *d = PCI_DEVICE(s);
PCIHostState *phb = PCI_HOST_BRIDGE(s->pcihost);
uint32_t pciaddr;
uint16_t status;
DPRINTF("bonito_spciconf_writel "TARGET_FMT_plx" val %x\n", addr, val);
assert((addr&0x3)==0);
assert((addr & 0x3) == 0);
pciaddr = bonito_sbridge_pciaddr(s, addr);
@@ -501,18 +522,20 @@ static void bonito_spciconf_writel(void *opaque, target_phys_addr_t addr,
}
/* set the pci address in s->config_reg */
s->pcihost->config_reg = (pciaddr) | (1u << 31);
pci_data_write(s->pcihost->bus, s->pcihost->config_reg, val, 4);
phb->config_reg = (pciaddr) | (1u << 31);
pci_data_write(phb->bus, phb->config_reg, val, 4);
/* clear PCI_STATUS_REC_MASTER_ABORT and PCI_STATUS_REC_TARGET_ABORT */
status = pci_get_word(s->dev.config + PCI_STATUS);
status = pci_get_word(d->config + PCI_STATUS);
status &= ~(PCI_STATUS_REC_MASTER_ABORT | PCI_STATUS_REC_TARGET_ABORT);
pci_set_word(s->dev.config + PCI_STATUS, status);
pci_set_word(d->config + PCI_STATUS, status);
}
static uint32_t bonito_spciconf_readb(void *opaque, target_phys_addr_t addr)
{
PCIBonitoState *s = opaque;
PCIDevice *d = PCI_DEVICE(s);
PCIHostState *phb = PCI_HOST_BRIDGE(s->pcihost);
uint32_t pciaddr;
uint16_t status;
@@ -524,24 +547,26 @@ static uint32_t bonito_spciconf_readb(void *opaque, target_phys_addr_t addr)
}
/* set the pci address in s->config_reg */
s->pcihost->config_reg = (pciaddr) | (1u << 31);
phb->config_reg = (pciaddr) | (1u << 31);
/* clear PCI_STATUS_REC_MASTER_ABORT and PCI_STATUS_REC_TARGET_ABORT */
status = pci_get_word(s->dev.config + PCI_STATUS);
status = pci_get_word(d->config + PCI_STATUS);
status &= ~(PCI_STATUS_REC_MASTER_ABORT | PCI_STATUS_REC_TARGET_ABORT);
pci_set_word(s->dev.config + PCI_STATUS, status);
pci_set_word(d->config + PCI_STATUS, status);
return pci_data_read(s->pcihost->bus, s->pcihost->config_reg, 1);
return pci_data_read(phb->bus, phb->config_reg, 1);
}
static uint32_t bonito_spciconf_readw(void *opaque, target_phys_addr_t addr)
{
PCIBonitoState *s = opaque;
PCIDevice *d = PCI_DEVICE(s);
PCIHostState *phb = PCI_HOST_BRIDGE(s->pcihost);
uint32_t pciaddr;
uint16_t status;
DPRINTF("bonito_spciconf_readw "TARGET_FMT_plx"\n", addr);
assert((addr&0x1)==0);
assert((addr & 0x1) == 0);
pciaddr = bonito_sbridge_pciaddr(s, addr);
@@ -550,24 +575,26 @@ static uint32_t bonito_spciconf_readw(void *opaque, target_phys_addr_t addr)
}
/* set the pci address in s->config_reg */
s->pcihost->config_reg = (pciaddr) | (1u << 31);
phb->config_reg = (pciaddr) | (1u << 31);
/* clear PCI_STATUS_REC_MASTER_ABORT and PCI_STATUS_REC_TARGET_ABORT */
status = pci_get_word(s->dev.config + PCI_STATUS);
status = pci_get_word(d->config + PCI_STATUS);
status &= ~(PCI_STATUS_REC_MASTER_ABORT | PCI_STATUS_REC_TARGET_ABORT);
pci_set_word(s->dev.config + PCI_STATUS, status);
pci_set_word(d->config + PCI_STATUS, status);
return pci_data_read(s->pcihost->bus, s->pcihost->config_reg, 2);
return pci_data_read(phb->bus, phb->config_reg, 2);
}
static uint32_t bonito_spciconf_readl(void *opaque, target_phys_addr_t addr)
{
PCIBonitoState *s = opaque;
PCIDevice *d = PCI_DEVICE(s);
PCIHostState *phb = PCI_HOST_BRIDGE(s->pcihost);
uint32_t pciaddr;
uint16_t status;
DPRINTF("bonito_spciconf_readl "TARGET_FMT_plx"\n", addr);
assert((addr&0x3) == 0);
assert((addr & 0x3) == 0);
pciaddr = bonito_sbridge_pciaddr(s, addr);
@@ -576,14 +603,14 @@ static uint32_t bonito_spciconf_readl(void *opaque, target_phys_addr_t addr)
}
/* set the pci address in s->config_reg */
s->pcihost->config_reg = (pciaddr) | (1u << 31);
phb->config_reg = (pciaddr) | (1u << 31);
/* clear PCI_STATUS_REC_MASTER_ABORT and PCI_STATUS_REC_TARGET_ABORT */
status = pci_get_word(s->dev.config + PCI_STATUS);
status = pci_get_word(d->config + PCI_STATUS);
status &= ~(PCI_STATUS_REC_MASTER_ABORT | PCI_STATUS_REC_TARGET_ABORT);
pci_set_word(s->dev.config + PCI_STATUS, status);
pci_set_word(d->config + PCI_STATUS, status);
return pci_data_read(s->pcihost->bus, s->pcihost->config_reg, 4);
return pci_data_read(phb->bus, phb->config_reg, 4);
}
/* south bridge PCI configure space. 0x1fe8 0000 - 0x1fef ffff */
@@ -607,13 +634,15 @@ static const MemoryRegionOps bonito_spciconf_ops = {
static void pci_bonito_set_irq(void *opaque, int irq_num, int level)
{
qemu_irq *pic = opaque;
BonitoState *s = opaque;
qemu_irq *pic = s->pic;
PCIBonitoState *bonito_state = s->pci_dev;
int internal_irq = irq_num - BONITO_IRQ_BASE;
if (bonito_state->regs[BONITO_INTEDGE] & (1<<internal_irq)) {
if (bonito_state->regs[BONITO_INTEDGE] & (1 << internal_irq)) {
qemu_irq_pulse(*pic);
} else { /* level triggered */
if (bonito_state->regs[BONITO_INTPOL] & (1<<internal_irq)) {
if (bonito_state->regs[BONITO_INTPOL] & (1 << internal_irq)) {
qemu_irq_raise(*pic);
} else {
qemu_irq_lower(*pic);
@@ -673,13 +702,21 @@ static const VMStateDescription vmstate_bonito = {
static int bonito_pcihost_initfn(SysBusDevice *dev)
{
PCIHostState *phb = PCI_HOST_BRIDGE(dev);
phb->bus = pci_register_bus(DEVICE(dev), "pci",
pci_bonito_set_irq, pci_bonito_map_irq, dev,
get_system_memory(), get_system_io(),
0x28, 32);
return 0;
}
static int bonito_initfn(PCIDevice *dev)
{
PCIBonitoState *s = DO_UPCAST(PCIBonitoState, dev, dev);
SysBusDevice *sysbus = &s->pcihost->busdev;
SysBusDevice *sysbus = SYS_BUS_DEVICE(s->pcihost);
PCIHostState *phb = PCI_HOST_BRIDGE(s->pcihost);
/* Bonito North Bridge, built on FPGA, VENDOR_ID/DEVICE_ID are "undefined" */
pci_config_set_prog_interface(dev->config, 0x00);
@@ -691,15 +728,15 @@ static int bonito_initfn(PCIDevice *dev)
sysbus_mmio_map(sysbus, 0, BONITO_INTERNAL_REG_BASE);
/* set the north bridge pci configure mapping */
memory_region_init_io(&s->pcihost->conf_mem, &bonito_pciconf_ops, s,
memory_region_init_io(&phb->conf_mem, &bonito_pciconf_ops, s,
"north-bridge-pci-config", BONITO_PCICONFIG_SIZE);
sysbus_init_mmio(sysbus, &s->pcihost->conf_mem);
sysbus_init_mmio(sysbus, &phb->conf_mem);
sysbus_mmio_map(sysbus, 1, BONITO_PCICONFIG_BASE);
/* set the south bridge pci configure mapping */
memory_region_init_io(&s->pcihost->data_mem, &bonito_spciconf_ops, s,
memory_region_init_io(&phb->data_mem, &bonito_spciconf_ops, s,
"south-bridge-pci-config", BONITO_SPCICONFIG_SIZE);
sysbus_init_mmio(sysbus, &s->pcihost->data_mem);
sysbus_init_mmio(sysbus, &phb->data_mem);
sysbus_mmio_map(sysbus, 2, BONITO_SPCICONFIG_BASE);
memory_region_init_io(&s->iomem_ldma, &bonito_ldma_ops, s,
@@ -742,28 +779,25 @@ static int bonito_initfn(PCIDevice *dev)
PCIBus *bonito_init(qemu_irq *pic)
{
DeviceState *dev;
PCIBus *b;
BonitoState *pcihost;
PCIHostState *phb;
PCIBonitoState *s;
PCIDevice *d;
dev = qdev_create(NULL, "Bonito-pcihost");
pcihost = FROM_SYSBUS(BonitoState, sysbus_from_qdev(dev));
b = pci_register_bus(&pcihost->busdev.qdev, "pci", pci_bonito_set_irq,
pci_bonito_map_irq, pic, get_system_memory(),
get_system_io(),
0x28, 32);
pcihost->bus = b;
dev = qdev_create(NULL, TYPE_BONITO_PCI_HOST_BRIDGE);
phb = PCI_HOST_BRIDGE(dev);
pcihost = BONITO_PCI_HOST_BRIDGE(dev);
pcihost->pic = pic;
qdev_init_nofail(dev);
/* set the pcihost pointer before bonito_initfn is called */
d = pci_create(b, PCI_DEVFN(0, 0), "Bonito");
d = pci_create(phb->bus, PCI_DEVFN(0, 0), "Bonito");
s = DO_UPCAST(PCIBonitoState, dev, d);
s->pcihost = pcihost;
bonito_state = s;
qdev_init_nofail(&d->qdev);
pcihost->pci_dev = s;
qdev_init_nofail(DEVICE(d));
return b;
return phb->bus;
}
static void bonito_class_init(ObjectClass *klass, void *data)
@@ -781,7 +815,7 @@ static void bonito_class_init(ObjectClass *klass, void *data)
dc->vmsd = &vmstate_bonito;
}
static TypeInfo bonito_info = {
static const TypeInfo bonito_info = {
.name = "Bonito",
.parent = TYPE_PCI_DEVICE,
.instance_size = sizeof(PCIBonitoState),
@@ -797,9 +831,9 @@ static void bonito_pcihost_class_init(ObjectClass *klass, void *data)
dc->no_user = 1;
}
static TypeInfo bonito_pcihost_info = {
.name = "Bonito-pcihost",
.parent = TYPE_SYS_BUS_DEVICE,
static const TypeInfo bonito_pcihost_info = {
.name = TYPE_BONITO_PCI_HOST_BRIDGE,
.parent = TYPE_PCI_HOST_BRIDGE,
.instance_size = sizeof(BonitoState),
.class_init = bonito_pcihost_class_init,
};
+16 -15
View File
@@ -40,9 +40,10 @@
#define DEC_DPRINTF(fmt, ...)
#endif
#define DEC_21154(obj) OBJECT_CHECK(DECState, (obj), TYPE_DEC_21154)
typedef struct DECState {
SysBusDevice busdev;
PCIHostState host_state;
PCIHostState parent_obj;
} DECState;
static int dec_map_irq(PCIDevice *pci_dev, int irq_num)
@@ -66,7 +67,7 @@ static void dec_21154_pci_bridge_class_init(ObjectClass *klass, void *data)
dc->vmsd = &vmstate_pci_device;
}
static TypeInfo dec_21154_pci_bridge_info = {
static const TypeInfo dec_21154_pci_bridge_info = {
.name = "dec-21154-p2p-bridge",
.parent = TYPE_PCI_DEVICE,
.instance_size = sizeof(PCIBridge),
@@ -88,16 +89,16 @@ PCIBus *pci_dec_21154_init(PCIBus *parent_bus, int devfn)
static int pci_dec_21154_device_init(SysBusDevice *dev)
{
DECState *s;
PCIHostState *phb;
s = FROM_SYSBUS(DECState, dev);
phb = PCI_HOST_BRIDGE(dev);
memory_region_init_io(&s->host_state.conf_mem, &pci_host_conf_le_ops,
&s->host_state, "pci-conf-idx", 0x1000);
memory_region_init_io(&s->host_state.data_mem, &pci_host_data_le_ops,
&s->host_state, "pci-data-idx", 0x1000);
sysbus_init_mmio(dev, &s->host_state.conf_mem);
sysbus_init_mmio(dev, &s->host_state.data_mem);
memory_region_init_io(&phb->conf_mem, &pci_host_conf_le_ops,
dev, "pci-conf-idx", 0x1000);
memory_region_init_io(&phb->data_mem, &pci_host_data_le_ops,
dev, "pci-data-idx", 0x1000);
sysbus_init_mmio(dev, &phb->conf_mem);
sysbus_init_mmio(dev, &phb->data_mem);
return 0;
}
@@ -119,7 +120,7 @@ static void dec_21154_pci_host_class_init(ObjectClass *klass, void *data)
k->is_bridge = 1;
}
static TypeInfo dec_21154_pci_host_info = {
static const TypeInfo dec_21154_pci_host_info = {
.name = "dec-21154",
.parent = TYPE_PCI_DEVICE,
.instance_size = sizeof(PCIDevice),
@@ -133,9 +134,9 @@ static void pci_dec_21154_device_class_init(ObjectClass *klass, void *data)
sdc->init = pci_dec_21154_device_init;
}
static TypeInfo pci_dec_21154_device_info = {
.name = "dec-21154-sysbus",
.parent = TYPE_SYS_BUS_DEVICE,
static const TypeInfo pci_dec_21154_device_info = {
.name = TYPE_DEC_21154,
.parent = TYPE_PCI_HOST_BRIDGE,
.instance_size = sizeof(DECState),
.class_init = pci_dec_21154_device_class_init,
};
+2
View File
@@ -3,6 +3,8 @@
#include "qemu-common.h"
#define TYPE_DEC_21154 "dec-21154-sysbus"
PCIBus *pci_dec_21154_init(PCIBus *parent_bus, int devfn);
#endif
+11 -5
View File
@@ -87,7 +87,9 @@ static uint32_t get_cmd(ESPState *s, uint8_t *buf)
target = s->wregs[ESP_WBUSID] & BUSID_DID;
if (s->dma) {
dmalen = s->rregs[ESP_TCLO] | (s->rregs[ESP_TCMID] << 8);
dmalen = s->rregs[ESP_TCLO];
dmalen |= s->rregs[ESP_TCMID] << 8;
dmalen |= s->rregs[ESP_TCHI] << 16;
s->dma_memory_read(s->dma_opaque, buf, dmalen);
} else {
dmalen = s->ti_size;
@@ -226,6 +228,7 @@ static void esp_dma_done(ESPState *s)
s->rregs[ESP_RFLAGS] = 0;
s->rregs[ESP_TCLO] = 0;
s->rregs[ESP_TCMID] = 0;
s->rregs[ESP_TCHI] = 0;
esp_raise_irq(s);
}
@@ -328,7 +331,9 @@ static void handle_ti(ESPState *s)
return;
}
dmalen = s->rregs[ESP_TCLO] | (s->rregs[ESP_TCMID] << 8);
dmalen = s->rregs[ESP_TCLO];
dmalen |= s->rregs[ESP_TCMID] << 8;
dmalen |= s->rregs[ESP_TCHI] << 16;
if (dmalen==0) {
dmalen=0x10000;
}
@@ -429,6 +434,7 @@ void esp_reg_write(ESPState *s, uint32_t saddr, uint64_t val)
switch (saddr) {
case ESP_TCLO:
case ESP_TCMID:
case ESP_TCHI:
s->rregs[ESP_RSTAT] &= ~STAT_TC;
break;
case ESP_FIFO:
@@ -448,6 +454,7 @@ void esp_reg_write(ESPState *s, uint32_t saddr, uint64_t val)
/* Reload DMA counter. */
s->rregs[ESP_TCLO] = s->wregs[ESP_TCLO];
s->rregs[ESP_TCMID] = s->wregs[ESP_TCMID];
s->rregs[ESP_TCHI] = s->wregs[ESP_TCHI];
} else {
s->dma = 0;
}
@@ -530,13 +537,12 @@ void esp_reg_write(ESPState *s, uint32_t saddr, uint64_t val)
case ESP_WBUSID ... ESP_WSYNO:
break;
case ESP_CFG1:
case ESP_CFG2: case ESP_CFG3:
case ESP_RES3: case ESP_RES4:
s->rregs[saddr] = val;
break;
case ESP_WCCF ... ESP_WTEST:
break;
case ESP_CFG2 ... ESP_RES4:
s->rregs[saddr] = val;
break;
default:
trace_esp_error_invalid_write(val, saddr);
return;
+32 -33
View File
@@ -23,10 +23,9 @@
* THE SOFTWARE.
*/
#include "sysbus.h"
#include "pci_host.h"
#include "ppc_mac.h"
#include "pci.h"
#include "pci_host.h"
/* debug Grackle */
//#define DEBUG_GRACKLE
@@ -38,9 +37,12 @@
#define GRACKLE_DPRINTF(fmt, ...)
#endif
#define GRACKLE_PCI_HOST_BRIDGE(obj) \
OBJECT_CHECK(GrackleState, (obj), TYPE_GRACKLE_PCI_HOST_BRIDGE)
typedef struct GrackleState {
SysBusDevice busdev;
PCIHostState host_state;
PCIHostState parent_obj;
MemoryRegion pci_mmio;
MemoryRegion pci_hole;
} GrackleState;
@@ -59,22 +61,20 @@ static void pci_grackle_set_irq(void *opaque, int irq_num, int level)
qemu_set_irq(pic[irq_num + 0x15], level);
}
static void pci_grackle_reset(void *opaque)
{
}
PCIBus *pci_grackle_init(uint32_t base, qemu_irq *pic,
MemoryRegion *address_space_mem,
MemoryRegion *address_space_io)
{
DeviceState *dev;
SysBusDevice *s;
PCIHostState *phb;
GrackleState *d;
dev = qdev_create(NULL, "grackle-pcihost");
dev = qdev_create(NULL, TYPE_GRACKLE_PCI_HOST_BRIDGE);
qdev_init_nofail(dev);
s = sysbus_from_qdev(dev);
d = FROM_SYSBUS(GrackleState, s);
s = SYS_BUS_DEVICE(dev);
phb = PCI_HOST_BRIDGE(dev);
d = GRACKLE_PCI_HOST_BRIDGE(dev);
memory_region_init(&d->pci_mmio, "pci-mmio", 0x100000000ULL);
memory_region_init_alias(&d->pci_hole, "pci-hole", &d->pci_mmio,
@@ -82,36 +82,35 @@ PCIBus *pci_grackle_init(uint32_t base, qemu_irq *pic,
memory_region_add_subregion(address_space_mem, 0x80000000ULL,
&d->pci_hole);
d->host_state.bus = pci_register_bus(&d->busdev.qdev, "pci",
pci_grackle_set_irq,
pci_grackle_map_irq,
pic,
&d->pci_mmio,
address_space_io,
0, 4);
phb->bus = pci_register_bus(dev, "pci",
pci_grackle_set_irq,
pci_grackle_map_irq,
pic,
&d->pci_mmio,
address_space_io,
0, 4);
pci_create_simple(d->host_state.bus, 0, "grackle");
pci_create_simple(phb->bus, 0, "grackle");
sysbus_mmio_map(s, 0, base);
sysbus_mmio_map(s, 1, base + 0x00200000);
return d->host_state.bus;
return phb->bus;
}
static int pci_grackle_init_device(SysBusDevice *dev)
{
GrackleState *s;
PCIHostState *phb;
s = FROM_SYSBUS(GrackleState, dev);
phb = PCI_HOST_BRIDGE(dev);
memory_region_init_io(&s->host_state.conf_mem, &pci_host_conf_le_ops,
&s->host_state, "pci-conf-idx", 0x1000);
memory_region_init_io(&s->host_state.data_mem, &pci_host_data_le_ops,
&s->host_state, "pci-data-idx", 0x1000);
sysbus_init_mmio(dev, &s->host_state.conf_mem);
sysbus_init_mmio(dev, &s->host_state.data_mem);
memory_region_init_io(&phb->conf_mem, &pci_host_conf_le_ops,
dev, "pci-conf-idx", 0x1000);
memory_region_init_io(&phb->data_mem, &pci_host_data_le_ops,
dev, "pci-data-idx", 0x1000);
sysbus_init_mmio(dev, &phb->conf_mem);
sysbus_init_mmio(dev, &phb->data_mem);
qemu_register_reset(pci_grackle_reset, &s->host_state);
return 0;
}
@@ -134,7 +133,7 @@ static void grackle_pci_class_init(ObjectClass *klass, void *data)
dc->no_user = 1;
}
static TypeInfo grackle_pci_info = {
static const TypeInfo grackle_pci_info = {
.name = "grackle",
.parent = TYPE_PCI_DEVICE,
.instance_size = sizeof(PCIDevice),
@@ -150,9 +149,9 @@ static void pci_grackle_class_init(ObjectClass *klass, void *data)
dc->no_user = 1;
}
static TypeInfo grackle_pci_host_info = {
.name = "grackle-pcihost",
.parent = TYPE_SYS_BUS_DEVICE,
static const TypeInfo grackle_pci_host_info = {
.name = TYPE_GRACKLE_PCI_HOST_BRIDGE,
.parent = TYPE_PCI_HOST_BRIDGE,
.instance_size = sizeof(GrackleState),
.class_init = pci_grackle_class_init,
};
+39 -28
View File
@@ -229,9 +229,14 @@
target_phys_addr_t regname ##_length; \
MemoryRegion regname ##_mem
#define TYPE_GT64120_PCI_HOST_BRIDGE "gt64120"
#define GT64120_PCI_HOST_BRIDGE(obj) \
OBJECT_CHECK(GT64120State, (obj), TYPE_GT64120_PCI_HOST_BRIDGE)
typedef struct GT64120State {
SysBusDevice busdev;
PCIHostState pci;
PCIHostState parent_obj;
uint32_t regs[GT_REGS];
PCI_MAPPING_ENTRY(PCI0IO);
PCI_MAPPING_ENTRY(ISD);
@@ -310,6 +315,7 @@ static void gt64120_writel (void *opaque, target_phys_addr_t addr,
uint64_t val, unsigned size)
{
GT64120State *s = opaque;
PCIHostState *phb = PCI_HOST_BRIDGE(s);
uint32_t saddr;
if (!(s->regs[GT_CPU] & 0x00001000))
@@ -530,13 +536,15 @@ static void gt64120_writel (void *opaque, target_phys_addr_t addr,
/* not implemented */
break;
case GT_PCI0_CFGADDR:
s->pci.config_reg = val & 0x80fffffc;
phb->config_reg = val & 0x80fffffc;
break;
case GT_PCI0_CFGDATA:
if (!(s->regs[GT_PCI0_CMD] & 1) && (s->pci.config_reg & 0x00fff800))
if (!(s->regs[GT_PCI0_CMD] & 1) && (phb->config_reg & 0x00fff800)) {
val = bswap32(val);
if (s->pci.config_reg & (1u << 31))
pci_data_write(s->pci.bus, s->pci.config_reg, val, 4);
}
if (phb->config_reg & (1u << 31)) {
pci_data_write(phb->bus, phb->config_reg, val, 4);
}
break;
/* Interrupts */
@@ -589,6 +597,7 @@ static uint64_t gt64120_readl (void *opaque,
target_phys_addr_t addr, unsigned size)
{
GT64120State *s = opaque;
PCIHostState *phb = PCI_HOST_BRIDGE(s);
uint32_t val;
uint32_t saddr;
@@ -770,15 +779,17 @@ static uint64_t gt64120_readl (void *opaque,
/* PCI Internal */
case GT_PCI0_CFGADDR:
val = s->pci.config_reg;
val = phb->config_reg;
break;
case GT_PCI0_CFGDATA:
if (!(s->pci.config_reg & (1 << 31)))
if (!(phb->config_reg & (1 << 31))) {
val = 0xffffffff;
else
val = pci_data_read(s->pci.bus, s->pci.config_reg, 4);
if (!(s->regs[GT_PCI0_CMD] & 1) && (s->pci.config_reg & 0x00fff800))
} else {
val = pci_data_read(phb->bus, phb->config_reg, 4);
}
if (!(s->regs[GT_PCI0_CMD] & 1) && (phb->config_reg & 0x00fff800)) {
val = bswap32(val);
}
break;
case GT_PCI0_CMD:
@@ -1083,31 +1094,31 @@ static void gt64120_reset(void *opaque)
PCIBus *gt64120_register(qemu_irq *pic)
{
SysBusDevice *s;
GT64120State *d;
PCIHostState *phb;
DeviceState *dev;
dev = qdev_create(NULL, "gt64120");
dev = qdev_create(NULL, TYPE_GT64120_PCI_HOST_BRIDGE);
qdev_init_nofail(dev);
s = sysbus_from_qdev(dev);
d = FROM_SYSBUS(GT64120State, s);
d->pci.bus = pci_register_bus(&d->busdev.qdev, "pci",
gt64120_pci_set_irq, gt64120_pci_map_irq,
pic,
get_system_memory(),
get_system_io(),
PCI_DEVFN(18, 0), 4);
d = GT64120_PCI_HOST_BRIDGE(dev);
phb = PCI_HOST_BRIDGE(dev);
phb->bus = pci_register_bus(dev, "pci",
gt64120_pci_set_irq, gt64120_pci_map_irq,
pic,
get_system_memory(),
get_system_io(),
PCI_DEVFN(18, 0), 4);
memory_region_init_io(&d->ISD_mem, &isd_mem_ops, d, "isd-mem", 0x1000);
pci_create_simple(d->pci.bus, PCI_DEVFN(0, 0), "gt64120_pci");
return d->pci.bus;
pci_create_simple(phb->bus, PCI_DEVFN(0, 0), "gt64120_pci");
return phb->bus;
}
static int gt64120_init(SysBusDevice *dev)
{
GT64120State *s;
s = FROM_SYSBUS(GT64120State, dev);
s = GT64120_PCI_HOST_BRIDGE(dev);
/* FIXME: This value is computed from registers during reset, but some
devices (e.g. VGA card) need to know it when they are registered.
@@ -1147,7 +1158,7 @@ static void gt64120_pci_class_init(ObjectClass *klass, void *data)
k->class_id = PCI_CLASS_BRIDGE_HOST;
}
static TypeInfo gt64120_pci_info = {
static const TypeInfo gt64120_pci_info = {
.name = "gt64120_pci",
.parent = TYPE_PCI_DEVICE,
.instance_size = sizeof(PCIDevice),
@@ -1161,9 +1172,9 @@ static void gt64120_class_init(ObjectClass *klass, void *data)
sdc->init = gt64120_init;
}
static TypeInfo gt64120_info = {
.name = "gt64120",
.parent = TYPE_SYS_BUS_DEVICE,
static const TypeInfo gt64120_info = {
.name = TYPE_GT64120_PCI_HOST_BRIDGE,
.parent = TYPE_PCI_HOST_BRIDGE,
.instance_size = sizeof(GT64120State),
.class_init = gt64120_class_init,
};
-1
View File
@@ -225,7 +225,6 @@ static int pci_i82378_init(PCIDevice *dev)
pci_register_bar(dev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->io);
memory_region_init_io(&s->mem, &i82378_mem_ops, s, "i82378-mem", 0x01000000);
memory_region_set_coalescing(&s->mem);
pci_register_bar(dev, 1, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->mem);
/* Make I/O address read only */
+4 -15
View File
@@ -366,6 +366,10 @@ static void close_guest_eventfds(IVShmemState *s, int posn)
{
int i, guest_curr_max;
if (!ivshmem_has_feature(s, IVSHMEM_IOEVENTFD)) {
return;
}
guest_curr_max = s->peers[posn].nb_eventfds;
memory_region_transaction_begin();
@@ -381,17 +385,6 @@ static void close_guest_eventfds(IVShmemState *s, int posn)
s->peers[posn].nb_eventfds = 0;
}
static void setup_ioeventfds(IVShmemState *s) {
int i, j;
for (i = 0; i <= s->max_peer; i++) {
for (j = 0; j < s->peers[i].nb_eventfds; j++) {
ivshmem_add_eventfd(s, i, j);
}
}
}
/* this function increase the dynamic storage need to store data about other
* guests */
static void increase_dynamic_storage(IVShmemState *s, int new_min_size) {
@@ -692,10 +685,6 @@ static int pci_ivshmem_init(PCIDevice *dev)
memory_region_init_io(&s->ivshmem_mmio, &ivshmem_mmio_ops, s,
"ivshmem-mmio", IVSHMEM_REG_BAR_SIZE);
if (ivshmem_has_feature(s, IVSHMEM_IOEVENTFD)) {
setup_ioeventfds(s);
}
/* region for registers*/
pci_register_bar(&s->dev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY,
&s->ivshmem_mmio);
+7 -2
View File
@@ -38,6 +38,7 @@
#define MEGASAS_MAX_SECTORS 0xFFFF /* No real limit */
#define MEGASAS_MAX_ARRAYS 128
#define MEGASAS_HBA_SERIAL "QEMU123456"
#define NAA_LOCALLY_ASSIGNED_ID 0x3ULL
#define IEEE_COMPANY_LOCALLY_ASSIGNED 0x525400
@@ -93,6 +94,7 @@ typedef struct MegasasState {
int boot_event;
uint64_t sas_addr;
char *hba_serial;
uint64_t reply_queue_pa;
void *reply_queue;
@@ -698,8 +700,7 @@ static int megasas_ctrl_get_info(MegasasState *s, MegasasCmd *cmd)
}
memcpy(info.product_name, "MegaRAID SAS 8708EM2", 20);
snprintf(info.serial_number, 32, "QEMU%08lx",
(unsigned long)s & 0xFFFFFFFF);
snprintf(info.serial_number, 32, "%s", s->hba_serial);
snprintf(info.package_version, 0x60, "%s-QEMU", QEMU_VERSION);
memcpy(info.image_component[0].name, "APP", 3);
memcpy(info.image_component[0].version, MEGASAS_VERSION "-QEMU", 9);
@@ -2132,6 +2133,9 @@ static int megasas_scsi_init(PCIDevice *dev)
s->sas_addr |= (PCI_SLOT(dev->devfn) << 8);
s->sas_addr |= PCI_FUNC(dev->devfn);
}
if (!s->hba_serial) {
s->hba_serial = g_strdup(MEGASAS_HBA_SERIAL);
}
if (s->fw_sge >= MEGASAS_MAX_SGE - MFI_PASS_FRAME_SIZE) {
s->fw_sge = MEGASAS_MAX_SGE - MFI_PASS_FRAME_SIZE;
} else if (s->fw_sge >= 128 - MFI_PASS_FRAME_SIZE) {
@@ -2166,6 +2170,7 @@ static Property megasas_properties[] = {
MEGASAS_DEFAULT_SGE),
DEFINE_PROP_UINT32("max_cmds", MegasasState, fw_cmds,
MEGASAS_DEFAULT_FRAMES),
DEFINE_PROP_STRING("hba_serial", MegasasState, hba_serial),
DEFINE_PROP_HEX64("sas_address", MegasasState, sas_addr, 0),
#ifdef USE_MSIX
DEFINE_PROP_BIT("use_msix", MegasasState, flags,
+13 -8
View File
@@ -307,13 +307,9 @@ int msix_init_exclusive_bar(PCIDevice *dev, unsigned short nentries,
return -EINVAL;
}
if (asprintf(&name, "%s-msix", dev->name) == -1) {
return -ENOMEM;
}
name = g_strdup_printf("%s-msix", dev->name);
memory_region_init(&dev->msix_exclusive_bar, name, MSIX_EXCLUSIVE_BAR_SIZE);
free(name);
g_free(name);
ret = msix_init(dev, nentries, &dev->msix_exclusive_bar, bar_nr,
MSIX_EXCLUSIVE_BAR_TABLE_OFFSET, &dev->msix_exclusive_bar,
@@ -340,6 +336,15 @@ static void msix_free_irq_entries(PCIDevice *dev)
}
}
static void msix_clear_all_vectors(PCIDevice *dev)
{
int vector;
for (vector = 0; vector < dev->msix_entries_nr; ++vector) {
msix_clr_pending(dev, vector);
}
}
/* Clean up resources for the device. */
void msix_uninit(PCIDevice *dev, MemoryRegion *table_bar, MemoryRegion *pba_bar)
{
@@ -394,7 +399,7 @@ void msix_load(PCIDevice *dev, QEMUFile *f)
return;
}
msix_free_irq_entries(dev);
msix_clear_all_vectors(dev);
qemu_get_buffer(f, dev->msix_table, n * PCI_MSIX_ENTRY_SIZE);
qemu_get_buffer(f, dev->msix_pba, (n + 7) / 8);
msix_update_function_masked(dev);
@@ -440,7 +445,7 @@ void msix_reset(PCIDevice *dev)
if (!msix_present(dev)) {
return;
}
msix_free_irq_entries(dev);
msix_clear_all_vectors(dev);
dev->config[dev->msix_cap + MSIX_CONTROL_OFFSET] &=
~dev->wmask[dev->msix_cap + MSIX_CONTROL_OFFSET];
memset(dev->msix_table, 0, dev->msix_entries_nr * PCI_MSIX_ENTRY_SIZE);
+40
View File
@@ -0,0 +1,40 @@
/*
* Empty machine
*
* Copyright IBM, Corp. 2012
*
* Authors:
* Anthony Liguori <aliguori@us.ibm.com>
*
* This work is licensed under the terms of the GNU GPL, version 2 or later.
* See the COPYING file in the top-level directory.
*
*/
#include "qemu-common.h"
#include "hw/hw.h"
#include "hw/boards.h"
static void machine_none_init(ram_addr_t ram_size,
const char *boot_device,
const char *kernel_filename,
const char *kernel_cmdline,
const char *initrd_filename,
const char *cpu_model)
{
}
static QEMUMachine machine_none = {
.name = "none",
.desc = "empty machine",
.init = machine_none_init,
.max_cpus = 0,
};
static void register_machines(void)
{
qemu_register_machine(&machine_none);
}
machine_init(register_machines);
+18 -13
View File
@@ -338,32 +338,37 @@ void pc_cmos_init(ram_addr_t ram_size, ram_addr_t above_4g_mem_size,
/* various important CMOS locations needed by PC/Bochs bios */
/* memory size */
val = 640; /* base memory in K */
/* base memory (first MiB) */
val = MIN(ram_size / 1024, 640);
rtc_set_memory(s, 0x15, val);
rtc_set_memory(s, 0x16, val >> 8);
val = (ram_size / 1024) - 1024;
/* extended memory (next 64MiB) */
if (ram_size > 1024 * 1024) {
val = (ram_size - 1024 * 1024) / 1024;
} else {
val = 0;
}
if (val > 65535)
val = 65535;
rtc_set_memory(s, 0x17, val);
rtc_set_memory(s, 0x18, val >> 8);
rtc_set_memory(s, 0x30, val);
rtc_set_memory(s, 0x31, val >> 8);
if (above_4g_mem_size) {
rtc_set_memory(s, 0x5b, (unsigned int)above_4g_mem_size >> 16);
rtc_set_memory(s, 0x5c, (unsigned int)above_4g_mem_size >> 24);
rtc_set_memory(s, 0x5d, (uint64_t)above_4g_mem_size >> 32);
}
if (ram_size > (16 * 1024 * 1024))
val = (ram_size / 65536) - ((16 * 1024 * 1024) / 65536);
else
/* memory between 16MiB and 4GiB */
if (ram_size > 16 * 1024 * 1024) {
val = (ram_size - 16 * 1024 * 1024) / 65536;
} else {
val = 0;
}
if (val > 65535)
val = 65535;
rtc_set_memory(s, 0x34, val);
rtc_set_memory(s, 0x35, val >> 8);
/* memory above 4GiB */
val = above_4g_mem_size / 65536;
rtc_set_memory(s, 0x5b, val);
rtc_set_memory(s, 0x5c, val >> 8);
rtc_set_memory(s, 0x5d, val >> 16);
/* set the number of CPU */
rtc_set_memory(s, 0x5f, smp_cpus - 1);
+12
View File
@@ -360,6 +360,14 @@ static QEMUMachine pc_machine_v1_2 = {
#define PC_COMPAT_1_1 \
{\
.driver = "virtio-scsi-pci",\
.property = "hotplug",\
.value = "off",\
},{\
.driver = "virtio-scsi-pci",\
.property = "param_change",\
.value = "off",\
},{\
.driver = "VGA",\
.property = "vgamem_mb",\
.value = stringify(8),\
@@ -375,6 +383,10 @@ static QEMUMachine pc_machine_v1_2 = {
.driver = "qxl",\
.property = "vgamem_mb",\
.value = stringify(8),\
},{\
.driver = "virtio-blk-pci",\
.property = "config-wce",\
.value = "off",\
}
static QEMUMachine pc_machine_v1_1 = {
+12
View File
@@ -165,4 +165,16 @@ const MemoryRegionOps pci_host_data_be_ops = {
.endianness = DEVICE_BIG_ENDIAN,
};
static const TypeInfo pci_host_type_info = {
.name = TYPE_PCI_HOST_BRIDGE,
.parent = TYPE_SYS_BUS_DEVICE,
.abstract = true,
.instance_size = sizeof(PCIHostState),
};
static void pci_host_register_types(void)
{
type_register_static(&pci_host_type_info);
}
type_init(pci_host_register_types)
+5
View File
@@ -30,8 +30,13 @@
#include "sysbus.h"
#define TYPE_PCI_HOST_BRIDGE "pci-host-bridge"
#define PCI_HOST_BRIDGE(obj) \
OBJECT_CHECK(PCIHostState, (obj), TYPE_PCI_HOST_BRIDGE)
struct PCIHostState {
SysBusDevice busdev;
MemoryRegion conf_mem;
MemoryRegion data_mem;
MemoryRegion mmcfg;
+12 -10
View File
@@ -36,7 +36,9 @@
* http://download.intel.com/design/chipsets/datashts/29054901.pdf
*/
typedef PCIHostState I440FXState;
typedef struct I440FXState {
PCIHostState parent_obj;
} I440FXState;
#define PIIX_NUM_PIC_IRQS 16 /* i8259 * 2 */
#define PIIX_NUM_PIRQS 4ULL /* PIRQ[A-D] */
@@ -225,7 +227,7 @@ static const VMStateDescription vmstate_i440fx = {
static int i440fx_pcihost_initfn(SysBusDevice *dev)
{
I440FXState *s = FROM_SYSBUS(I440FXState, dev);
PCIHostState *s = PCI_HOST_BRIDGE(dev);
memory_region_init_io(&s->conf_mem, &pci_host_conf_le_ops, s,
"pci-conf-idx", 4);
@@ -267,14 +269,14 @@ static PCIBus *i440fx_common_init(const char *device_name,
DeviceState *dev;
PCIBus *b;
PCIDevice *d;
I440FXState *s;
PCIHostState *s;
PIIX3State *piix3;
PCII440FXState *f;
dev = qdev_create(NULL, "i440FX-pcihost");
s = FROM_SYSBUS(I440FXState, sysbus_from_qdev(dev));
s = PCI_HOST_BRIDGE(dev);
s->address_space = address_space_mem;
b = pci_bus_new(&s->busdev.qdev, NULL, pci_address_space,
b = pci_bus_new(dev, NULL, pci_address_space,
address_space_io, 0);
s->bus = b;
object_property_add_child(qdev_get_machine(), "i440fx", OBJECT(dev), NULL);
@@ -537,7 +539,7 @@ static void piix3_class_init(ObjectClass *klass, void *data)
k->class_id = PCI_CLASS_BRIDGE_ISA;
}
static TypeInfo piix3_info = {
static const TypeInfo piix3_info = {
.name = "PIIX3",
.parent = TYPE_PCI_DEVICE,
.instance_size = sizeof(PIIX3State),
@@ -560,7 +562,7 @@ static void piix3_xen_class_init(ObjectClass *klass, void *data)
k->class_id = PCI_CLASS_BRIDGE_ISA;
};
static TypeInfo piix3_xen_info = {
static const TypeInfo piix3_xen_info = {
.name = "PIIX3-xen",
.parent = TYPE_PCI_DEVICE,
.instance_size = sizeof(PIIX3State),
@@ -584,7 +586,7 @@ static void i440fx_class_init(ObjectClass *klass, void *data)
dc->vmsd = &vmstate_i440fx;
}
static TypeInfo i440fx_info = {
static const TypeInfo i440fx_info = {
.name = "i440FX",
.parent = TYPE_PCI_DEVICE,
.instance_size = sizeof(PCII440FXState),
@@ -601,9 +603,9 @@ static void i440fx_pcihost_class_init(ObjectClass *klass, void *data)
dc->no_user = 1;
}
static TypeInfo i440fx_pcihost_info = {
static const TypeInfo i440fx_pcihost_info = {
.name = "i440FX-pcihost",
.parent = TYPE_SYS_BUS_DEVICE,
.parent = TYPE_PCI_HOST_BRIDGE,
.instance_size = sizeof(I440FXState),
.class_init = i440fx_pcihost_class_init,
};
+2 -1
View File
@@ -216,7 +216,8 @@ static void bamboo_init(ram_addr_t ram_size,
ram_bases, ram_sizes, 1);
/* PCI */
dev = sysbus_create_varargs("ppc4xx-pcihost", PPC440EP_PCI_CONFIG,
dev = sysbus_create_varargs(TYPE_PPC4xx_PCI_HOST_BRIDGE,
PPC440EP_PCI_CONFIG,
pic[pci_irq_nrs[0]], pic[pci_irq_nrs[1]],
pic[pci_irq_nrs[2]], pic[pci_irq_nrs[3]],
NULL);
+2
View File
@@ -53,6 +53,8 @@ void ppc4xx_sdram_init (CPUPPCState *env, qemu_irq irq, int nbanks,
target_phys_addr_t *ram_sizes,
int do_init);
#define TYPE_PPC4xx_PCI_HOST_BRIDGE "ppc4xx-pcihost"
PCIBus *ppc4xx_pci_init(CPUPPCState *env, qemu_irq pci_irqs[4],
target_phys_addr_t config_space,
target_phys_addr_t int_ack,
+16 -11
View File
@@ -45,11 +45,14 @@ struct PCITargetMap {
uint32_t la;
};
#define PPC4xx_PCI_HOST_BRIDGE(obj) \
OBJECT_CHECK(PPC4xxPCIState, (obj), TYPE_PPC4xx_PCI_HOST_BRIDGE)
#define PPC4xx_PCI_NR_PMMS 3
#define PPC4xx_PCI_NR_PTMS 2
struct PPC4xxPCIState {
PCIHostState pci_state;
PCIHostState parent_obj;
struct PCIMasterMap pmm[PPC4xx_PCI_NR_PMMS];
struct PCITargetMap ptm[PPC4xx_PCI_NR_PTMS];
@@ -93,16 +96,18 @@ static uint64_t pci4xx_cfgaddr_read(void *opaque, target_phys_addr_t addr,
unsigned size)
{
PPC4xxPCIState *ppc4xx_pci = opaque;
PCIHostState *phb = PCI_HOST_BRIDGE(ppc4xx_pci);
return ppc4xx_pci->pci_state.config_reg;
return phb->config_reg;
}
static void pci4xx_cfgaddr_write(void *opaque, target_phys_addr_t addr,
uint64_t value, unsigned size)
{
PPC4xxPCIState *ppc4xx_pci = opaque;
PCIHostState *phb = PCI_HOST_BRIDGE(ppc4xx_pci);
ppc4xx_pci->pci_state.config_reg = value & ~0x3;
phb->config_reg = value & ~0x3;
}
static const MemoryRegionOps pci4xx_cfgaddr_ops = {
@@ -335,17 +340,17 @@ static int ppc4xx_pcihost_initfn(SysBusDevice *dev)
PCIBus *b;
int i;
h = FROM_SYSBUS(PCIHostState, sysbus_from_qdev(dev));
s = DO_UPCAST(PPC4xxPCIState, pci_state, h);
h = PCI_HOST_BRIDGE(dev);
s = PPC4xx_PCI_HOST_BRIDGE(dev);
for (i = 0; i < ARRAY_SIZE(s->irq); i++) {
sysbus_init_irq(dev, &s->irq[i]);
}
b = pci_register_bus(&s->pci_state.busdev.qdev, NULL, ppc4xx_pci_set_irq,
b = pci_register_bus(DEVICE(dev), NULL, ppc4xx_pci_set_irq,
ppc4xx_pci_map_irq, s->irq, get_system_memory(),
get_system_io(), 0, 4);
s->pci_state.bus = b;
h->bus = b;
pci_create_simple(b, 0, "ppc4xx-host-bridge");
@@ -377,7 +382,7 @@ static void ppc4xx_host_bridge_class_init(ObjectClass *klass, void *data)
k->class_id = PCI_CLASS_BRIDGE_OTHER;
}
static TypeInfo ppc4xx_host_bridge_info = {
static const TypeInfo ppc4xx_host_bridge_info = {
.name = "ppc4xx-host-bridge",
.parent = TYPE_PCI_DEVICE,
.instance_size = sizeof(PCIDevice),
@@ -393,9 +398,9 @@ static void ppc4xx_pcihost_class_init(ObjectClass *klass, void *data)
dc->vmsd = &vmstate_ppc4xx_pci;
}
static TypeInfo ppc4xx_pcihost_info = {
.name = "ppc4xx-pcihost",
.parent = TYPE_SYS_BUS_DEVICE,
static const TypeInfo ppc4xx_pcihost_info = {
.name = TYPE_PPC4xx_PCI_HOST_BRIDGE,
.parent = TYPE_PCI_HOST_BRIDGE,
.instance_size = sizeof(PPC4xxPCIState),
.class_init = ppc4xx_pcihost_class_init,
};
+1
View File
@@ -55,6 +55,7 @@ qemu_irq *heathrow_pic_init(MemoryRegion **pmem,
int nb_cpus, qemu_irq **irqs);
/* Grackle PCI */
#define TYPE_GRACKLE_PCI_HOST_BRIDGE "grackle-pcihost"
PCIBus *pci_grackle_init(uint32_t base, qemu_irq *pic,
MemoryRegion *address_space_mem,
MemoryRegion *address_space_io);
+1 -3
View File
@@ -471,7 +471,6 @@ static void ppc_prep_init (ram_addr_t ram_size,
uint32_t kernel_base, initrd_base;
long kernel_size, initrd_size;
DeviceState *dev;
SysBusDevice *sys;
PCIHostState *pcihost;
PCIBus *pci_bus;
PCIDevice *pci;
@@ -584,8 +583,7 @@ static void ppc_prep_init (ram_addr_t ram_size,
}
dev = qdev_create(NULL, "raven-pcihost");
sys = sysbus_from_qdev(dev);
pcihost = DO_UPCAST(PCIHostState, busdev, sys);
pcihost = PCI_HOST_BRIDGE(dev);
pcihost->address_space = get_system_memory();
object_property_add_child(qdev_get_machine(), "raven", OBJECT(dev), NULL);
qdev_init_nofail(dev);
+15 -9
View File
@@ -72,8 +72,14 @@ struct pci_inbound {
uint32_t piwar;
};
#define TYPE_PPC_E500_PCI_HOST_BRIDGE "e500-pcihost"
#define PPC_E500_PCI_HOST_BRIDGE(obj) \
OBJECT_CHECK(PPCE500PCIState, (obj), TYPE_PPC_E500_PCI_HOST_BRIDGE)
struct PPCE500PCIState {
PCIHostState pci_state;
PCIHostState parent_obj;
struct pci_outbound pob[PPCE500_PCI_NR_POBS];
struct pci_inbound pib[PPCE500_PCI_NR_PIBS];
uint32_t gasket_time;
@@ -310,17 +316,17 @@ static int e500_pcihost_initfn(SysBusDevice *dev)
MemoryRegion *address_space_mem = get_system_memory();
MemoryRegion *address_space_io = get_system_io();
h = FROM_SYSBUS(PCIHostState, sysbus_from_qdev(dev));
s = DO_UPCAST(PPCE500PCIState, pci_state, h);
h = PCI_HOST_BRIDGE(dev);
s = PPC_E500_PCI_HOST_BRIDGE(dev);
for (i = 0; i < ARRAY_SIZE(s->irq); i++) {
sysbus_init_irq(dev, &s->irq[i]);
}
b = pci_register_bus(&s->pci_state.busdev.qdev, NULL, mpc85xx_pci_set_irq,
b = pci_register_bus(DEVICE(dev), NULL, mpc85xx_pci_set_irq,
mpc85xx_pci_map_irq, s->irq, address_space_mem,
address_space_io, PCI_DEVFN(0x11, 0), 4);
s->pci_state.bus = b;
h->bus = b;
pci_create_simple(b, 0, "e500-host-bridge");
@@ -350,7 +356,7 @@ static void e500_host_bridge_class_init(ObjectClass *klass, void *data)
dc->desc = "Host bridge";
}
static TypeInfo e500_host_bridge_info = {
static const TypeInfo e500_host_bridge_info = {
.name = "e500-host-bridge",
.parent = TYPE_PCI_DEVICE,
.instance_size = sizeof(PCIDevice),
@@ -366,9 +372,9 @@ static void e500_pcihost_class_init(ObjectClass *klass, void *data)
dc->vmsd = &vmstate_ppce500_pci;
}
static TypeInfo e500_pcihost_info = {
.name = "e500-pcihost",
.parent = TYPE_SYS_BUS_DEVICE,
static const TypeInfo e500_pcihost_info = {
.name = TYPE_PPC_E500_PCI_HOST_BRIDGE,
.parent = TYPE_PCI_HOST_BRIDGE,
.instance_size = sizeof(PPCE500PCIState),
.class_init = e500_pcihost_class_init,
};
+21 -12
View File
@@ -28,8 +28,14 @@
#include "pc.h"
#include "exec-memory.h"
#define TYPE_RAVEN_PCI_HOST_BRIDGE "raven-pcihost"
#define RAVEN_PCI_HOST_BRIDGE(obj) \
OBJECT_CHECK(PREPPCIState, (obj), TYPE_RAVEN_PCI_HOST_BRIDGE)
typedef struct PRePPCIState {
PCIHostState host_state;
PCIHostState parent_obj;
MemoryRegion intack;
qemu_irq irq[4];
} PREPPCIState;
@@ -42,9 +48,10 @@ static inline uint32_t PPC_PCIIO_config(target_phys_addr_t addr)
{
int i;
for(i = 0; i < 11; i++) {
if ((addr & (1 << (11 + i))) != 0)
for (i = 0; i < 11; i++) {
if ((addr & (1 << (11 + i))) != 0) {
break;
}
}
return (addr & 0x7ff) | (i << 11);
}
@@ -53,14 +60,16 @@ static void ppc_pci_io_write(void *opaque, target_phys_addr_t addr,
uint64_t val, unsigned int size)
{
PREPPCIState *s = opaque;
pci_data_write(s->host_state.bus, PPC_PCIIO_config(addr), val, size);
PCIHostState *phb = PCI_HOST_BRIDGE(s);
pci_data_write(phb->bus, PPC_PCIIO_config(addr), val, size);
}
static uint64_t ppc_pci_io_read(void *opaque, target_phys_addr_t addr,
unsigned int size)
{
PREPPCIState *s = opaque;
return pci_data_read(s->host_state.bus, PPC_PCIIO_config(addr), size);
PCIHostState *phb = PCI_HOST_BRIDGE(s);
return pci_data_read(phb->bus, PPC_PCIIO_config(addr), size);
}
static const MemoryRegionOps PPC_PCIIO_ops = {
@@ -96,8 +105,8 @@ static void prep_set_irq(void *opaque, int irq_num, int level)
static int raven_pcihost_init(SysBusDevice *dev)
{
PCIHostState *h = FROM_SYSBUS(PCIHostState, dev);
PREPPCIState *s = DO_UPCAST(PREPPCIState, host_state, h);
PCIHostState *h = PCI_HOST_BRIDGE(dev);
PREPPCIState *s = RAVEN_PCI_HOST_BRIDGE(dev);
MemoryRegion *address_space_mem = get_system_memory();
MemoryRegion *address_space_io = get_system_io();
PCIBus *bus;
@@ -107,7 +116,7 @@ static int raven_pcihost_init(SysBusDevice *dev)
sysbus_init_irq(dev, &s->irq[i]);
}
bus = pci_register_bus(&h->busdev.qdev, NULL,
bus = pci_register_bus(DEVICE(dev), NULL,
prep_set_irq, prep_map_irq, s->irq,
address_space_mem, address_space_io, 0, 4);
h->bus = bus;
@@ -166,7 +175,7 @@ static void raven_class_init(ObjectClass *klass, void *data)
dc->no_user = 1;
}
static TypeInfo raven_info = {
static const TypeInfo raven_info = {
.name = "raven",
.parent = TYPE_PCI_DEVICE,
.instance_size = sizeof(RavenPCIState),
@@ -183,9 +192,9 @@ static void raven_pcihost_class_init(ObjectClass *klass, void *data)
dc->no_user = 1;
}
static TypeInfo raven_pcihost_info = {
.name = "raven-pcihost",
.parent = TYPE_SYS_BUS_DEVICE,
static const TypeInfo raven_pcihost_info = {
.name = TYPE_RAVEN_PCI_HOST_BRIDGE,
.parent = TYPE_PCI_HOST_BRIDGE,
.instance_size = sizeof(PREPPCIState),
.class_init = raven_pcihost_class_init,
};
+1 -1
View File
@@ -543,7 +543,7 @@ static void qdev_print(Monitor *mon, DeviceState *dev, int indent)
qdev_print_props(mon, dev, DEVICE_CLASS(class)->props, indent);
class = object_class_get_parent(class);
} while (class != object_class_by_name(TYPE_DEVICE));
bus_print_dev(dev->parent_bus, mon, dev, indent + 2);
bus_print_dev(dev->parent_bus, mon, dev, indent);
QLIST_FOREACH(child, &dev->child_bus, sibling) {
qbus_print(mon, child, indent);
}
-2
View File
@@ -159,7 +159,6 @@ int qdev_init(DeviceState *dev)
rc = dc->init(dev);
if (rc < 0) {
object_unparent(OBJECT(dev));
qdev_free(dev);
return rc;
}
@@ -243,7 +242,6 @@ void qbus_reset_all_fn(void *opaque)
int qdev_simple_unplug_cb(DeviceState *dev)
{
/* just zap it */
object_unparent(OBJECT(dev));
qdev_free(dev);
return 0;
}
+2
View File
@@ -761,6 +761,7 @@ static int ata_passthrough_12_xfer_size(SCSIDevice *dev, uint8_t *buf)
switch (length) {
case 0:
case 3: /* USB-specific. */
default:
xfer = 0;
break;
case 1:
@@ -784,6 +785,7 @@ static int ata_passthrough_16_xfer_size(SCSIDevice *dev, uint8_t *buf)
switch (length) {
case 0:
case 3: /* USB-specific. */
default:
xfer = 0;
break;
case 1:
+2 -1
View File
@@ -1461,7 +1461,7 @@ static void scsi_unmap_complete(void *opaque, int ret)
SCSIDiskReq *r = data->r;
SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
uint64_t sector_num;
uint32 nb_sectors;
uint32_t nb_sectors;
r->req.aiocb = NULL;
if (ret < 0) {
@@ -2421,6 +2421,7 @@ static TypeInfo scsi_cd_info = {
#ifdef __linux__
static Property scsi_block_properties[] = {
DEFINE_PROP_DRIVE("drive", SCSIDiskState, qdev.conf.bs),
DEFINE_PROP_INT32("bootindex", SCSIDiskState, qdev.conf.bootindex, -1),
DEFINE_PROP_END_OF_LIST(),
};
+2 -1
View File
@@ -479,7 +479,8 @@ static SCSIRequest *scsi_new_request(SCSIDevice *d, uint32_t tag, uint32_t lun,
}
static Property scsi_generic_properties[] = {
DEFINE_BLOCK_PROPERTIES(SCSIDevice, conf),
DEFINE_PROP_DRIVE("drive", SCSIDevice, conf.bs),
DEFINE_PROP_INT32("bootindex", SCSIDevice, conf.bootindex, -1),
DEFINE_PROP_END_OF_LIST(),
};
-1
View File
@@ -253,7 +253,6 @@ static void shpc_free_devices_in_slot(SHPCDevice *shpc, int slot)
++devfn) {
PCIDevice *affected_dev = shpc->sec_bus->devices[devfn];
if (affected_dev) {
object_unparent(OBJECT(affected_dev));
qdev_free(&affected_dev->qdev);
}
}
+4 -3
View File
@@ -612,6 +612,7 @@ static void ppc_spapr_init(ram_addr_t ram_size,
{
PowerPCCPU *cpu;
CPUPPCState *env;
PCIHostState *phb;
int i;
MemoryRegion *sysmem = get_system_memory();
MemoryRegion *ram = g_new(MemoryRegion, 1);
@@ -742,6 +743,7 @@ static void ppc_spapr_init(ram_addr_t ram_size,
SPAPR_PCI_MEM_WIN_SIZE,
SPAPR_PCI_IO_WIN_ADDR,
SPAPR_PCI_MSI_WIN_ADDR);
phb = PCI_HOST_BRIDGE(QLIST_FIRST(&spapr->phbs));
for (i = 0; i < nb_nics; i++) {
NICInfo *nd = &nd_table[i];
@@ -762,13 +764,12 @@ static void ppc_spapr_init(ram_addr_t ram_size,
}
/* Graphics */
if (spapr_vga_init(QLIST_FIRST(&spapr->phbs)->host_state.bus)) {
if (spapr_vga_init(phb->bus)) {
spapr->has_graphics = true;
}
if (usb_enabled) {
pci_create_simple(QLIST_FIRST(&spapr->phbs)->host_state.bus,
-1, "pci-ohci");
pci_create_simple(phb->bus, -1, "pci-ohci");
if (spapr->has_graphics) {
usbdevice_create("keyboard");
usbdevice_create("mouse");
+49 -45
View File
@@ -48,13 +48,13 @@
static sPAPRPHBState *find_phb(sPAPREnvironment *spapr, uint64_t buid)
{
sPAPRPHBState *phb;
sPAPRPHBState *sphb;
QLIST_FOREACH(phb, &spapr->phbs, list) {
if (phb->buid != buid) {
QLIST_FOREACH(sphb, &spapr->phbs, list) {
if (sphb->buid != buid) {
continue;
}
return phb;
return sphb;
}
return NULL;
@@ -63,7 +63,9 @@ static sPAPRPHBState *find_phb(sPAPREnvironment *spapr, uint64_t buid)
static PCIDevice *find_dev(sPAPREnvironment *spapr, uint64_t buid,
uint32_t config_addr)
{
sPAPRPHBState *phb = find_phb(spapr, buid);
sPAPRPHBState *sphb = find_phb(spapr, buid);
PCIHostState *phb = PCI_HOST_BRIDGE(sphb);
BusState *bus = BUS(phb->bus);
BusChild *kid;
int devfn = (config_addr >> 8) & 0xFF;
@@ -71,7 +73,7 @@ static PCIDevice *find_dev(sPAPREnvironment *spapr, uint64_t buid,
return NULL;
}
QTAILQ_FOREACH(kid, &phb->host_state.bus->qbus.children, sibling) {
QTAILQ_FOREACH(kid, &bus->children, sibling) {
PCIDevice *dev = (PCIDevice *)kid->child;
if (dev->devfn == devfn) {
return dev;
@@ -514,23 +516,24 @@ static DMAContext *spapr_pci_dma_context_fn(PCIBus *bus, void *opaque,
static int spapr_phb_init(SysBusDevice *s)
{
sPAPRPHBState *phb = DO_UPCAST(sPAPRPHBState, host_state.busdev, s);
sPAPRPHBState *sphb = SPAPR_PCI_HOST_BRIDGE(s);
PCIHostState *phb = PCI_HOST_BRIDGE(s);
char *namebuf;
int i;
PCIBus *bus;
phb->dtbusname = g_strdup_printf("pci@%" PRIx64, phb->buid);
namebuf = alloca(strlen(phb->dtbusname) + 32);
sphb->dtbusname = g_strdup_printf("pci@%" PRIx64, sphb->buid);
namebuf = alloca(strlen(sphb->dtbusname) + 32);
/* Initialize memory regions */
sprintf(namebuf, "%s.mmio", phb->dtbusname);
memory_region_init(&phb->memspace, namebuf, INT64_MAX);
sprintf(namebuf, "%s.mmio", sphb->dtbusname);
memory_region_init(&sphb->memspace, namebuf, INT64_MAX);
sprintf(namebuf, "%s.mmio-alias", phb->dtbusname);
memory_region_init_alias(&phb->memwindow, namebuf, &phb->memspace,
SPAPR_PCI_MEM_WIN_BUS_OFFSET, phb->mem_win_size);
memory_region_add_subregion(get_system_memory(), phb->mem_win_addr,
&phb->memwindow);
sprintf(namebuf, "%s.mmio-alias", sphb->dtbusname);
memory_region_init_alias(&sphb->memwindow, namebuf, &sphb->memspace,
SPAPR_PCI_MEM_WIN_BUS_OFFSET, sphb->mem_win_size);
memory_region_add_subregion(get_system_memory(), sphb->mem_win_addr,
&sphb->memwindow);
/* On ppc, we only have MMIO no specific IO space from the CPU
* perspective. In theory we ought to be able to embed the PCI IO
@@ -540,42 +543,42 @@ static int spapr_phb_init(SysBusDevice *s)
* system io address space. This hack to bounce things via
* system_io works around the problem until all the users of
* old_portion are updated */
sprintf(namebuf, "%s.io", phb->dtbusname);
memory_region_init(&phb->iospace, namebuf, SPAPR_PCI_IO_WIN_SIZE);
sprintf(namebuf, "%s.io", sphb->dtbusname);
memory_region_init(&sphb->iospace, namebuf, SPAPR_PCI_IO_WIN_SIZE);
/* FIXME: fix to support multiple PHBs */
memory_region_add_subregion(get_system_io(), 0, &phb->iospace);
memory_region_add_subregion(get_system_io(), 0, &sphb->iospace);
sprintf(namebuf, "%s.io-alias", phb->dtbusname);
memory_region_init_io(&phb->iowindow, &spapr_io_ops, phb,
sprintf(namebuf, "%s.io-alias", sphb->dtbusname);
memory_region_init_io(&sphb->iowindow, &spapr_io_ops, sphb,
namebuf, SPAPR_PCI_IO_WIN_SIZE);
memory_region_add_subregion(get_system_memory(), phb->io_win_addr,
&phb->iowindow);
memory_region_add_subregion(get_system_memory(), sphb->io_win_addr,
&sphb->iowindow);
/* As MSI/MSIX interrupts trigger by writing at MSI/MSIX vectors,
* we need to allocate some memory to catch those writes coming
* from msi_notify()/msix_notify() */
if (msi_supported) {
sprintf(namebuf, "%s.msi", phb->dtbusname);
memory_region_init_io(&phb->msiwindow, &spapr_msi_ops, phb,
sprintf(namebuf, "%s.msi", sphb->dtbusname);
memory_region_init_io(&sphb->msiwindow, &spapr_msi_ops, sphb,
namebuf, SPAPR_MSIX_MAX_DEVS * 0x10000);
memory_region_add_subregion(get_system_memory(), phb->msi_win_addr,
&phb->msiwindow);
memory_region_add_subregion(get_system_memory(), sphb->msi_win_addr,
&sphb->msiwindow);
}
bus = pci_register_bus(&phb->host_state.busdev.qdev,
phb->busname ? phb->busname : phb->dtbusname,
pci_spapr_set_irq, pci_spapr_map_irq, phb,
&phb->memspace, &phb->iospace,
bus = pci_register_bus(DEVICE(s),
sphb->busname ? sphb->busname : sphb->dtbusname,
pci_spapr_set_irq, pci_spapr_map_irq, sphb,
&sphb->memspace, &sphb->iospace,
PCI_DEVFN(0, 0), PCI_NUM_PINS);
phb->host_state.bus = bus;
phb->bus = bus;
phb->dma_liobn = SPAPR_PCI_BASE_LIOBN | (pci_find_domain(bus) << 16);
phb->dma_window_start = 0;
phb->dma_window_size = 0x40000000;
phb->dma = spapr_tce_new_dma_context(phb->dma_liobn, phb->dma_window_size);
pci_setup_iommu(bus, spapr_pci_dma_context_fn, phb);
sphb->dma_liobn = SPAPR_PCI_BASE_LIOBN | (pci_find_domain(bus) << 16);
sphb->dma_window_start = 0;
sphb->dma_window_size = 0x40000000;
sphb->dma = spapr_tce_new_dma_context(sphb->dma_liobn, sphb->dma_window_size);
pci_setup_iommu(bus, spapr_pci_dma_context_fn, sphb);
QLIST_INSERT_HEAD(&spapr->phbs, phb, list);
QLIST_INSERT_HEAD(&spapr->phbs, sphb, list);
/* Initialize the LSI table */
for (i = 0; i < PCI_NUM_PINS; i++) {
@@ -586,7 +589,7 @@ static int spapr_phb_init(SysBusDevice *s)
return -1;
}
phb->lsi_table[i].irq = irq;
sphb->lsi_table[i].irq = irq;
}
return 0;
@@ -612,9 +615,9 @@ static void spapr_phb_class_init(ObjectClass *klass, void *data)
dc->props = spapr_phb_properties;
}
static TypeInfo spapr_phb_info = {
.name = "spapr-pci-host-bridge",
.parent = TYPE_SYS_BUS_DEVICE,
static const TypeInfo spapr_phb_info = {
.name = TYPE_SPAPR_PCI_HOST_BRIDGE,
.parent = TYPE_PCI_HOST_BRIDGE,
.instance_size = sizeof(sPAPRPHBState),
.class_init = spapr_phb_class_init,
};
@@ -626,7 +629,7 @@ void spapr_create_phb(sPAPREnvironment *spapr,
{
DeviceState *dev;
dev = qdev_create(NULL, spapr_phb_info.name);
dev = qdev_create(NULL, TYPE_SPAPR_PCI_HOST_BRIDGE);
if (busname) {
qdev_prop_set_string(dev, "busname", g_strdup(busname));
@@ -750,8 +753,9 @@ void spapr_pci_rtas_init(void)
}
}
static void register_types(void)
static void spapr_pci_register_types(void)
{
type_register_static(&spapr_phb_info);
}
type_init(register_types)
type_init(spapr_pci_register_types)
+6 -1
View File
@@ -29,8 +29,13 @@
#define SPAPR_MSIX_MAX_DEVS 32
#define TYPE_SPAPR_PCI_HOST_BRIDGE "spapr-pci-host-bridge"
#define SPAPR_PCI_HOST_BRIDGE(obj) \
OBJECT_CHECK(sPAPRPHBState, (obj), TYPE_SPAPR_PCI_HOST_BRIDGE)
typedef struct sPAPRPHBState {
PCIHostState host_state;
PCIHostState parent_obj;
uint64_t buid;
char *busname;
+95 -86
View File
@@ -38,8 +38,23 @@
static const int unin_irq_line[] = { 0x1b, 0x1c, 0x1d, 0x1e };
#define TYPE_UNI_NORTH_PCI_HOST_BRIDGE "uni-north-pci-pcihost"
#define TYPE_UNI_NORTH_AGP_HOST_BRIDGE "uni-north-agp-pcihost"
#define TYPE_UNI_NORTH_INTERNAL_PCI_HOST_BRIDGE "uni-north-internal-pci-pcihost"
#define TYPE_U3_AGP_HOST_BRIDGE "u3-agp-pcihost"
#define UNI_NORTH_PCI_HOST_BRIDGE(obj) \
OBJECT_CHECK(UNINState, (obj), TYPE_UNI_NORTH_PCI_HOST_BRIDGE)
#define UNI_NORTH_AGP_HOST_BRIDGE(obj) \
OBJECT_CHECK(UNINState, (obj), TYPE_UNI_NORTH_AGP_HOST_BRIDGE)
#define UNI_NORTH_INTERNAL_PCI_HOST_BRIDGE(obj) \
OBJECT_CHECK(UNINState, (obj), TYPE_UNI_NORTH_INTERNAL_PCI_HOST_BRIDGE)
#define U3_AGP_HOST_BRIDGE(obj) \
OBJECT_CHECK(UNINState, (obj), TYPE_U3_AGP_HOST_BRIDGE)
typedef struct UNINState {
PCIHostState host_state;
PCIHostState parent_obj;
MemoryRegion pci_mmio;
MemoryRegion pci_hole;
} UNINState;
@@ -100,10 +115,11 @@ static void unin_data_write(void *opaque, target_phys_addr_t addr,
uint64_t val, unsigned len)
{
UNINState *s = opaque;
PCIHostState *phb = PCI_HOST_BRIDGE(s);
UNIN_DPRINTF("write addr %" TARGET_FMT_plx " len %d val %"PRIx64"\n",
addr, len, val);
pci_data_write(s->host_state.bus,
unin_get_config_reg(s->host_state.config_reg, addr),
pci_data_write(phb->bus,
unin_get_config_reg(phb->config_reg, addr),
val, len);
}
@@ -111,10 +127,11 @@ static uint64_t unin_data_read(void *opaque, target_phys_addr_t addr,
unsigned len)
{
UNINState *s = opaque;
PCIHostState *phb = PCI_HOST_BRIDGE(s);
uint32_t val;
val = pci_data_read(s->host_state.bus,
unin_get_config_reg(s->host_state.config_reg, addr),
val = pci_data_read(phb->bus,
unin_get_config_reg(phb->config_reg, addr),
len);
UNIN_DPRINTF("read addr %" TARGET_FMT_plx " len %d val %x\n",
addr, len, val);
@@ -130,19 +147,17 @@ static const MemoryRegionOps unin_data_ops = {
static int pci_unin_main_init_device(SysBusDevice *dev)
{
PCIHostState *h;
UNINState *s;
/* Use values found on a real PowerMac */
/* Uninorth main bus */
h = FROM_SYSBUS(PCIHostState, dev);
s = DO_UPCAST(UNINState, host_state, h);
h = PCI_HOST_BRIDGE(dev);
memory_region_init_io(&s->host_state.conf_mem, &pci_host_conf_le_ops,
&s->host_state, "pci-conf-idx", 0x1000);
memory_region_init_io(&s->host_state.data_mem, &unin_data_ops, s,
memory_region_init_io(&h->conf_mem, &pci_host_conf_le_ops,
dev, "pci-conf-idx", 0x1000);
memory_region_init_io(&h->data_mem, &unin_data_ops, dev,
"pci-conf-data", 0x1000);
sysbus_init_mmio(dev, &s->host_state.conf_mem);
sysbus_init_mmio(dev, &s->host_state.data_mem);
sysbus_init_mmio(dev, &h->conf_mem);
sysbus_init_mmio(dev, &h->data_mem);
return 0;
}
@@ -151,18 +166,16 @@ static int pci_unin_main_init_device(SysBusDevice *dev)
static int pci_u3_agp_init_device(SysBusDevice *dev)
{
PCIHostState *h;
UNINState *s;
/* Uninorth U3 AGP bus */
h = FROM_SYSBUS(PCIHostState, dev);
s = DO_UPCAST(UNINState, host_state, h);
h = PCI_HOST_BRIDGE(dev);
memory_region_init_io(&s->host_state.conf_mem, &pci_host_conf_le_ops,
&s->host_state, "pci-conf-idx", 0x1000);
memory_region_init_io(&s->host_state.data_mem, &unin_data_ops, s,
memory_region_init_io(&h->conf_mem, &pci_host_conf_le_ops,
dev, "pci-conf-idx", 0x1000);
memory_region_init_io(&h->data_mem, &unin_data_ops, dev,
"pci-conf-data", 0x1000);
sysbus_init_mmio(dev, &s->host_state.conf_mem);
sysbus_init_mmio(dev, &s->host_state.data_mem);
sysbus_init_mmio(dev, &h->conf_mem);
sysbus_init_mmio(dev, &h->data_mem);
return 0;
}
@@ -170,36 +183,32 @@ static int pci_u3_agp_init_device(SysBusDevice *dev)
static int pci_unin_agp_init_device(SysBusDevice *dev)
{
PCIHostState *h;
UNINState *s;
/* Uninorth AGP bus */
h = FROM_SYSBUS(PCIHostState, dev);
s = DO_UPCAST(UNINState, host_state, h);
h = PCI_HOST_BRIDGE(dev);
memory_region_init_io(&s->host_state.conf_mem, &pci_host_conf_le_ops,
&s->host_state, "pci-conf-idx", 0x1000);
memory_region_init_io(&s->host_state.data_mem, &pci_host_data_le_ops,
&s->host_state, "pci-conf-data", 0x1000);
sysbus_init_mmio(dev, &s->host_state.conf_mem);
sysbus_init_mmio(dev, &s->host_state.data_mem);
memory_region_init_io(&h->conf_mem, &pci_host_conf_le_ops,
dev, "pci-conf-idx", 0x1000);
memory_region_init_io(&h->data_mem, &pci_host_data_le_ops,
dev, "pci-conf-data", 0x1000);
sysbus_init_mmio(dev, &h->conf_mem);
sysbus_init_mmio(dev, &h->data_mem);
return 0;
}
static int pci_unin_internal_init_device(SysBusDevice *dev)
{
PCIHostState *h;
UNINState *s;
/* Uninorth internal bus */
h = FROM_SYSBUS(PCIHostState, dev);
s = DO_UPCAST(UNINState, host_state, h);
h = PCI_HOST_BRIDGE(dev);
memory_region_init_io(&s->host_state.conf_mem, &pci_host_conf_le_ops,
&s->host_state, "pci-conf-idx", 0x1000);
memory_region_init_io(&s->host_state.data_mem, &pci_host_data_le_ops,
&s->host_state, "pci-conf-data", 0x1000);
sysbus_init_mmio(dev, &s->host_state.conf_mem);
sysbus_init_mmio(dev, &s->host_state.data_mem);
memory_region_init_io(&h->conf_mem, &pci_host_conf_le_ops,
dev, "pci-conf-idx", 0x1000);
memory_region_init_io(&h->data_mem, &pci_host_data_le_ops,
dev, "pci-conf-data", 0x1000);
sysbus_init_mmio(dev, &h->conf_mem);
sysbus_init_mmio(dev, &h->data_mem);
return 0;
}
@@ -214,26 +223,26 @@ PCIBus *pci_pmac_init(qemu_irq *pic,
/* Use values found on a real PowerMac */
/* Uninorth main bus */
dev = qdev_create(NULL, "uni-north-pci-pcihost");
dev = qdev_create(NULL, TYPE_UNI_NORTH_PCI_HOST_BRIDGE);
qdev_init_nofail(dev);
s = sysbus_from_qdev(dev);
h = FROM_SYSBUS(PCIHostState, s);
d = DO_UPCAST(UNINState, host_state, h);
s = SYS_BUS_DEVICE(dev);
h = PCI_HOST_BRIDGE(s);
d = UNI_NORTH_PCI_HOST_BRIDGE(dev);
memory_region_init(&d->pci_mmio, "pci-mmio", 0x100000000ULL);
memory_region_init_alias(&d->pci_hole, "pci-hole", &d->pci_mmio,
0x80000000ULL, 0x70000000ULL);
memory_region_add_subregion(address_space_mem, 0x80000000ULL,
&d->pci_hole);
d->host_state.bus = pci_register_bus(dev, "pci",
pci_unin_set_irq, pci_unin_map_irq,
pic,
&d->pci_mmio,
address_space_io,
PCI_DEVFN(11, 0), 4);
h->bus = pci_register_bus(dev, "pci",
pci_unin_set_irq, pci_unin_map_irq,
pic,
&d->pci_mmio,
address_space_io,
PCI_DEVFN(11, 0), 4);
#if 0
pci_create_simple(d->host_state.bus, PCI_DEVFN(11, 0), "uni-north");
pci_create_simple(h->bus, PCI_DEVFN(11, 0), "uni-north");
#endif
sysbus_mmio_map(s, 0, 0xf2800000);
@@ -242,30 +251,30 @@ PCIBus *pci_pmac_init(qemu_irq *pic,
/* DEC 21154 bridge */
#if 0
/* XXX: not activated as PPC BIOS doesn't handle multiple buses properly */
pci_create_simple(d->host_state.bus, PCI_DEVFN(12, 0), "dec-21154");
pci_create_simple(h->bus, PCI_DEVFN(12, 0), "dec-21154");
#endif
/* Uninorth AGP bus */
pci_create_simple(d->host_state.bus, PCI_DEVFN(11, 0), "uni-north-agp");
dev = qdev_create(NULL, "uni-north-agp-pcihost");
pci_create_simple(h->bus, PCI_DEVFN(11, 0), "uni-north-agp");
dev = qdev_create(NULL, TYPE_UNI_NORTH_AGP_HOST_BRIDGE);
qdev_init_nofail(dev);
s = sysbus_from_qdev(dev);
s = SYS_BUS_DEVICE(dev);
sysbus_mmio_map(s, 0, 0xf0800000);
sysbus_mmio_map(s, 1, 0xf0c00000);
/* Uninorth internal bus */
#if 0
/* XXX: not needed for now */
pci_create_simple(d->host_state.bus, PCI_DEVFN(14, 0),
pci_create_simple(h->bus, PCI_DEVFN(14, 0),
"uni-north-internal-pci");
dev = qdev_create(NULL, "uni-north-internal-pci-pcihost");
dev = qdev_create(NULL, TYPE_UNI_NORTH_INTERNAL_PCI_HOST_BRIDGE);
qdev_init_nofail(dev);
s = sysbus_from_qdev(dev);
s = SYS_BUS_DEVICE(dev);
sysbus_mmio_map(s, 0, 0xf4800000);
sysbus_mmio_map(s, 1, 0xf4c00000);
#endif
return d->host_state.bus;
return h->bus;
}
PCIBus *pci_pmac_u3_init(qemu_irq *pic,
@@ -279,11 +288,11 @@ PCIBus *pci_pmac_u3_init(qemu_irq *pic,
/* Uninorth AGP bus */
dev = qdev_create(NULL, "u3-agp-pcihost");
dev = qdev_create(NULL, TYPE_U3_AGP_HOST_BRIDGE);
qdev_init_nofail(dev);
s = sysbus_from_qdev(dev);
h = FROM_SYSBUS(PCIHostState, s);
d = DO_UPCAST(UNINState, host_state, h);
s = SYS_BUS_DEVICE(dev);
h = PCI_HOST_BRIDGE(dev);
d = U3_AGP_HOST_BRIDGE(dev);
memory_region_init(&d->pci_mmio, "pci-mmio", 0x100000000ULL);
memory_region_init_alias(&d->pci_hole, "pci-hole", &d->pci_mmio,
@@ -291,19 +300,19 @@ PCIBus *pci_pmac_u3_init(qemu_irq *pic,
memory_region_add_subregion(address_space_mem, 0x80000000ULL,
&d->pci_hole);
d->host_state.bus = pci_register_bus(dev, "pci",
pci_unin_set_irq, pci_unin_map_irq,
pic,
&d->pci_mmio,
address_space_io,
PCI_DEVFN(11, 0), 4);
h->bus = pci_register_bus(dev, "pci",
pci_unin_set_irq, pci_unin_map_irq,
pic,
&d->pci_mmio,
address_space_io,
PCI_DEVFN(11, 0), 4);
sysbus_mmio_map(s, 0, 0xf0800000);
sysbus_mmio_map(s, 1, 0xf0c00000);
pci_create_simple(d->host_state.bus, 11 << 3, "u3-agp");
pci_create_simple(h->bus, 11 << 3, "u3-agp");
return d->host_state.bus;
return h->bus;
}
static int unin_main_pci_host_init(PCIDevice *d)
@@ -350,7 +359,7 @@ static void unin_main_pci_host_class_init(ObjectClass *klass, void *data)
k->class_id = PCI_CLASS_BRIDGE_HOST;
}
static TypeInfo unin_main_pci_host_info = {
static const TypeInfo unin_main_pci_host_info = {
.name = "uni-north-pci",
.parent = TYPE_PCI_DEVICE,
.instance_size = sizeof(PCIDevice),
@@ -368,7 +377,7 @@ static void u3_agp_pci_host_class_init(ObjectClass *klass, void *data)
k->class_id = PCI_CLASS_BRIDGE_HOST;
}
static TypeInfo u3_agp_pci_host_info = {
static const TypeInfo u3_agp_pci_host_info = {
.name = "u3-agp",
.parent = TYPE_PCI_DEVICE,
.instance_size = sizeof(PCIDevice),
@@ -386,7 +395,7 @@ static void unin_agp_pci_host_class_init(ObjectClass *klass, void *data)
k->class_id = PCI_CLASS_BRIDGE_HOST;
}
static TypeInfo unin_agp_pci_host_info = {
static const TypeInfo unin_agp_pci_host_info = {
.name = "uni-north-agp",
.parent = TYPE_PCI_DEVICE,
.instance_size = sizeof(PCIDevice),
@@ -404,7 +413,7 @@ static void unin_internal_pci_host_class_init(ObjectClass *klass, void *data)
k->class_id = PCI_CLASS_BRIDGE_HOST;
}
static TypeInfo unin_internal_pci_host_info = {
static const TypeInfo unin_internal_pci_host_info = {
.name = "uni-north-internal-pci",
.parent = TYPE_PCI_DEVICE,
.instance_size = sizeof(PCIDevice),
@@ -418,9 +427,9 @@ static void pci_unin_main_class_init(ObjectClass *klass, void *data)
sbc->init = pci_unin_main_init_device;
}
static TypeInfo pci_unin_main_info = {
.name = "uni-north-pci-pcihost",
.parent = TYPE_SYS_BUS_DEVICE,
static const TypeInfo pci_unin_main_info = {
.name = TYPE_UNI_NORTH_PCI_HOST_BRIDGE,
.parent = TYPE_PCI_HOST_BRIDGE,
.instance_size = sizeof(UNINState),
.class_init = pci_unin_main_class_init,
};
@@ -432,9 +441,9 @@ static void pci_u3_agp_class_init(ObjectClass *klass, void *data)
sbc->init = pci_u3_agp_init_device;
}
static TypeInfo pci_u3_agp_info = {
.name = "u3-agp-pcihost",
.parent = TYPE_SYS_BUS_DEVICE,
static const TypeInfo pci_u3_agp_info = {
.name = TYPE_U3_AGP_HOST_BRIDGE,
.parent = TYPE_PCI_HOST_BRIDGE,
.instance_size = sizeof(UNINState),
.class_init = pci_u3_agp_class_init,
};
@@ -446,9 +455,9 @@ static void pci_unin_agp_class_init(ObjectClass *klass, void *data)
sbc->init = pci_unin_agp_init_device;
}
static TypeInfo pci_unin_agp_info = {
.name = "uni-north-agp-pcihost",
.parent = TYPE_SYS_BUS_DEVICE,
static const TypeInfo pci_unin_agp_info = {
.name = TYPE_UNI_NORTH_AGP_HOST_BRIDGE,
.parent = TYPE_PCI_HOST_BRIDGE,
.instance_size = sizeof(UNINState),
.class_init = pci_unin_agp_class_init,
};
@@ -460,9 +469,9 @@ static void pci_unin_internal_class_init(ObjectClass *klass, void *data)
sbc->init = pci_unin_internal_init_device;
}
static TypeInfo pci_unin_internal_info = {
.name = "uni-north-internal-pci-pcihost",
.parent = TYPE_SYS_BUS_DEVICE,
static const TypeInfo pci_unin_internal_info = {
.name = TYPE_UNI_NORTH_INTERNAL_PCI_HOST_BRIDGE,
.parent = TYPE_PCI_HOST_BRIDGE,
.instance_size = sizeof(UNINState),
.class_init = pci_unin_internal_class_init,
};
+3 -1
View File
@@ -179,6 +179,7 @@ struct USBEndpoint {
uint8_t ifnum;
int max_packet_size;
bool pipeline;
bool halted;
USBDevice *dev;
QTAILQ_HEAD(, USBPacket) queue;
};
@@ -331,6 +332,7 @@ typedef enum USBPacketState {
struct USBPacket {
/* Data fields for use by the driver. */
int pid;
uint64_t id;
USBEndpoint *ep;
QEMUIOVector iov;
uint64_t parameter; /* control transfers */
@@ -343,7 +345,7 @@ struct USBPacket {
void usb_packet_init(USBPacket *p);
void usb_packet_set_state(USBPacket *p, USBPacketState state);
void usb_packet_check_state(USBPacket *p, USBPacketState expected);
void usb_packet_setup(USBPacket *p, int pid, USBEndpoint *ep);
void usb_packet_setup(USBPacket *p, int pid, USBEndpoint *ep, uint64_t id);
void usb_packet_addbuf(USBPacket *p, void *ptr, size_t len);
int usb_packet_map(USBPacket *p, QEMUSGList *sgl);
void usb_packet_unmap(USBPacket *p, QEMUSGList *sgl);
+31 -8
View File
@@ -107,6 +107,7 @@ static int do_token_setup(USBDevice *s, USBPacket *p)
}
usb_packet_copy(p, s->setup_buf, p->iov.size);
p->result = 0;
s->setup_len = (s->setup_buf[7] << 8) | s->setup_buf[6];
s->setup_index = 0;
@@ -381,12 +382,23 @@ int usb_handle_packet(USBDevice *dev, USBPacket *p)
usb_packet_check_state(p, USB_PACKET_SETUP);
assert(p->ep != NULL);
/* Submitting a new packet clears halt */
if (p->ep->halted) {
assert(QTAILQ_EMPTY(&p->ep->queue));
p->ep->halted = false;
}
if (QTAILQ_EMPTY(&p->ep->queue) || p->ep->pipeline) {
ret = usb_process_one(p);
if (ret == USB_RET_ASYNC) {
usb_packet_set_state(p, USB_PACKET_ASYNC);
QTAILQ_INSERT_TAIL(&p->ep->queue, p, queue);
} else {
/*
* When pipelining is enabled usb-devices must always return async,
* otherwise packets can complete out of order!
*/
assert(!p->ep->pipeline);
p->result = ret;
usb_packet_set_state(p, USB_PACKET_COMPLETE);
}
@@ -398,6 +410,20 @@ int usb_handle_packet(USBDevice *dev, USBPacket *p)
return ret;
}
static void __usb_packet_complete(USBDevice *dev, USBPacket *p)
{
USBEndpoint *ep = p->ep;
assert(p->result != USB_RET_ASYNC && p->result != USB_RET_NAK);
if (p->result < 0) {
ep->halted = true;
}
usb_packet_set_state(p, USB_PACKET_COMPLETE);
QTAILQ_REMOVE(&ep->queue, p, queue);
dev->port->ops->complete(dev->port, p);
}
/* Notify the controller that an async packet is complete. This should only
be called for packets previously deferred by returning USB_RET_ASYNC from
handle_packet. */
@@ -408,11 +434,9 @@ void usb_packet_complete(USBDevice *dev, USBPacket *p)
usb_packet_check_state(p, USB_PACKET_ASYNC);
assert(QTAILQ_FIRST(&ep->queue) == p);
usb_packet_set_state(p, USB_PACKET_COMPLETE);
QTAILQ_REMOVE(&ep->queue, p, queue);
dev->port->ops->complete(dev->port, p);
__usb_packet_complete(dev, p);
while (!QTAILQ_EMPTY(&ep->queue)) {
while (!ep->halted && !QTAILQ_EMPTY(&ep->queue)) {
p = QTAILQ_FIRST(&ep->queue);
if (p->state == USB_PACKET_ASYNC) {
break;
@@ -424,9 +448,7 @@ void usb_packet_complete(USBDevice *dev, USBPacket *p)
break;
}
p->result = ret;
usb_packet_set_state(p, USB_PACKET_COMPLETE);
QTAILQ_REMOVE(&ep->queue, p, queue);
dev->port->ops->complete(dev->port, p);
__usb_packet_complete(ep->dev, p);
}
}
@@ -498,10 +520,11 @@ void usb_packet_set_state(USBPacket *p, USBPacketState state)
p->state = state;
}
void usb_packet_setup(USBPacket *p, int pid, USBEndpoint *ep)
void usb_packet_setup(USBPacket *p, int pid, USBEndpoint *ep, uint64_t id)
{
assert(!usb_packet_is_inflight(p));
assert(p->iov.iov != NULL);
p->id = id;
p->pid = pid;
p->ep = ep;
p->result = 0;
+2 -3
View File
@@ -223,7 +223,7 @@ static const USBDescDevice desc_device_high = {
static const USBDesc desc = {
.id = {
.idVendor = 0x46f4, /* CRC16() of "QEMU" */
.idProduct = 0x0002,
.idProduct = 0x0003,
.bcdDevice = 0,
.iManufacturer = STR_MANUFACTURER,
.iProduct = STR_PRODUCT,
@@ -424,6 +424,7 @@ static void usb_uas_scsi_free_request(SCSIBus *bus, void *priv)
}
QTAILQ_REMOVE(&uas->requests, req, next);
g_free(req);
usb_uas_start_next_transfer(uas);
}
static UASRequest *usb_uas_find_request(UASDevice *uas, uint16_t tag)
@@ -456,7 +457,6 @@ static void usb_uas_scsi_command_complete(SCSIRequest *r,
uint32_t status, size_t resid)
{
UASRequest *req = r->hba_private;
UASDevice *uas = req->uas;
trace_usb_uas_scsi_complete(req->uas->dev.addr, req->tag, status, resid);
req->complete = true;
@@ -465,7 +465,6 @@ static void usb_uas_scsi_command_complete(SCSIRequest *r,
}
usb_uas_queue_sense(req, status);
scsi_req_unref(req->req);
usb_uas_start_next_transfer(uas);
}
static void usb_uas_scsi_request_cancelled(SCSIRequest *r)
+101 -54
View File
@@ -575,7 +575,12 @@ static inline void ehci_update_irq(EHCIState *s)
/* flag interrupt condition */
static inline void ehci_raise_irq(EHCIState *s, int intr)
{
s->usbsts_pending |= intr;
if (intr & (USBSTS_PCD | USBSTS_FLR | USBSTS_HSE)) {
s->usbsts |= intr;
ehci_update_irq(s);
} else {
s->usbsts_pending |= intr;
}
}
/*
@@ -761,15 +766,27 @@ static EHCIQueue *ehci_alloc_queue(EHCIState *ehci, uint32_t addr, int async)
return q;
}
static void ehci_cancel_queue(EHCIQueue *q)
{
EHCIPacket *p;
p = QTAILQ_FIRST(&q->packets);
if (p == NULL) {
return;
}
trace_usb_ehci_queue_action(q, "cancel");
do {
ehci_free_packet(p);
} while ((p = QTAILQ_FIRST(&q->packets)) != NULL);
}
static void ehci_free_queue(EHCIQueue *q)
{
EHCIQueueHead *head = q->async ? &q->ehci->aqueues : &q->ehci->pqueues;
EHCIPacket *p;
trace_usb_ehci_queue_action(q, "free");
while ((p = QTAILQ_FIRST(&q->packets)) != NULL) {
ehci_free_packet(p);
}
ehci_cancel_queue(q);
QTAILQ_REMOVE(head, q, next);
g_free(q);
}
@@ -1182,22 +1199,32 @@ static void ehci_mem_writel(void *ptr, target_phys_addr_t addr, uint32_t val)
break;
}
if (((USBCMD_RUNSTOP | USBCMD_PSE | USBCMD_ASE) & val) !=
((USBCMD_RUNSTOP | USBCMD_PSE | USBCMD_ASE) & s->usbcmd)) {
if (s->pstate == EST_INACTIVE) {
SET_LAST_RUN_CLOCK(s);
}
ehci_update_halt(s);
s->async_stepdown = 0;
qemu_mod_timer(s->frame_timer, qemu_get_clock_ns(vm_clock));
}
/* not supporting dynamic frame list size at the moment */
if ((val & USBCMD_FLS) && !(s->usbcmd & USBCMD_FLS)) {
fprintf(stderr, "attempt to set frame list size -- value %d\n",
val & USBCMD_FLS);
val &= ~USBCMD_FLS;
}
if (val & USBCMD_IAAD) {
/*
* Process IAAD immediately, otherwise the Linux IAAD watchdog may
* trigger and re-use a qh without us seeing the unlink.
*/
s->async_stepdown = 0;
qemu_bh_schedule(s->async_bh);
}
if (((USBCMD_RUNSTOP | USBCMD_PSE | USBCMD_ASE) & val) !=
((USBCMD_RUNSTOP | USBCMD_PSE | USBCMD_ASE) & s->usbcmd)) {
if (s->pstate == EST_INACTIVE) {
SET_LAST_RUN_CLOCK(s);
}
s->usbcmd = val; /* Set usbcmd for ehci_update_halt() */
ehci_update_halt(s);
s->async_stepdown = 0;
qemu_mod_timer(s->frame_timer, qemu_get_clock_ns(vm_clock));
}
break;
case USBSTS:
@@ -1524,7 +1551,7 @@ static int ehci_execute(EHCIPacket *p, const char *action)
endp = get_field(p->queue->qh.epchar, QH_EPCHAR_EP);
ep = usb_ep_get(p->queue->dev, p->pid, endp);
usb_packet_setup(&p->packet, p->pid, ep);
usb_packet_setup(&p->packet, p->pid, ep, p->qtdaddr);
usb_packet_map(&p->packet, &p->sgl);
trace_usb_ehci_packet_action(p->queue, p, action);
@@ -1546,7 +1573,8 @@ static int ehci_execute(EHCIPacket *p, const char *action)
*/
static int ehci_process_itd(EHCIState *ehci,
EHCIitd *itd)
EHCIitd *itd,
uint32_t addr)
{
USBDevice *dev;
USBEndpoint *ep;
@@ -1591,8 +1619,8 @@ static int ehci_process_itd(EHCIState *ehci,
dev = ehci_find_device(ehci, devaddr);
ep = usb_ep_get(dev, pid, endp);
if (ep->type == USB_ENDPOINT_XFER_ISOC) {
usb_packet_setup(&ehci->ipacket, pid, ep);
if (ep && ep->type == USB_ENDPOINT_XFER_ISOC) {
usb_packet_setup(&ehci->ipacket, pid, ep, addr);
usb_packet_map(&ehci->ipacket, &ehci->isgl);
ret = usb_handle_packet(dev, &ehci->ipacket);
assert(ret != USB_RET_ASYNC);
@@ -1780,9 +1808,7 @@ static EHCIQueue *ehci_state_fetchqh(EHCIState *ehci, int async)
if (q->dev != NULL && q->dev->addr != devaddr) {
if (!QTAILQ_EMPTY(&q->packets)) {
/* should not happen (guest bug) */
while ((p = QTAILQ_FIRST(&q->packets)) != NULL) {
ehci_free_packet(p);
}
ehci_cancel_queue(q);
}
q->dev = NULL;
}
@@ -1790,11 +1816,6 @@ static EHCIQueue *ehci_state_fetchqh(EHCIState *ehci, int async)
q->dev = ehci_find_device(q->ehci, devaddr);
}
if (p && p->async == EHCI_ASYNC_INFLIGHT) {
/* I/O still in progress -- skip queue */
ehci_set_state(ehci, async, EST_HORIZONTALQH);
goto out;
}
if (p && p->async == EHCI_ASYNC_FINISHED) {
/* I/O finished -- continue processing queue */
trace_usb_ehci_packet_action(p->queue, p, "complete");
@@ -1856,7 +1877,7 @@ static int ehci_state_fetchitd(EHCIState *ehci, int async)
sizeof(EHCIitd) >> 2);
ehci_trace_itd(ehci, entry, &itd);
if (ehci_process_itd(ehci, &itd) != 0) {
if (ehci_process_itd(ehci, &itd, entry) != 0) {
return -1;
}
@@ -1943,29 +1964,50 @@ static int ehci_state_fetchqtd(EHCIQueue *q)
ehci_trace_qtd(q, NLPTR_GET(q->qtdaddr), &qtd);
p = QTAILQ_FIRST(&q->packets);
while (p != NULL && p->qtdaddr != q->qtdaddr) {
/* should not happen (guest bug) */
ehci_free_packet(p);
p = QTAILQ_FIRST(&q->packets);
}
if (p != NULL) {
ehci_qh_do_overlay(q);
ehci_flush_qh(q);
if (p->async == EHCI_ASYNC_INFLIGHT) {
ehci_set_state(q->ehci, q->async, EST_HORIZONTALQH);
if (p->qtdaddr != q->qtdaddr ||
(!NLPTR_TBIT(p->qtd.next) && (p->qtd.next != qtd.next)) ||
(!NLPTR_TBIT(p->qtd.altnext) && (p->qtd.altnext != qtd.altnext)) ||
p->qtd.bufptr[0] != qtd.bufptr[0]) {
/* guest bug: guest updated active QH or qTD underneath us */
ehci_cancel_queue(q);
p = NULL;
} else {
p->qtd = qtd;
ehci_qh_do_overlay(q);
}
}
if (!(qtd.token & QTD_TOKEN_ACTIVE)) {
if (p != NULL) {
/* transfer canceled by guest (clear active) */
ehci_cancel_queue(q);
p = NULL;
}
ehci_set_state(q->ehci, q->async, EST_HORIZONTALQH);
again = 1;
} else if (p != NULL) {
switch (p->async) {
case EHCI_ASYNC_NONE:
/* Previously nacked packet (likely interrupt ep) */
ehci_set_state(q->ehci, q->async, EST_EXECUTE);
break;
case EHCI_ASYNC_INFLIGHT:
/* Unfinyshed async handled packet, go horizontal */
ehci_set_state(q->ehci, q->async, EST_HORIZONTALQH);
break;
case EHCI_ASYNC_FINISHED:
/* Should never happen, as this case is caught by fetchqh */
ehci_set_state(q->ehci, q->async, EST_EXECUTING);
break;
}
again = 1;
} else if (qtd.token & QTD_TOKEN_ACTIVE) {
} else {
p = ehci_alloc_packet(q);
p->qtdaddr = q->qtdaddr;
p->qtd = qtd;
ehci_set_state(q->ehci, q->async, EST_EXECUTE);
again = 1;
} else {
ehci_set_state(q->ehci, q->async, EST_HORIZONTALQH);
again = 1;
}
return again;
@@ -2069,19 +2111,11 @@ out:
static int ehci_state_executing(EHCIQueue *q)
{
EHCIPacket *p = QTAILQ_FIRST(&q->packets);
int again = 0;
assert(p != NULL);
assert(p->qtdaddr == q->qtdaddr);
ehci_execute_complete(q);
if (p->usb_status == USB_RET_ASYNC) {
goto out;
}
if (p->usb_status == USB_RET_PROCERR) {
again = -1;
goto out;
}
// 4.10.3
if (!q->async) {
@@ -2099,11 +2133,8 @@ static int ehci_state_executing(EHCIQueue *q)
ehci_set_state(q->ehci, q->async, EST_WRITEBACK);
}
again = 1;
out:
ehci_flush_qh(q);
return again;
return 1;
}
@@ -2132,6 +2163,19 @@ static int ehci_state_writeback(EHCIQueue *q)
* bit is clear.
*/
if (q->qh.token & QTD_TOKEN_HALT) {
/*
* We should not do any further processing on a halted queue!
* This is esp. important for bulk endpoints with pipelining enabled
* (redirection to a real USB device), where we must cancel all the
* transfers after this one so that:
* 1) If they've completed already, they are not processed further
* causing more stalls, originating from the same failed transfer
* 2) If still in flight, they are cancelled before the guest does
* a clear stall, otherwise the guest and device can loose sync!
*/
while ((p = QTAILQ_FIRST(&q->packets)) != NULL) {
ehci_free_packet(p);
}
ehci_set_state(q->ehci, q->async, EST_HORIZONTALQH);
again = 1;
} else {
@@ -2466,13 +2510,16 @@ static int usb_ehci_post_load(void *opaque, int version_id)
static const VMStateDescription vmstate_ehci = {
.name = "ehci",
.version_id = 1,
.version_id = 2,
.minimum_version_id = 1,
.post_load = usb_ehci_post_load,
.fields = (VMStateField[]) {
VMSTATE_PCI_DEVICE(dev, EHCIState),
/* mmio registers */
VMSTATE_UINT32(usbcmd, EHCIState),
VMSTATE_UINT32(usbsts, EHCIState),
VMSTATE_UINT32_V(usbsts_pending, EHCIState, 2),
VMSTATE_UINT32_V(usbsts_frindex, EHCIState, 2),
VMSTATE_UINT32(usbintr, EHCIState),
VMSTATE_UINT32(frindex, EHCIState),
VMSTATE_UINT32(ctrldssegment, EHCIState),
+2 -1
View File
@@ -626,7 +626,8 @@ static void musb_packet(MUSBState *s, MUSBEndPoint *ep,
/* A wild guess on the FADDR semantics... */
dev = usb_find_device(&s->port, ep->faddr[idx]);
uep = usb_ep_get(dev, pid, ep->type[idx] & 0xf);
usb_packet_setup(&ep->packey[dir].p, pid, uep);
usb_packet_setup(&ep->packey[dir].p, pid, uep,
(dev->addr << 16) | (uep->nr << 8) | pid);
usb_packet_addbuf(&ep->packey[dir].p, ep->buf[idx], len);
ep->packey[dir].ep = ep;
ep->packey[dir].dir = dir;
+2 -2
View File
@@ -812,7 +812,7 @@ static int ohci_service_iso_td(OHCIState *ohci, struct ohci_ed *ed,
} else {
dev = ohci_find_device(ohci, OHCI_BM(ed->flags, ED_FA));
ep = usb_ep_get(dev, pid, OHCI_BM(ed->flags, ED_EN));
usb_packet_setup(&ohci->usb_packet, pid, ep);
usb_packet_setup(&ohci->usb_packet, pid, ep, addr);
usb_packet_addbuf(&ohci->usb_packet, ohci->usb_buf, len);
ret = usb_handle_packet(dev, &ohci->usb_packet);
if (ret == USB_RET_ASYNC) {
@@ -1011,7 +1011,7 @@ static int ohci_service_td(OHCIState *ohci, struct ohci_ed *ed)
}
dev = ohci_find_device(ohci, OHCI_BM(ed->flags, ED_FA));
ep = usb_ep_get(dev, pid, OHCI_BM(ed->flags, ED_EN));
usb_packet_setup(&ohci->usb_packet, pid, ep);
usb_packet_setup(&ohci->usb_packet, pid, ep, addr);
usb_packet_addbuf(&ohci->usb_packet, ohci->usb_buf, pktlen);
ret = usb_handle_packet(dev, &ohci->usb_packet);
#ifdef DEBUG_PACKET
+18 -2
View File
@@ -748,6 +748,22 @@ static int uhci_complete_td(UHCIState *s, UHCI_TD *td, UHCIAsync *async, uint32_
return TD_RESULT_COMPLETE;
out:
/*
* We should not do any further processing on a queue with errors!
* This is esp. important for bulk endpoints with pipelining enabled
* (redirection to a real USB device), where we must cancel all the
* transfers after this one so that:
* 1) If they've completed already, they are not processed further
* causing more stalls, originating from the same failed transfer
* 2) If still in flight, they are cancelled before the guest does
* a clear stall, otherwise the guest and device can loose sync!
*/
while (!QTAILQ_EMPTY(&async->queue->asyncs)) {
UHCIAsync *as = QTAILQ_FIRST(&async->queue->asyncs);
uhci_async_unlink(as);
uhci_async_cancel(as);
}
switch(ret) {
case USB_RET_STALL:
td->ctrl |= TD_CTRL_STALL;
@@ -843,14 +859,14 @@ static int uhci_handle_td(UHCIState *s, uint32_t addr, UHCI_TD *td,
* for initial isochronous requests
*/
async->queue->valid = 32;
async->isoc = td->ctrl & TD_CTRL_IOS;
async->isoc = td->ctrl & TD_CTRL_IOS;
max_len = ((td->token >> 21) + 1) & 0x7ff;
pid = td->token & 0xff;
dev = uhci_find_device(s, (td->token >> 8) & 0x7f);
ep = usb_ep_get(dev, pid, (td->token >> 15) & 0xf);
usb_packet_setup(&async->packet, pid, ep);
usb_packet_setup(&async->packet, pid, ep, addr);
qemu_sglist_add(&async->sgl, td->buffer, max_len);
usb_packet_map(&async->packet, &async->sgl);
+1 -1
View File
@@ -1392,7 +1392,7 @@ static int xhci_setup_packet(XHCITransfer *xfer, USBDevice *dev)
dir = xfer->in_xfer ? USB_TOKEN_IN : USB_TOKEN_OUT;
ep = usb_ep_get(dev, dir, xfer->epid >> 1);
usb_packet_setup(&xfer->packet, dir, ep);
usb_packet_setup(&xfer->packet, dir, ep, xfer->trbs[0].addr);
usb_packet_addbuf(&xfer->packet, xfer->data, xfer->data_length);
DPRINTF("xhci: setup packet pid 0x%x addr %d ep %d\n",
xfer->packet.pid, dev->addr, ep->nr);
+1
View File
@@ -1045,6 +1045,7 @@ static int usb_host_handle_control(USBDevice *dev, USBPacket *p,
/* Note request is (bRequestType << 8) | bRequest */
trace_usb_host_req_control(s->bus_num, s->addr, p, request, value, index);
assert(p->result == 0);
switch (request) {
case DeviceOutRequest | USB_REQ_SET_ADDRESS:
-1
View File
@@ -533,7 +533,6 @@ static uint32_t virtio_blk_get_features(VirtIODevice *vdev, uint32_t features)
features |= (1 << VIRTIO_BLK_F_BLK_SIZE);
features |= (1 << VIRTIO_BLK_F_SCSI);
features |= (1 << VIRTIO_BLK_F_CONFIG_WCE);
if (bdrv_enable_write_cache(s->bs))
features |= (1 << VIRTIO_BLK_F_WCE);
+3 -1
View File
@@ -104,9 +104,11 @@ struct VirtIOBlkConf
BlockConf conf;
char *serial;
uint32_t scsi;
uint32_t config_wce;
};
#define DEFINE_VIRTIO_BLK_FEATURES(_state, _field) \
DEFINE_VIRTIO_COMMON_FEATURES(_state, _field)
DEFINE_VIRTIO_COMMON_FEATURES(_state, _field), \
DEFINE_PROP_BIT("config-wce", _state, _field, VIRTIO_BLK_F_CONFIG_WCE, true)
#endif
+3
View File
@@ -131,6 +131,7 @@ static int virtio_pci_load_config(void * opaque, QEMUFile *f)
if (ret) {
return ret;
}
msix_unuse_all_vectors(&proxy->pci_dev);
msix_load(&proxy->pci_dev, f);
if (msix_present(&proxy->pci_dev)) {
qemu_get_be16s(f, &proxy->vdev->config_vector);
@@ -246,6 +247,7 @@ void virtio_pci_reset(DeviceState *d)
VirtIOPCIProxy *proxy = container_of(d, VirtIOPCIProxy, pci_dev.qdev);
virtio_pci_stop_ioeventfd(proxy);
virtio_reset(proxy->vdev);
msix_unuse_all_vectors(&proxy->pci_dev);
proxy->flags &= ~VIRTIO_PCI_FLAG_BUS_MASTER_BUG;
}
@@ -886,6 +888,7 @@ static Property virtio_blk_properties[] = {
#ifdef __linux__
DEFINE_PROP_BIT("scsi", VirtIOPCIProxy, blk.scsi, 0, true),
#endif
DEFINE_PROP_BIT("config-wce", VirtIOPCIProxy, blk.config_wce, 0, true),
DEFINE_PROP_BIT("ioeventfd", VirtIOPCIProxy, flags, VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT, true),
DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors, 2),
DEFINE_VIRTIO_BLK_FEATURES(VirtIOPCIProxy, host_features),
-7
View File
@@ -24,11 +24,6 @@
#define VIRTIO_SCSI_MAX_TARGET 255
#define VIRTIO_SCSI_MAX_LUN 16383
/* Feature Bits */
#define VIRTIO_SCSI_F_INOUT 0
#define VIRTIO_SCSI_F_HOTPLUG 1
#define VIRTIO_SCSI_F_CHANGE 2
/* Response codes */
#define VIRTIO_SCSI_S_OK 0
#define VIRTIO_SCSI_S_OVERRUN 1
@@ -561,8 +556,6 @@ static void virtio_scsi_set_config(VirtIODevice *vdev,
static uint32_t virtio_scsi_get_features(VirtIODevice *vdev,
uint32_t requested_features)
{
requested_features |= (1UL << VIRTIO_SCSI_F_HOTPLUG);
requested_features |= (1UL << VIRTIO_SCSI_F_CHANGE);
return requested_features;
}
+8 -1
View File
@@ -21,6 +21,11 @@
/* The ID for virtio_scsi */
#define VIRTIO_ID_SCSI 8
/* Feature Bits */
#define VIRTIO_SCSI_F_INOUT 0
#define VIRTIO_SCSI_F_HOTPLUG 1
#define VIRTIO_SCSI_F_CHANGE 2
struct VirtIOSCSIConf {
uint32_t num_queues;
uint32_t max_sectors;
@@ -31,6 +36,8 @@ struct VirtIOSCSIConf {
DEFINE_VIRTIO_COMMON_FEATURES(_state, _features_field), \
DEFINE_PROP_UINT32("num_queues", _state, _conf_field.num_queues, 1), \
DEFINE_PROP_UINT32("max_sectors", _state, _conf_field.max_sectors, 0xFFFF), \
DEFINE_PROP_UINT32("cmd_per_lun", _state, _conf_field.cmd_per_lun, 128)
DEFINE_PROP_UINT32("cmd_per_lun", _state, _conf_field.cmd_per_lun, 128), \
DEFINE_PROP_BIT("hotplug", _state, _features_field, VIRTIO_SCSI_F_HOTPLUG, true), \
DEFINE_PROP_BIT("param_change", _state, _features_field, VIRTIO_SCSI_F_CHANGE, true)
#endif /* _QEMU_VIRTIO_SCSI_H */
-3
View File
@@ -87,9 +87,6 @@ static void unplug_nic(PCIBus *b, PCIDevice *d, void *o)
{
if (pci_get_word(d->config + PCI_CLASS_DEVICE) ==
PCI_CLASS_NETWORK_ETHERNET) {
/* Until qdev_free includes a call to object_unparent, we call it here
*/
object_unparent(&d->qdev.parent_obj);
qdev_free(&d->qdev);
}
}
+1
View File
@@ -77,6 +77,7 @@ int qemu_set_fd_handler2(int fd,
ioh->fd_write = fd_write;
ioh->opaque = opaque;
ioh->deleted = 0;
qemu_notify_event();
}
return 0;
}
+1 -1
View File
@@ -1,7 +1,7 @@
#ifndef __LINUX_KVM_S390_H
#define __LINUX_KVM_S390_H
/*
* asm-s390/kvm.h - KVM s390 specific structures and definitions
* KVM s390 specific structures and definitions
*
* Copyright IBM Corp. 2008
*
+1 -1
View File
@@ -1,5 +1,5 @@
/*
* asm-s390/kvm_para.h - definition for paravirtual devices on s390
* definition for paravirtual devices on s390
*
* Copyright IBM Corp. 2008
*
+1
View File
@@ -12,6 +12,7 @@
/* Select x86 specific features in <linux/kvm.h> */
#define __KVM_HAVE_PIT
#define __KVM_HAVE_IOAPIC
#define __KVM_HAVE_IRQ_LINE
#define __KVM_HAVE_DEVICE_ASSIGNMENT
#define __KVM_HAVE_MSI
#define __KVM_HAVE_USER_NMI
+7
View File
@@ -22,6 +22,7 @@
#define KVM_FEATURE_CLOCKSOURCE2 3
#define KVM_FEATURE_ASYNC_PF 4
#define KVM_FEATURE_STEAL_TIME 5
#define KVM_FEATURE_PV_EOI 6
/* The last 8 bits are used to indicate how to interpret the flags field
* in pvclock structure. If no bits are set, all flags are ignored.
@@ -37,6 +38,7 @@
#define MSR_KVM_SYSTEM_TIME_NEW 0x4b564d01
#define MSR_KVM_ASYNC_PF_EN 0x4b564d02
#define MSR_KVM_STEAL_TIME 0x4b564d03
#define MSR_KVM_PV_EOI_EN 0x4b564d04
struct kvm_steal_time {
__u64 steal;
@@ -89,5 +91,10 @@ struct kvm_vcpu_pv_apf_data {
__u32 enabled;
};
#define KVM_PV_EOI_BIT 0
#define KVM_PV_EOI_MASK (0x1 << KVM_PV_EOI_BIT)
#define KVM_PV_EOI_ENABLED KVM_PV_EOI_MASK
#define KVM_PV_EOI_DISABLED 0x0
#endif /* _ASM_X86_KVM_PARA_H */
+3
View File
@@ -617,6 +617,7 @@ struct kvm_ppc_smmu_info {
#define KVM_CAP_SIGNAL_MSI 77
#define KVM_CAP_PPC_GET_SMMU_INFO 78
#define KVM_CAP_S390_COW 79
#define KVM_CAP_PPC_ALLOC_HTAB 80
#ifdef KVM_CAP_IRQ_ROUTING
@@ -828,6 +829,8 @@ struct kvm_s390_ucas_mapping {
#define KVM_SIGNAL_MSI _IOW(KVMIO, 0xa5, struct kvm_msi)
/* Available with KVM_CAP_PPC_GET_SMMU_INFO */
#define KVM_PPC_GET_SMMU_INFO _IOR(KVMIO, 0xa6, struct kvm_ppc_smmu_info)
/* Available with KVM_CAP_PPC_ALLOC_HTAB */
#define KVM_PPC_ALLOCATE_HTAB _IOWR(KVMIO, 0xa7, __u32)
/*
* ioctls for vcpu fds
+7 -4
View File
@@ -3222,7 +3222,7 @@ struct qemu_argument {
const char *help;
};
struct qemu_argument arg_table[] = {
static const struct qemu_argument arg_table[] = {
{"h", "", false, handle_arg_help,
"", "print this help"},
{"g", "QEMU_GDB", true, handle_arg_gdb,
@@ -3264,7 +3264,7 @@ struct qemu_argument arg_table[] = {
static void usage(void)
{
struct qemu_argument *arginfo;
const struct qemu_argument *arginfo;
int maxarglen;
int maxenvlen;
@@ -3330,7 +3330,7 @@ static int parse_args(int argc, char **argv)
{
const char *r;
int optind;
struct qemu_argument *arginfo;
const struct qemu_argument *arginfo;
for (arginfo = arg_table; arginfo->handle_opt != NULL; arginfo++) {
if (arginfo->env == NULL) {
@@ -3519,7 +3519,10 @@ int main(int argc, char **argv, char **envp)
guest_base = init_guest_space(guest_base, reserved_va, 0,
have_guest_base);
if (guest_base == (unsigned long)-1) {
fprintf(stderr, "Unable to reserve guest address space\n");
fprintf(stderr, "Unable to reserve 0x%lx bytes of virtual address "
"space for use as guest address space (check your virtual "
"memory ulimit setting or reserve less using -R option)\n",
reserved_va);
exit(1);
}
+7 -8
View File
@@ -2848,7 +2848,7 @@ static inline abi_long do_msgrcv(int msqid, abi_long msgp,
if (!lock_user_struct(VERIFY_WRITE, target_mb, msgp, 0))
return -TARGET_EFAULT;
host_mb = malloc(msgsz+sizeof(long));
host_mb = g_malloc(msgsz+sizeof(long));
ret = get_errno(msgrcv(msqid, host_mb, msgsz, tswapal(msgtyp), msgflg));
if (ret > 0) {
@@ -2863,11 +2863,11 @@ static inline abi_long do_msgrcv(int msqid, abi_long msgp,
}
target_mb->mtype = tswapal(host_mb->mtype);
free(host_mb);
end:
if (target_mb)
unlock_user_struct(target_mb, msgp, 1);
g_free(host_mb);
return ret;
}
@@ -7025,15 +7025,14 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
tde = target_dirp;
while (len > 0) {
reclen = de->d_reclen;
treclen = reclen - (2 * (sizeof(long) - sizeof(abi_long)));
tnamelen = reclen - offsetof(struct linux_dirent, d_name);
assert(tnamelen >= 0);
treclen = tnamelen + offsetof(struct target_dirent, d_name);
assert(count1 + treclen <= count);
tde->d_reclen = tswap16(treclen);
tde->d_ino = tswapal(de->d_ino);
tde->d_off = tswapal(de->d_off);
tnamelen = treclen - (2 * sizeof(abi_long) + 2);
if (tnamelen > 256)
tnamelen = 256;
/* XXX: may not be correct */
pstrcpy(tde->d_name, tnamelen, de->d_name);
memcpy(tde->d_name, de->d_name, tnamelen);
de = (struct linux_dirent *)((char *)de + reclen);
len -= reclen;
tde = (struct target_dirent *)((char *)tde + treclen);
+4 -4
View File
@@ -255,10 +255,10 @@ struct kernel_statfs {
};
struct target_dirent {
abi_long d_ino;
abi_long d_off;
unsigned short d_reclen;
char d_name[256]; /* We must not include limits.h! */
abi_long d_ino;
abi_long d_off;
unsigned short d_reclen;
char d_name[];
};
struct target_dirent64 {
+1 -1
View File
@@ -426,7 +426,7 @@ static void memory_region_iorange_write(IORange *iorange,
if (mrp) {
mrp->write(mr->opaque, offset, data);
} else if (width == 2) {
mrp = find_portio(mr, offset - mrio->offset, 1, false);
mrp = find_portio(mr, offset - mrio->offset, 1, true);
assert(mrp);
mrp->write(mr->opaque, offset, data & 0xff);
mrp->write(mr->opaque, offset + 1, data >> 8);
+4 -3
View File
@@ -166,14 +166,15 @@ MigrationInfo *qmp_query_migrate(Error **errp)
case MIG_STATE_ACTIVE:
info->has_status = true;
info->status = g_strdup("active");
info->has_total_time = true;
info->total_time = qemu_get_clock_ms(rt_clock)
- s->total_time;
info->has_ram = true;
info->ram = g_malloc0(sizeof(*info->ram));
info->ram->transferred = ram_bytes_transferred();
info->ram->remaining = ram_bytes_remaining();
info->ram->total = ram_bytes_total();
info->ram->total_time = qemu_get_clock_ms(rt_clock)
- s->total_time;
info->ram->duplicate = dup_mig_pages_transferred();
info->ram->normal = norm_mig_pages_transferred();
info->ram->normal_bytes = norm_mig_bytes_transferred();
@@ -193,13 +194,13 @@ MigrationInfo *qmp_query_migrate(Error **errp)
info->has_status = true;
info->status = g_strdup("completed");
info->total_time = s->total_time;
info->has_ram = true;
info->ram = g_malloc0(sizeof(*info->ram));
info->ram->transferred = ram_bytes_transferred();
info->ram->remaining = 0;
info->ram->total = ram_bytes_total();
info->ram->total_time = s->total_time;
info->ram->duplicate = dup_mig_pages_transferred();
info->ram->normal = norm_mig_pages_transferred();
info->ram->normal_bytes = norm_mig_bytes_transferred();
+4 -2
View File
@@ -2570,11 +2570,11 @@ FdsetInfoList *qmp_query_fdsets(Error **errp)
int monitor_fdset_get_fd(int64_t fdset_id, int flags)
{
#ifndef _WIN32
MonFdset *mon_fdset;
MonFdsetFd *mon_fdset_fd;
int mon_fd_flags;
#ifndef _WIN32
QLIST_FOREACH(mon_fdset, &mon_fdsets, next) {
if (mon_fdset->id != fdset_id) {
continue;
@@ -4832,7 +4832,6 @@ static void monitor_control_event(void *opaque, int event)
switch (event) {
case CHR_EVENT_OPENED:
mon->mc->command_mode = 0;
json_message_parser_init(&mon->mc->parser, handle_qmp_command);
data = get_qmp_greeting();
monitor_json_emitter(mon, data);
qobject_decref(data);
@@ -4840,6 +4839,7 @@ static void monitor_control_event(void *opaque, int event)
break;
case CHR_EVENT_CLOSED:
json_message_parser_destroy(&mon->mc->parser);
json_message_parser_init(&mon->mc->parser, handle_qmp_command);
mon_refcount--;
monitor_fdsets_cleanup();
break;
@@ -4946,6 +4946,8 @@ void monitor_init(CharDriverState *chr, int flags)
qemu_chr_add_handlers(chr, monitor_can_read, monitor_control_read,
monitor_control_event, mon);
qemu_chr_fe_set_echo(chr, true);
json_message_parser_init(&mon->mc->parser, handle_qmp_command);
} else {
qemu_chr_add_handlers(chr, monitor_can_read, monitor_read,
monitor_event, mon);
+1 -1
View File
@@ -12,7 +12,7 @@
1275-1994 (referred to as Open Firmware) compliant firmware.
The included images for PowerPC (for 32 and 64 bit PPC CPUs),
Sparc32 and Sparc64 are built from OpenBIOS SVN revision
1060.
1063.
- SLOF (Slimline Open Firmware) is a free IEEE 1275 Open Firmware
implementation for certain IBM POWER hardware. The sources are at
Binary file not shown.
Binary file not shown.
Binary file not shown.
+46 -7
View File
@@ -290,10 +290,6 @@
#
# @total: total amount of bytes involved in the migration process
#
# @total-time: total amount of ms since migration started. If
# migration has ended, it returns the total migration
# time. (since 1.2)
#
# @duplicate: number of duplicate pages (since 1.2)
#
# @normal : number of normal pages (since 1.2)
@@ -304,8 +300,7 @@
##
{ 'type': 'MigrationStats',
'data': {'transferred': 'int', 'remaining': 'int', 'total': 'int' ,
'total-time': 'int', 'duplicate': 'int', 'normal': 'int',
'normal-bytes': 'int' } }
'duplicate': 'int', 'normal': 'int', 'normal-bytes': 'int' } }
##
# @XBZRLECacheStats
@@ -350,12 +345,17 @@
# migration statistics, only returned if XBZRLE feature is on and
# status is 'active' or 'completed' (since 1.2)
#
# @total-time: #optional total amount of milliseconds since migration started.
# If migration has ended, it returns the total migration
# time. (since 1.2)
#
# Since: 0.14.0
##
{ 'type': 'MigrationInfo',
'data': {'*status': 'str', '*ram': 'MigrationStats',
'*disk': 'MigrationStats',
'*xbzrle-cache': 'XBZRLECacheStats'} }
'*xbzrle-cache': 'XBZRLECacheStats',
'*total-time': 'int'} }
##
# @query-migrate
@@ -2454,3 +2454,42 @@
#
##
{ 'command': 'query-fdsets', 'returns': ['FdsetInfo'] }
##
# @TargetType
#
# Target CPU emulation type
#
# These parameters correspond to the softmmu binary CPU name that is currently
# running.
#
# Since: 1.2.0
##
{ 'enum': 'TargetType',
'data': [ 'alpha', 'arm', 'cris', 'i386', 'lm32', 'm68k', 'microblazeel',
'microblaze', 'mips64el', 'mips64', 'mipsel', 'mips', 'or32',
'ppc64', 'ppcemb', 'ppc', 's390x', 'sh4eb', 'sh4', 'sparc64',
'sparc', 'unicore32', 'x86_64', 'xtensaeb', 'xtensa' ] }
##
# @TargetInfo:
#
# Information describing the QEMU target.
#
# @arch: the target architecture (eg "x86_64", "i386", etc)
#
# Since: 1.2.0
##
{ 'type': 'TargetInfo',
'data': { 'arch': 'TargetType' } }
##
# @query-target:
#
# Return information about the target for this QEMU
#
# Returns: TargetInfo
#
# Since: 1.2.0
##
{ 'command': 'query-target', 'returns': 'TargetInfo' }
+1 -1
View File
@@ -416,7 +416,7 @@ opts_visitor_cleanup(OptsVisitor *ov)
g_hash_table_destroy(ov->unprocessed_opts);
}
g_free(ov->fake_id_opt);
memset(ov, '\0', sizeof *ov);
g_free(ov);
}
+6 -1
View File
@@ -247,6 +247,9 @@ static bool ga_open_pidfile(const char *pidfile)
pidfd = open(pidfile, O_CREAT|O_WRONLY, S_IRUSR|S_IWUSR);
if (pidfd == -1 || lockf(pidfd, F_TLOCK, 0)) {
g_critical("Cannot lock pid file, %s", strerror(errno));
if (pidfd != -1) {
close(pidfd);
}
return false;
}
@@ -435,7 +438,9 @@ static void become_daemon(const char *pidfile)
return;
fail:
unlink(pidfile);
if (pidfile) {
unlink(pidfile);
}
g_critical("failed to daemonize");
exit(EXIT_FAILURE);
#endif
+10
View File
@@ -4,6 +4,16 @@ usage: qemu-img command [command options]
@c man end
@end example
@c man begin DESCRIPTION
qemu-img allows you to create, convert and modify images offline. It can handle
all image formats supported by QEMU.
@b{Warning:} Never use qemu-img to modify images in use by a running virtual
machine or any other process; this may destroy the image. Also, be aware that
querying an image that is being modified by another process may encounter
inconsistent state.
@c man end
@c man begin OPTIONS
The following commands are supported:
-3
View File
@@ -759,11 +759,8 @@ int init_timer_alarm(void)
goto fail;
}
/* first event is at time 0 */
atexit(quit_timers);
t->pending = true;
alarm_timer = t;
return 0;
fail:
+8 -3
View File
@@ -2239,14 +2239,14 @@ The main json-object contains the following:
- "status": migration status (json-string)
- Possible values: "active", "completed", "failed", "cancelled"
- "total-time": total amount of ms since migration started. If
migration has ended, it returns the total migration
time (json-int)
- "ram": only present if "status" is "active", it is a json-object with the
following RAM information (in bytes):
- "transferred": amount transferred (json-int)
- "remaining": amount remaining (json-int)
- "total": total (json-int)
- "total-time": total amount of ms since migration started. If
migration has ended, it returns the total migration time
(json-int)
- "duplicate": number of duplicated pages (json-int)
- "normal" : number of normal pages transferred (json-int)
- "normal-bytes" : number of normal bytes transferred (json-int)
@@ -2509,3 +2509,8 @@ EQMP
.mhandler.cmd_new = qmp_marshal_input_query_cpu_definitions,
},
{
.name = "query-target",
.args_type = "",
.mhandler.cmd_new = qmp_marshal_input_query_target,
},
+2 -3
View File
@@ -373,8 +373,6 @@ static void object_deinit(Object *obj, TypeImpl *type)
if (type_has_parent(type)) {
object_deinit(obj, type_get_parent(type));
}
object_unparent(obj);
}
void object_finalize(void *data)
@@ -411,8 +409,9 @@ Object *object_new(const char *typename)
void object_delete(Object *obj)
{
object_unparent(obj);
g_assert(obj->ref == 1);
object_unref(obj);
g_assert(obj->ref == 0);
g_free(obj);
}
+4 -1
View File
@@ -40,7 +40,7 @@ static void *softmmu_lock_user(CPUArchState *env, uint32_t addr, uint32_t len,
uint8_t *p;
/* TODO: Make this something that isn't fixed size. */
p = malloc(len);
if (copy)
if (p && copy)
cpu_memory_rw_debug(env, addr, p, len, 0);
return p;
}
@@ -52,6 +52,9 @@ static char *softmmu_lock_user_string(CPUArchState *env, uint32_t addr)
uint8_t c;
/* TODO: Make this something that isn't fixed size. */
s = p = malloc(1024);
if (!s) {
return NULL;
}
do {
cpu_memory_rw_debug(env, addr, &c, 1, 0);
addr++;
+7 -6
View File
@@ -194,18 +194,19 @@ uint32_t do_arm_semihosting(CPUARMState *env)
if (!(s = lock_user_string(ARG(0))))
/* FIXME - should this error code be -TARGET_EFAULT ? */
return (uint32_t)-1;
if (ARG(1) >= 12)
if (ARG(1) >= 12) {
unlock_user(s, ARG(0), 0);
return (uint32_t)-1;
}
if (strcmp(s, ":tt") == 0) {
if (ARG(1) < 4)
return STDIN_FILENO;
else
return STDOUT_FILENO;
int result_fileno = ARG(1) < 4 ? STDIN_FILENO : STDOUT_FILENO;
unlock_user(s, ARG(0), 0);
return result_fileno;
}
if (use_gdb_syscalls()) {
gdb_do_syscall(arm_semi_cb, "open,%s,%x,1a4", ARG(0),
(int)ARG(2)+1, gdb_open_modeflags[ARG(1)]);
return env->regs[0];
ret = env->regs[0];
} else {
ret = set_swi_errno(ts, open(s, open_modeflags[ARG(1)], 0644));
}
+14 -1
View File
@@ -33,6 +33,9 @@
#include "hyperv.h"
#include "hw/hw.h"
#if defined(CONFIG_KVM)
#include <linux/kvm_para.h>
#endif
/* feature flags taken from "Intel Processor Identification and the CPUID
* Instruction" and AMD's "CPUID Specification". In cases of disagreement
@@ -887,7 +890,17 @@ static int cpu_x86_find_by_name(x86_def_t *x86_cpu_def, const char *cpu_model)
memcpy(x86_cpu_def, def, sizeof(*def));
}
plus_kvm_features = ~0; /* not supported bits will be filtered out later */
#if defined(CONFIG_KVM)
plus_kvm_features = (1 << KVM_FEATURE_CLOCKSOURCE) |
(1 << KVM_FEATURE_NOP_IO_DELAY) |
(1 << KVM_FEATURE_MMU_OP) |
(1 << KVM_FEATURE_CLOCKSOURCE2) |
(1 << KVM_FEATURE_ASYNC_PF) |
(1 << KVM_FEATURE_STEAL_TIME) |
(1 << KVM_FEATURE_CLOCKSOURCE_STABLE_BIT);
#else
plus_kvm_features = 0;
#endif
add_flagname_to_bitmaps("hypervisor", &plus_features,
&plus_ext_features, &plus_ext2_features, &plus_ext3_features,
+1
View File
@@ -699,6 +699,7 @@ typedef struct CPUX86State {
uint64_t system_time_msr;
uint64_t wall_clock_msr;
uint64_t async_pf_en_msr;
uint64_t pv_eoi_en_msr;
uint64_t tsc;
uint64_t tsc_deadline;
+13
View File
@@ -63,6 +63,7 @@ static bool has_msr_star;
static bool has_msr_hsave_pa;
static bool has_msr_tsc_deadline;
static bool has_msr_async_pf_en;
static bool has_msr_pv_eoi_en;
static bool has_msr_misc_enable;
static int lm_capable_kernel;
@@ -455,6 +456,8 @@ int kvm_arch_init_vcpu(CPUX86State *env)
has_msr_async_pf_en = c->eax & (1 << KVM_FEATURE_ASYNC_PF);
has_msr_pv_eoi_en = c->eax & (1 << KVM_FEATURE_PV_EOI);
cpu_x86_cpuid(env, 0, 0, &limit, &unused, &unused, &unused);
for (i = 0; i <= limit; i++) {
@@ -1017,6 +1020,10 @@ static int kvm_put_msrs(CPUX86State *env, int level)
kvm_msr_entry_set(&msrs[n++], MSR_KVM_ASYNC_PF_EN,
env->async_pf_en_msr);
}
if (has_msr_pv_eoi_en) {
kvm_msr_entry_set(&msrs[n++], MSR_KVM_PV_EOI_EN,
env->pv_eoi_en_msr);
}
if (hyperv_hypercall_available()) {
kvm_msr_entry_set(&msrs[n++], HV_X64_MSR_GUEST_OS_ID, 0);
kvm_msr_entry_set(&msrs[n++], HV_X64_MSR_HYPERCALL, 0);
@@ -1259,6 +1266,9 @@ static int kvm_get_msrs(CPUX86State *env)
if (has_msr_async_pf_en) {
msrs[n++].index = MSR_KVM_ASYNC_PF_EN;
}
if (has_msr_pv_eoi_en) {
msrs[n++].index = MSR_KVM_PV_EOI_EN;
}
if (env->mcg_cap) {
msrs[n++].index = MSR_MCG_STATUS;
@@ -1338,6 +1348,9 @@ static int kvm_get_msrs(CPUX86State *env)
case MSR_KVM_ASYNC_PF_EN:
env->async_pf_en_msr = msrs[i].data;
break;
case MSR_KVM_PV_EOI_EN:
env->pv_eoi_en_msr = msrs[i].data;
break;
}
}
+21
View File
@@ -279,6 +279,13 @@ static bool async_pf_msr_needed(void *opaque)
return cpu->async_pf_en_msr != 0;
}
static bool pv_eoi_msr_needed(void *opaque)
{
CPUX86State *cpu = opaque;
return cpu->pv_eoi_en_msr != 0;
}
static const VMStateDescription vmstate_async_pf_msr = {
.name = "cpu/async_pf_msr",
.version_id = 1,
@@ -290,6 +297,17 @@ static const VMStateDescription vmstate_async_pf_msr = {
}
};
static const VMStateDescription vmstate_pv_eoi_msr = {
.name = "cpu/async_pv_eoi_msr",
.version_id = 1,
.minimum_version_id = 1,
.minimum_version_id_old = 1,
.fields = (VMStateField []) {
VMSTATE_UINT64(pv_eoi_en_msr, CPUX86State),
VMSTATE_END_OF_LIST()
}
};
static bool fpop_ip_dp_needed(void *opaque)
{
CPUX86State *env = opaque;
@@ -453,6 +471,9 @@ static const VMStateDescription vmstate_cpu = {
{
.vmsd = &vmstate_async_pf_msr,
.needed = async_pf_msr_needed,
} , {
.vmsd = &vmstate_pv_eoi_msr,
.needed = pv_eoi_msr_needed,
} , {
.vmsd = &vmstate_fpop_ip_dp,
.needed = fpop_ip_dp_needed,
+10 -4
View File
@@ -7551,8 +7551,11 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
} else {
modrm = cpu_ldub_code(cpu_single_env, s->pc++);
if ((modrm & 0xc0) != 0xc0)
goto illegal_op;
/* Ignore the mod bits (assume (modrm&0xc0)==0xc0).
* AMD documentation (24594.pdf) and testing of
* intel 386 and 486 processors all show that the mod bits
* are assumed to be 1's, regardless of actual values.
*/
rm = (modrm & 7) | REX_B(s);
reg = ((modrm >> 3) & 7) | rex_r;
if (CODE64(s))
@@ -7594,8 +7597,11 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
} else {
modrm = cpu_ldub_code(cpu_single_env, s->pc++);
if ((modrm & 0xc0) != 0xc0)
goto illegal_op;
/* Ignore the mod bits (assume (modrm&0xc0)==0xc0).
* AMD documentation (24594.pdf) and testing of
* intel 386 and 486 processors all show that the mod bits
* are assumed to be 1's, regardless of actual values.
*/
rm = (modrm & 7) | REX_B(s);
reg = ((modrm >> 3) & 7) | rex_r;
if (CODE64(s))
+29 -46
View File
@@ -192,115 +192,98 @@ static inline uint64_t get_HILO (void)
return ((uint64_t)(env->active_tc.HI[0]) << 32) | (uint32_t)env->active_tc.LO[0];
}
static inline void set_HIT0_LO (target_ulong arg1, uint64_t HILO)
static inline target_ulong set_HIT0_LO(uint64_t HILO)
{
target_ulong tmp;
env->active_tc.LO[0] = (int32_t)(HILO & 0xFFFFFFFF);
arg1 = env->active_tc.HI[0] = (int32_t)(HILO >> 32);
tmp = env->active_tc.HI[0] = (int32_t)(HILO >> 32);
return tmp;
}
static inline void set_HI_LOT0 (target_ulong arg1, uint64_t HILO)
static inline target_ulong set_HI_LOT0(uint64_t HILO)
{
arg1 = env->active_tc.LO[0] = (int32_t)(HILO & 0xFFFFFFFF);
target_ulong tmp = env->active_tc.LO[0] = (int32_t)(HILO & 0xFFFFFFFF);
env->active_tc.HI[0] = (int32_t)(HILO >> 32);
return tmp;
}
/* Multiplication variants of the vr54xx. */
target_ulong helper_muls (target_ulong arg1, target_ulong arg2)
{
set_HI_LOT0(arg1, 0 - ((int64_t)(int32_t)arg1 * (int64_t)(int32_t)arg2));
return arg1;
return set_HI_LOT0(0 - ((int64_t)(int32_t)arg1 * (int64_t)(int32_t)arg2));
}
target_ulong helper_mulsu (target_ulong arg1, target_ulong arg2)
{
set_HI_LOT0(arg1, 0 - ((uint64_t)(uint32_t)arg1 * (uint64_t)(uint32_t)arg2));
return arg1;
return set_HI_LOT0(0 - (uint64_t)(uint32_t)arg1 * (uint64_t)(uint32_t)arg2);
}
target_ulong helper_macc (target_ulong arg1, target_ulong arg2)
{
set_HI_LOT0(arg1, ((int64_t)get_HILO()) + ((int64_t)(int32_t)arg1 * (int64_t)(int32_t)arg2));
return arg1;
return set_HI_LOT0((int64_t)get_HILO() + (int64_t)(int32_t)arg1 *
(int64_t)(int32_t)arg2);
}
target_ulong helper_macchi (target_ulong arg1, target_ulong arg2)
{
set_HIT0_LO(arg1, ((int64_t)get_HILO()) + ((int64_t)(int32_t)arg1 * (int64_t)(int32_t)arg2));
return arg1;
return set_HIT0_LO((int64_t)get_HILO() + (int64_t)(int32_t)arg1 *
(int64_t)(int32_t)arg2);
}
target_ulong helper_maccu (target_ulong arg1, target_ulong arg2)
{
set_HI_LOT0(arg1, ((uint64_t)get_HILO()) + ((uint64_t)(uint32_t)arg1 * (uint64_t)(uint32_t)arg2));
return arg1;
return set_HI_LOT0((uint64_t)get_HILO() + (uint64_t)(uint32_t)arg1 *
(uint64_t)(uint32_t)arg2);
}
target_ulong helper_macchiu (target_ulong arg1, target_ulong arg2)
{
set_HIT0_LO(arg1, ((uint64_t)get_HILO()) + ((uint64_t)(uint32_t)arg1 * (uint64_t)(uint32_t)arg2));
return arg1;
return set_HIT0_LO((uint64_t)get_HILO() + (uint64_t)(uint32_t)arg1 *
(uint64_t)(uint32_t)arg2);
}
target_ulong helper_msac (target_ulong arg1, target_ulong arg2)
{
set_HI_LOT0(arg1, ((int64_t)get_HILO()) - ((int64_t)(int32_t)arg1 * (int64_t)(int32_t)arg2));
return arg1;
return set_HI_LOT0((int64_t)get_HILO() - (int64_t)(int32_t)arg1 *
(int64_t)(int32_t)arg2);
}
target_ulong helper_msachi (target_ulong arg1, target_ulong arg2)
{
set_HIT0_LO(arg1, ((int64_t)get_HILO()) - ((int64_t)(int32_t)arg1 * (int64_t)(int32_t)arg2));
return arg1;
return set_HIT0_LO((int64_t)get_HILO() - (int64_t)(int32_t)arg1 *
(int64_t)(int32_t)arg2);
}
target_ulong helper_msacu (target_ulong arg1, target_ulong arg2)
{
set_HI_LOT0(arg1, ((uint64_t)get_HILO()) - ((uint64_t)(uint32_t)arg1 * (uint64_t)(uint32_t)arg2));
return arg1;
return set_HI_LOT0((uint64_t)get_HILO() - (uint64_t)(uint32_t)arg1 *
(uint64_t)(uint32_t)arg2);
}
target_ulong helper_msachiu (target_ulong arg1, target_ulong arg2)
{
set_HIT0_LO(arg1, ((uint64_t)get_HILO()) - ((uint64_t)(uint32_t)arg1 * (uint64_t)(uint32_t)arg2));
return arg1;
return set_HIT0_LO((uint64_t)get_HILO() - (uint64_t)(uint32_t)arg1 *
(uint64_t)(uint32_t)arg2);
}
target_ulong helper_mulhi (target_ulong arg1, target_ulong arg2)
{
set_HIT0_LO(arg1, (int64_t)(int32_t)arg1 * (int64_t)(int32_t)arg2);
return arg1;
return set_HIT0_LO((int64_t)(int32_t)arg1 * (int64_t)(int32_t)arg2);
}
target_ulong helper_mulhiu (target_ulong arg1, target_ulong arg2)
{
set_HIT0_LO(arg1, (uint64_t)(uint32_t)arg1 * (uint64_t)(uint32_t)arg2);
return arg1;
return set_HIT0_LO((uint64_t)(uint32_t)arg1 * (uint64_t)(uint32_t)arg2);
}
target_ulong helper_mulshi (target_ulong arg1, target_ulong arg2)
{
set_HIT0_LO(arg1, 0 - ((int64_t)(int32_t)arg1 * (int64_t)(int32_t)arg2));
return arg1;
return set_HIT0_LO(0 - (int64_t)(int32_t)arg1 * (int64_t)(int32_t)arg2);
}
target_ulong helper_mulshiu (target_ulong arg1, target_ulong arg2)
{
set_HIT0_LO(arg1, 0 - ((uint64_t)(uint32_t)arg1 * (uint64_t)(uint32_t)arg2));
return arg1;
return set_HIT0_LO(0 - (uint64_t)(uint32_t)arg1 * (uint64_t)(uint32_t)arg2);
}
#ifdef TARGET_MIPS64
+29 -8
View File
@@ -5933,6 +5933,7 @@ static void gen_cp0 (CPUMIPSState *env, DisasContext *ctx, uint32_t opc, int rt,
{
const char *opn = "ldst";
check_cp0_enabled(ctx);
switch (opc) {
case OPC_MFC0:
if (rt == 0) {
@@ -6805,7 +6806,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
TCGv_i32 fp1 = tcg_temp_new_i32();
gen_load_fpr32(fp0, fs);
gen_load_fpr32(fp1, fd);
gen_load_fpr32(fp1, ft);
gen_helper_float_recip2_s(fp0, fp0, fp1);
tcg_temp_free_i32(fp1);
gen_store_fpr32(fp0, fd);
@@ -6900,7 +6901,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
gen_load_fpr32(fp32_0, fs);
gen_load_fpr32(fp32_1, ft);
tcg_gen_concat_i32_i64(fp64, fp32_0, fp32_1);
tcg_gen_concat_i32_i64(fp64, fp32_1, fp32_0);
tcg_temp_free_i32(fp32_1);
tcg_temp_free_i32(fp32_0);
gen_store_fpr64(ctx, fp64, fd);
@@ -7543,7 +7544,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
TCGv_i64 fp1 = tcg_temp_new_i64();
gen_load_fpr64(ctx, fp0, fs);
gen_load_fpr64(ctx, fp1, fd);
gen_load_fpr64(ctx, fp1, ft);
gen_helper_float_recip2_ps(fp0, fp0, fp1);
tcg_temp_free_i64(fp1);
gen_store_fpr64(ctx, fp0, fd);
@@ -7742,8 +7743,7 @@ static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
} else if (index == 0) {
gen_load_gpr(t0, base);
} else {
gen_load_gpr(t0, index);
gen_op_addr_add(ctx, t0, cpu_gpr[base], t0);
gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[index]);
}
/* Don't do NOP if destination is zero: we must perform the actual
memory access. */
@@ -8112,7 +8112,11 @@ gen_rdhwr (CPUMIPSState *env, DisasContext *ctx, int rt, int rd)
{
TCGv t0;
#if !defined(CONFIG_USER_ONLY)
/* The Linux kernel will emulate rdhwr if it's not supported natively.
Therefore only check the ISA in system mode. */
check_insn(env, ctx, ISA_MIPS32R2);
#endif
t0 = tcg_temp_new();
switch (rd) {
@@ -10027,7 +10031,7 @@ static void gen_ldst_pair (DisasContext *ctx, uint32_t opc, int rd,
const char *opn = "ldst_pair";
TCGv t0, t1;
if (ctx->hflags & MIPS_HFLAG_BMASK || rd == 31 || rd == base) {
if (ctx->hflags & MIPS_HFLAG_BMASK || rd == 31) {
generate_exception(ctx, EXCP_RI);
return;
}
@@ -10039,6 +10043,10 @@ static void gen_ldst_pair (DisasContext *ctx, uint32_t opc, int rd,
switch (opc) {
case LWP:
if (rd == base) {
generate_exception(ctx, EXCP_RI);
return;
}
save_cpu_state(ctx, 0);
op_ld_lw(t1, t0, ctx);
gen_store_gpr(t1, rd);
@@ -10060,6 +10068,10 @@ static void gen_ldst_pair (DisasContext *ctx, uint32_t opc, int rd,
break;
#ifdef TARGET_MIPS64
case LDP:
if (rd == base) {
generate_exception(ctx, EXCP_RI);
return;
}
save_cpu_state(ctx, 0);
op_ld_ld(t1, t0, ctx);
gen_store_gpr(t1, rd);
@@ -10118,6 +10130,7 @@ static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs,
#ifndef CONFIG_USER_ONLY
case MFC0:
case MFC0 + 32:
check_cp0_enabled(ctx);
if (rt == 0) {
/* Treat as NOP. */
break;
@@ -10126,6 +10139,7 @@ static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs,
break;
case MTC0:
case MTC0 + 32:
check_cp0_enabled(ctx);
{
TCGv t0 = tcg_temp_new();
@@ -10222,10 +10236,12 @@ static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs,
case 0x05:
switch (minor) {
case RDPGPR:
check_cp0_enabled(ctx);
check_insn(env, ctx, ISA_MIPS32R2);
gen_load_srsgpr(rt, rs);
break;
case WRPGPR:
check_cp0_enabled(ctx);
check_insn(env, ctx, ISA_MIPS32R2);
gen_store_srsgpr(rt, rs);
break;
@@ -10266,6 +10282,7 @@ static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs,
case 0x1d:
switch (minor) {
case DI:
check_cp0_enabled(ctx);
{
TCGv t0 = tcg_temp_new();
@@ -10278,6 +10295,7 @@ static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs,
}
break;
case EI:
check_cp0_enabled(ctx);
{
TCGv t0 = tcg_temp_new();
@@ -10758,6 +10776,7 @@ static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx,
minor = (ctx->opcode >> 12) & 0xf;
switch (minor) {
case CACHE:
check_cp0_enabled(ctx);
/* Treat as no-op. */
break;
case LWC2:
@@ -12208,6 +12227,7 @@ static void decode_opc (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
gen_st_cond(ctx, op, rt, rs, imm);
break;
case OPC_CACHE:
check_cp0_enabled(ctx);
check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
/* Treat as NOP. */
break;
@@ -12768,8 +12788,9 @@ void cpu_state_reset(CPUMIPSState *env)
#if defined(CONFIG_USER_ONLY)
env->hflags = MIPS_HFLAG_UM;
/* Enable access to the SYNCI_Step register. */
env->CP0_HWREna |= (1 << 1);
/* Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR
hardware registers. */
env->CP0_HWREna |= 0x0000000F;
if (env->CP0_Config1 & (1 << CP0C1_FP)) {
env->hflags |= MIPS_HFLAG_FPU;
}
+1 -1
View File
@@ -6530,7 +6530,7 @@ static void glue(gen_, name)(DisasContext *ctx) \
ra = gen_avr_ptr(rA(ctx->opcode)); \
rb = gen_avr_ptr(rB(ctx->opcode)); \
rd = gen_avr_ptr(rD(ctx->opcode)); \
gen_helper_##name(rd, cpu_env, ra, rb); \
gen_helper_##name(cpu_env, rd, ra, rb); \
tcg_temp_free_ptr(ra); \
tcg_temp_free_ptr(rb); \
tcg_temp_free_ptr(rd); \
+2
View File
@@ -218,6 +218,8 @@ void HELPER(simcall)(CPUXtensaState *env)
default:
qemu_log("%s(%d): not implemented\n", __func__, regs[2]);
regs[2] = -1;
regs[3] = ENOSYS;
break;
}
}
+153 -102
View File
@@ -176,6 +176,13 @@ static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str)
so don't use these. */
tcg_regset_reset_reg(ct->u.regs, TCG_REG_R0);
tcg_regset_reset_reg(ct->u.regs, TCG_REG_R1);
#if defined(CONFIG_TCG_PASS_AREG0) && (TARGET_LONG_BITS == 64)
/* If we're passing env to the helper as r0 and need a regpair
* for the address then r2 will be overwritten as we're setting
* up the args to the helper.
*/
tcg_regset_reset_reg(ct->u.regs, TCG_REG_R2);
#endif
#endif
break;
case 'L':
@@ -197,6 +204,12 @@ static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str)
use these. */
tcg_regset_reset_reg(ct->u.regs, TCG_REG_R0);
tcg_regset_reset_reg(ct->u.regs, TCG_REG_R1);
#if defined(CONFIG_SOFTMMU) && \
defined(CONFIG_TCG_PASS_AREG0) && (TARGET_LONG_BITS == 64)
/* Avoid clashes with registers being used for helper args */
tcg_regset_reset_reg(ct->u.regs, TCG_REG_R2);
tcg_regset_reset_reg(ct->u.regs, TCG_REG_R3);
#endif
break;
/* qemu_st64 data_reg2 */
case 'S':
@@ -210,6 +223,10 @@ static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str)
#ifdef CONFIG_SOFTMMU
/* r2 is still needed to load data_reg, so don't use it. */
tcg_regset_reset_reg(ct->u.regs, TCG_REG_R2);
#if defined(CONFIG_TCG_PASS_AREG0) && (TARGET_LONG_BITS == 64)
/* Avoid clashes with registers being used for helper args */
tcg_regset_reset_reg(ct->u.regs, TCG_REG_R3);
#endif
#endif
break;
@@ -388,6 +405,14 @@ static inline void tcg_out_dat_reg(TCGContext *s,
(rn << 16) | (rd << 12) | shift | rm);
}
static inline void tcg_out_mov_reg(TCGContext *s, int cond, int rd, int rm)
{
/* Simple reg-reg move, optimising out the 'do nothing' case */
if (rd != rm) {
tcg_out_dat_reg(s, cond, ARITH_MOV, rd, 0, rm, SHIFT_IMM_LSL(0));
}
}
static inline void tcg_out_dat_reg2(TCGContext *s,
int cond, int opc0, int opc1, int rd0, int rd1,
int rn0, int rn1, int rm0, int rm1, int shift)
@@ -966,6 +991,90 @@ static void *qemu_st_helpers[4] = {
__stq_mmu,
};
#endif
/* Helper routines for marshalling helper function arguments into
* the correct registers and stack.
* argreg is where we want to put this argument, arg is the argument itself.
* Return value is the updated argreg ready for the next call.
* Note that argreg 0..3 is real registers, 4+ on stack.
* When we reach the first stacked argument, we allocate space for it
* and the following stacked arguments using "str r8, [sp, #-0x10]!".
* Following arguments are filled in with "str r8, [sp, #0xNN]".
* For more than 4 stacked arguments we'd need to know how much
* space to allocate when we pushed the first stacked argument.
* We don't need this, so don't implement it (and will assert if you try it.)
*
* We provide routines for arguments which are: immediate, 32 bit
* value in register, 16 and 8 bit values in register (which must be zero
* extended before use) and 64 bit value in a lo:hi register pair.
*/
#define DEFINE_TCG_OUT_ARG(NAME, ARGPARAM) \
static TCGReg NAME(TCGContext *s, TCGReg argreg, ARGPARAM) \
{ \
if (argreg < 4) { \
TCG_OUT_ARG_GET_ARG(argreg); \
} else if (argreg == 4) { \
TCG_OUT_ARG_GET_ARG(TCG_REG_R8); \
tcg_out32(s, (COND_AL << 28) | 0x052d8010); \
} else { \
assert(argreg < 8); \
TCG_OUT_ARG_GET_ARG(TCG_REG_R8); \
tcg_out32(s, (COND_AL << 28) | 0x058d8000 | (argreg - 4) * 4); \
} \
return argreg + 1; \
}
#define TCG_OUT_ARG_GET_ARG(A) tcg_out_dat_imm(s, COND_AL, ARITH_MOV, A, 0, arg)
DEFINE_TCG_OUT_ARG(tcg_out_arg_imm32, uint32_t arg)
#undef TCG_OUT_ARG_GET_ARG
#define TCG_OUT_ARG_GET_ARG(A) tcg_out_ext8u(s, COND_AL, A, arg)
DEFINE_TCG_OUT_ARG(tcg_out_arg_reg8, TCGReg arg)
#undef TCG_OUT_ARG_GET_ARG
#define TCG_OUT_ARG_GET_ARG(A) tcg_out_ext16u(s, COND_AL, A, arg)
DEFINE_TCG_OUT_ARG(tcg_out_arg_reg16, TCGReg arg)
#undef TCG_OUT_ARG_GET_ARG
/* We don't use the macro for this one to avoid an unnecessary reg-reg
* move when storing to the stack.
*/
static TCGReg tcg_out_arg_reg32(TCGContext *s, TCGReg argreg, TCGReg arg)
{
if (argreg < 4) {
tcg_out_mov_reg(s, COND_AL, argreg, arg);
} else if (argreg == 4) {
/* str arg, [sp, #-0x10]! */
tcg_out32(s, (COND_AL << 28) | 0x052d0010 | (arg << 12));
} else {
assert(argreg < 8);
/* str arg, [sp, #0xNN] */
tcg_out32(s, (COND_AL << 28) | 0x058d0000 |
(arg << 12) | (argreg - 4) * 4);
}
return argreg + 1;
}
static inline TCGReg tcg_out_arg_reg64(TCGContext *s, TCGReg argreg,
TCGReg arglo, TCGReg arghi)
{
/* 64 bit arguments must go in even/odd register pairs
* and in 8-aligned stack slots.
*/
if (argreg & 1) {
argreg++;
}
argreg = tcg_out_arg_reg32(s, argreg, arglo);
argreg = tcg_out_arg_reg32(s, argreg, arghi);
return argreg;
}
static inline void tcg_out_arg_stacktidy(TCGContext *s, TCGReg argreg)
{
/* Output any necessary post-call cleanup of the stack */
if (argreg > 4) {
tcg_out_dat_imm(s, COND_AL, ARITH_ADD, TCG_REG_R13, TCG_REG_R13, 0x10);
}
}
#endif
#define TLB_SHIFT (CPU_TLB_ENTRY_BITS + CPU_TLB_BITS)
@@ -975,6 +1084,7 @@ static inline void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, int opc)
int addr_reg, data_reg, data_reg2, bswap;
#ifdef CONFIG_SOFTMMU
int mem_index, s_bits;
TCGReg argreg;
# if TARGET_LONG_BITS == 64
int addr_reg2;
# endif
@@ -1088,31 +1198,22 @@ static inline void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, int opc)
tcg_out_b_noaddr(s, COND_EQ);
/* TODO: move this code to where the constants pool will be */
if (addr_reg != TCG_REG_R0) {
tcg_out_dat_reg(s, COND_AL, ARITH_MOV,
TCG_REG_R0, 0, addr_reg, SHIFT_IMM_LSL(0));
}
# if TARGET_LONG_BITS == 32
tcg_out_dat_imm(s, COND_AL, ARITH_MOV, TCG_REG_R1, 0, mem_index);
# else
tcg_out_dat_reg(s, COND_AL, ARITH_MOV,
TCG_REG_R1, 0, addr_reg2, SHIFT_IMM_LSL(0));
tcg_out_dat_imm(s, COND_AL, ARITH_MOV, TCG_REG_R2, 0, mem_index);
# endif
/* Note that this code relies on the constraints we set in arm_op_defs[]
* to ensure that later arguments are not passed to us in registers we
* trash by moving the earlier arguments into them.
*/
argreg = TCG_REG_R0;
#ifdef CONFIG_TCG_PASS_AREG0
/* XXX/FIXME: suboptimal and incorrect for 64 bit */
tcg_out_dat_reg(s, COND_AL, ARITH_MOV,
tcg_target_call_iarg_regs[2], 0,
tcg_target_call_iarg_regs[1], SHIFT_IMM_LSL(0));
tcg_out_dat_reg(s, COND_AL, ARITH_MOV,
tcg_target_call_iarg_regs[1], 0,
tcg_target_call_iarg_regs[0], SHIFT_IMM_LSL(0));
tcg_out_dat_reg(s, COND_AL, ARITH_MOV,
tcg_target_call_iarg_regs[0], 0, TCG_AREG0,
SHIFT_IMM_LSL(0));
argreg = tcg_out_arg_reg32(s, argreg, TCG_AREG0);
#endif
#if TARGET_LONG_BITS == 64
argreg = tcg_out_arg_reg64(s, argreg, addr_reg, addr_reg2);
#else
argreg = tcg_out_arg_reg32(s, argreg, addr_reg);
#endif
argreg = tcg_out_arg_imm32(s, argreg, mem_index);
tcg_out_call(s, (tcg_target_long) qemu_ld_helpers[s_bits]);
tcg_out_arg_stacktidy(s, argreg);
switch (opc) {
case 0 | 4:
@@ -1211,6 +1312,7 @@ static inline void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, int opc)
int addr_reg, data_reg, data_reg2, bswap;
#ifdef CONFIG_SOFTMMU
int mem_index, s_bits;
TCGReg argreg;
# if TARGET_LONG_BITS == 64
int addr_reg2;
# endif
@@ -1314,89 +1416,38 @@ static inline void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, int opc)
tcg_out_b_noaddr(s, COND_EQ);
/* TODO: move this code to where the constants pool will be */
tcg_out_dat_reg(s, COND_AL, ARITH_MOV,
TCG_REG_R0, 0, addr_reg, SHIFT_IMM_LSL(0));
# if TARGET_LONG_BITS == 32
switch (opc) {
case 0:
tcg_out_ext8u(s, COND_AL, TCG_REG_R1, data_reg);
tcg_out_dat_imm(s, COND_AL, ARITH_MOV, TCG_REG_R2, 0, mem_index);
break;
case 1:
tcg_out_ext16u(s, COND_AL, TCG_REG_R1, data_reg);
tcg_out_dat_imm(s, COND_AL, ARITH_MOV, TCG_REG_R2, 0, mem_index);
break;
case 2:
tcg_out_dat_reg(s, COND_AL, ARITH_MOV,
TCG_REG_R1, 0, data_reg, SHIFT_IMM_LSL(0));
tcg_out_dat_imm(s, COND_AL, ARITH_MOV, TCG_REG_R2, 0, mem_index);
break;
case 3:
tcg_out_dat_imm(s, COND_AL, ARITH_MOV, TCG_REG_R8, 0, mem_index);
tcg_out32(s, (COND_AL << 28) | 0x052d8010); /* str r8, [sp, #-0x10]! */
if (data_reg != TCG_REG_R2) {
tcg_out_dat_reg(s, COND_AL, ARITH_MOV,
TCG_REG_R2, 0, data_reg, SHIFT_IMM_LSL(0));
}
if (data_reg2 != TCG_REG_R3) {
tcg_out_dat_reg(s, COND_AL, ARITH_MOV,
TCG_REG_R3, 0, data_reg2, SHIFT_IMM_LSL(0));
}
break;
}
# else
tcg_out_dat_reg(s, COND_AL, ARITH_MOV,
TCG_REG_R1, 0, addr_reg2, SHIFT_IMM_LSL(0));
switch (opc) {
case 0:
tcg_out_ext8u(s, COND_AL, TCG_REG_R2, data_reg);
tcg_out_dat_imm(s, COND_AL, ARITH_MOV, TCG_REG_R3, 0, mem_index);
break;
case 1:
tcg_out_ext16u(s, COND_AL, TCG_REG_R2, data_reg);
tcg_out_dat_imm(s, COND_AL, ARITH_MOV, TCG_REG_R3, 0, mem_index);
break;
case 2:
if (data_reg != TCG_REG_R2) {
tcg_out_dat_reg(s, COND_AL, ARITH_MOV,
TCG_REG_R2, 0, data_reg, SHIFT_IMM_LSL(0));
}
tcg_out_dat_imm(s, COND_AL, ARITH_MOV, TCG_REG_R3, 0, mem_index);
break;
case 3:
tcg_out_dat_imm(s, COND_AL, ARITH_MOV, TCG_REG_R8, 0, mem_index);
tcg_out32(s, (COND_AL << 28) | 0x052d8010); /* str r8, [sp, #-0x10]! */
if (data_reg != TCG_REG_R2) {
tcg_out_dat_reg(s, COND_AL, ARITH_MOV,
TCG_REG_R2, 0, data_reg, SHIFT_IMM_LSL(0));
}
if (data_reg2 != TCG_REG_R3) {
tcg_out_dat_reg(s, COND_AL, ARITH_MOV,
TCG_REG_R3, 0, data_reg2, SHIFT_IMM_LSL(0));
}
break;
}
# endif
/* Note that this code relies on the constraints we set in arm_op_defs[]
* to ensure that later arguments are not passed to us in registers we
* trash by moving the earlier arguments into them.
*/
argreg = TCG_REG_R0;
#ifdef CONFIG_TCG_PASS_AREG0
/* XXX/FIXME: suboptimal and incorrect for 64 bit */
tcg_out_dat_reg(s, COND_AL, ARITH_MOV,
tcg_target_call_iarg_regs[3], 0,
tcg_target_call_iarg_regs[2], SHIFT_IMM_LSL(0));
tcg_out_dat_reg(s, COND_AL, ARITH_MOV,
tcg_target_call_iarg_regs[2], 0,
tcg_target_call_iarg_regs[1], SHIFT_IMM_LSL(0));
tcg_out_dat_reg(s, COND_AL, ARITH_MOV,
tcg_target_call_iarg_regs[1], 0,
tcg_target_call_iarg_regs[0], SHIFT_IMM_LSL(0));
tcg_out_dat_reg(s, COND_AL, ARITH_MOV,
tcg_target_call_iarg_regs[0], 0, TCG_AREG0,
SHIFT_IMM_LSL(0));
argreg = tcg_out_arg_reg32(s, argreg, TCG_AREG0);
#endif
#if TARGET_LONG_BITS == 64
argreg = tcg_out_arg_reg64(s, argreg, addr_reg, addr_reg2);
#else
argreg = tcg_out_arg_reg32(s, argreg, addr_reg);
#endif
switch (opc) {
case 0:
argreg = tcg_out_arg_reg8(s, argreg, data_reg);
break;
case 1:
argreg = tcg_out_arg_reg16(s, argreg, data_reg);
break;
case 2:
argreg = tcg_out_arg_reg32(s, argreg, data_reg);
break;
case 3:
argreg = tcg_out_arg_reg64(s, argreg, data_reg, data_reg2);
break;
}
argreg = tcg_out_arg_imm32(s, argreg, mem_index);
tcg_out_call(s, (tcg_target_long) qemu_st_helpers[s_bits]);
if (opc == 3)
tcg_out_dat_imm(s, COND_AL, ARITH_ADD, TCG_REG_R13, TCG_REG_R13, 0x10);
tcg_out_arg_stacktidy(s, argreg);
reloc_pc24(label_ptr, (tcg_target_long)s->code_ptr);
#else /* !CONFIG_SOFTMMU */
+33 -25
View File
@@ -107,7 +107,7 @@ enum {
};
static const int tcg_target_reg_alloc_order[] = {
TCG_REG_R34,
TCG_REG_R33,
TCG_REG_R35,
TCG_REG_R36,
TCG_REG_R37,
@@ -1532,12 +1532,13 @@ static inline void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, int opc)
}
#ifdef CONFIG_TCG_PASS_AREG0
/* XXX/FIXME: suboptimal */
tcg_out_mov(s, TCG_TYPE_I32, tcg_target_call_iarg_regs[2],
tcg_target_call_iarg_regs[1]);
tcg_out_mov(s, TCG_TYPE_TL, tcg_target_call_iarg_regs[1],
tcg_target_call_iarg_regs[0]);
tcg_out_mov(s, TCG_TYPE_PTR, tcg_target_call_iarg_regs[0],
TCG_AREG0);
tcg_out_bundle(s, mII,
tcg_opc_a5 (TCG_REG_P7, OPC_ADDL_A5, TCG_REG_R58,
mem_index, TCG_REG_R0),
tcg_opc_a4 (TCG_REG_P7, OPC_ADDS_A4,
TCG_REG_R57, 0, TCG_REG_R56),
tcg_opc_a4 (TCG_REG_P7, OPC_ADDS_A4,
TCG_REG_R56, 0, TCG_AREG0));
#endif
if (!bswap || s_bits == 0) {
tcg_out_bundle(s, miB,
@@ -1659,15 +1660,21 @@ static inline void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, int opc)
#ifdef CONFIG_TCG_PASS_AREG0
/* XXX/FIXME: suboptimal */
tcg_out_mov(s, TCG_TYPE_I32, tcg_target_call_iarg_regs[3],
tcg_target_call_iarg_regs[2]);
tcg_out_mov(s, TCG_TYPE_I64, tcg_target_call_iarg_regs[2],
tcg_target_call_iarg_regs[1]);
tcg_out_mov(s, TCG_TYPE_TL, tcg_target_call_iarg_regs[1],
tcg_target_call_iarg_regs[0]);
tcg_out_mov(s, TCG_TYPE_PTR, tcg_target_call_iarg_regs[0],
TCG_AREG0);
#endif
tcg_out_bundle(s, mII,
tcg_opc_a5 (TCG_REG_P7, OPC_ADDL_A5, TCG_REG_R59,
mem_index, TCG_REG_R0),
tcg_opc_a4 (TCG_REG_P7, OPC_ADDS_A4,
TCG_REG_R58, 0, TCG_REG_R57),
tcg_opc_a4 (TCG_REG_P7, OPC_ADDS_A4,
TCG_REG_R57, 0, TCG_REG_R56));
tcg_out_bundle(s, miB,
tcg_opc_m4 (TCG_REG_P6, opc_st_m4[opc],
data_reg, TCG_REG_R3),
tcg_opc_a4 (TCG_REG_P7, OPC_ADDS_A4,
TCG_REG_R56, 0, TCG_AREG0),
tcg_opc_b5 (TCG_REG_P7, OPC_BR_CALL_SPTK_MANY_B5,
TCG_REG_B0, TCG_REG_B6));
#else
tcg_out_bundle(s, miB,
tcg_opc_m4 (TCG_REG_P6, opc_st_m4[opc],
data_reg, TCG_REG_R3),
@@ -1675,6 +1682,7 @@ static inline void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, int opc)
mem_index, TCG_REG_R0),
tcg_opc_b5 (TCG_REG_P7, OPC_BR_CALL_SPTK_MANY_B5,
TCG_REG_B0, TCG_REG_B6));
#endif
}
#else /* !CONFIG_SOFTMMU */
@@ -2314,13 +2322,13 @@ static void tcg_target_qemu_prologue(TCGContext *s)
s->code_ptr += 16; /* skip GP */
/* prologue */
tcg_out_bundle(s, mII,
tcg_out_bundle(s, miI,
tcg_opc_m34(TCG_REG_P0, OPC_ALLOC_M34,
TCG_REG_R33, 32, 24, 0),
TCG_REG_R34, 32, 24, 0),
tcg_opc_a4 (TCG_REG_P0, OPC_ADDS_A4,
TCG_AREG0, 0, TCG_REG_R32),
tcg_opc_i21(TCG_REG_P0, OPC_MOV_I21,
TCG_REG_B6, TCG_REG_R33, 0),
tcg_opc_i22(TCG_REG_P0, OPC_MOV_I22,
TCG_REG_R32, TCG_REG_B0));
TCG_REG_B6, TCG_REG_R33, 0));
/* ??? If GUEST_BASE < 0x200000, we could load the register via
an ADDL in the M slot of the next bundle. */
@@ -2334,10 +2342,10 @@ static void tcg_target_qemu_prologue(TCGContext *s)
}
tcg_out_bundle(s, miB,
tcg_opc_a4 (TCG_REG_P0, OPC_ADDS_A4,
TCG_AREG0, 0, TCG_REG_R32),
tcg_opc_a4 (TCG_REG_P0, OPC_ADDS_A4,
TCG_REG_R12, -frame_size, TCG_REG_R12),
tcg_opc_i22(TCG_REG_P0, OPC_MOV_I22,
TCG_REG_R32, TCG_REG_B0),
tcg_opc_b4 (TCG_REG_P0, OPC_BR_SPTK_MANY_B4, TCG_REG_B6));
/* epilogue */
@@ -2351,7 +2359,7 @@ static void tcg_target_qemu_prologue(TCGContext *s)
tcg_out_bundle(s, miB,
tcg_opc_m48(TCG_REG_P0, OPC_NOP_M48, 0),
tcg_opc_i26(TCG_REG_P0, OPC_MOV_I_I26,
TCG_REG_PFS, TCG_REG_R33),
TCG_REG_PFS, TCG_REG_R34),
tcg_opc_b4 (TCG_REG_P0, OPC_BR_RET_SPTK_MANY_B4,
TCG_REG_B0));
}
@@ -2403,7 +2411,7 @@ static void tcg_target_init(TCGContext *s)
tcg_regset_set_reg(s->reserved_regs, TCG_REG_R12); /* stack pointer */
tcg_regset_set_reg(s->reserved_regs, TCG_REG_R13); /* thread pointer */
tcg_regset_set_reg(s->reserved_regs, TCG_REG_R32); /* return address */
tcg_regset_set_reg(s->reserved_regs, TCG_REG_R33); /* PFS */
tcg_regset_set_reg(s->reserved_regs, TCG_REG_R34); /* PFS */
/* The following 3 are not in use, are call-saved, but *not* saved
by the prologue. Therefore we cannot use them without modifying
Loaded 100 of 106 files, more files were not shown because too many files have changed in this diff. Show more