Re: [Qemu-devel] [PATCH 8/8] usb-hid: Allow connecting to a USB-2 device
Il 06/11/2012 15:08, Hans de Goede ha scritto: > Our ehci code has is capable of significantly lowering the wakeup rate > for the hcd emulation while the device is idle. It is possible to add > similar code ot the uhci emulation, but that simply is not there atm, > and there is no reason why a (virtual) usb device can not be a USB-2 device. > > Making usb-hid devices connect to the emulated ehci controller instead > of the emulated uhci controller on vms which have both lowers the cpuload > for a fully idle vm from 20% to 2-3% (on my laptop). You need this to be dependent on the machine version. Otherwise the USB paths may change and migration will break. Paolo > Signed-off-by: Hans de Goede > --- > hw/usb/dev-hid.c | 9 ++--- > 1 file changed, 6 insertions(+), 3 deletions(-) > > diff --git a/hw/usb/dev-hid.c b/hw/usb/dev-hid.c > index 69f89ff..96ba0c0 100644 > --- a/hw/usb/dev-hid.c > +++ b/hw/usb/dev-hid.c > @@ -97,7 +97,7 @@ static const USBDescIface desc_iface_mouse = { > .bEndpointAddress = USB_DIR_IN | 0x01, > .bmAttributes = USB_ENDPOINT_XFER_INT, > .wMaxPacketSize= 4, > -.bInterval = 0x0a, > +.bInterval = 8, > }, > }, > }; > @@ -127,7 +127,7 @@ static const USBDescIface desc_iface_tablet = { > .bEndpointAddress = USB_DIR_IN | 0x01, > .bmAttributes = USB_ENDPOINT_XFER_INT, > .wMaxPacketSize= 8, > -.bInterval = 0x0a, > +.bInterval = 8, > }, > }, > }; > @@ -158,7 +158,7 @@ static const USBDescIface desc_iface_keyboard = { > .bEndpointAddress = USB_DIR_IN | 0x01, > .bmAttributes = USB_ENDPOINT_XFER_INT, > .wMaxPacketSize= 8, > -.bInterval = 0x0a, > +.bInterval = 8, > }, > }, > }; > @@ -224,6 +224,7 @@ static const USBDesc desc_mouse = { > .iSerialNumber = STR_SERIALNUMBER, > }, > .full = &desc_device_mouse, > +.high = &desc_device_mouse, > .str = desc_strings, > }; > > @@ -237,6 +238,7 @@ static const USBDesc desc_tablet = { > .iSerialNumber = STR_SERIALNUMBER, > }, > .full = &desc_device_tablet, > +.high = &desc_device_tablet, > .str = desc_strings, > }; > > @@ -250,6 +252,7 @@ static const USBDesc desc_keyboard = { > .iSerialNumber = STR_SERIALNUMBER, > }, > .full = &desc_device_keyboard, > +.high = &desc_device_keyboard, > .str = desc_strings, > }; > >
Re: [Qemu-devel] [PATCH 2/8] usb-redir: Store interrupt receiving status in the bufp-queue
Il 06/11/2012 15:08, Hans de Goede ha scritto: > Since we handle interrupt out async, and not buffered like iso-out, there is > no need for a separate status flag, instead store any reported error status > into the bufp queue. > > Signed-off-by: Hans de Goede > --- > hw/usb/redirect.c | 24 +--- > 1 file changed, 9 insertions(+), 15 deletions(-) > > diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c > index 9052ef8..b61bb6e 100644 > --- a/hw/usb/redirect.c > +++ b/hw/usb/redirect.c > @@ -58,11 +58,11 @@ struct endp_data { > uint8_t type; > uint8_t interval; > uint8_t interface; /* bInterfaceNumber this ep belongs to */ > +uint8_t zero; /* Was interrupt_error, now always 0 for migration compat > */ No need for this, use VMSTATE_UNUSED. But if you do this, you need to bump the migration version because the old version will not be able to retrieve the interrupt_error value. Can you somewhat figure out it in the pre_load callback instead? Hmm... well, migration from usbredir is new in 1.3, so you do have time to change the protocol. You do not need zero, you do not need VMSTATE_UNUSED. But you'd better do this change as well in a certain downstream you care about, otherwise you'll have the same problem soon. Paolo > uint16_t max_packet_size; /* In bytes, not wMaxPacketSize format !! */ > uint8_t iso_started; > uint8_t iso_error; /* For reporting iso errors to the HC */ > uint8_t interrupt_started; > -uint8_t interrupt_error; > uint8_t bufpq_prefilled; > uint8_t bufpq_dropping_packets; > QTAILQ_HEAD(, buf_packet) bufpq; > @@ -626,7 +626,7 @@ static void > usbredir_handle_interrupt_in_data(USBRedirDevice *dev, > int status, len; > > if (!dev->endpoint[EP2I(ep)].interrupt_started && > -!dev->endpoint[EP2I(ep)].interrupt_error) { > +QTAILQ_EMPTY(&dev->endpoint[EP2I(ep)].bufpq)) { > struct usb_redir_start_interrupt_receiving_header start_int = { > .endpoint = ep, > }; > @@ -645,14 +645,7 @@ static void > usbredir_handle_interrupt_in_data(USBRedirDevice *dev, > intp = QTAILQ_FIRST(&dev->endpoint[EP2I(ep)].bufpq); > if (intp == NULL) { > DPRINTF2("interrupt-token-in ep %02X, no intp\n", ep); > -/* Check interrupt_error for stream errors */ > -status = dev->endpoint[EP2I(ep)].interrupt_error; > -dev->endpoint[EP2I(ep)].interrupt_error = 0; > -if (status) { > -usbredir_handle_status(dev, p, status); > -} else { > -p->status = USB_RET_NAK; > -} > +p->status = USB_RET_NAK; > return; > } > DPRINTF("interrupt-token-in ep %02X status %d len %d\n", ep, > @@ -708,7 +701,6 @@ static void > usbredir_stop_interrupt_receiving(USBRedirDevice *dev, > DPRINTF("interrupt recv stopped ep %02X\n", ep); > dev->endpoint[EP2I(ep)].interrupt_started = 0; > } > -dev->endpoint[EP2I(ep)].interrupt_error = 0; > usbredir_free_bufpq(dev, ep); > } > > @@ -1513,20 +1505,22 @@ static void usbredir_interrupt_receiving_status(void > *priv, uint64_t id, > { > USBRedirDevice *dev = priv; > uint8_t ep = interrupt_receiving_status->endpoint; > +uint8_t status = interrupt_receiving_status->status; > > DPRINTF("interrupt recv status %d ep %02X id %"PRIu64"\n", > interrupt_receiving_status->status, ep, id); > > -if (!dev->dev.attached || !dev->endpoint[EP2I(ep)].interrupt_started) { > +if (!dev->dev.attached || !dev->endpoint[EP2I(ep)].interrupt_started || > +status == usb_redir_success) { > return; > } > > -dev->endpoint[EP2I(ep)].interrupt_error = > -interrupt_receiving_status->status; > if (interrupt_receiving_status->status == usb_redir_stall) { > DPRINTF("interrupt receiving stopped by peer ep %02X\n", ep); > dev->endpoint[EP2I(ep)].interrupt_started = 0; > +status = usb_redir_ioerror; > } > +bufp_alloc(dev, NULL, 0, status, ep); > } > > static void usbredir_bulk_streams_status(void *priv, uint64_t id, > @@ -1833,7 +1827,7 @@ static const VMStateDescription usbredir_ep_vmstate = { > VMSTATE_UINT8(iso_started, struct endp_data), > VMSTATE_UINT8(iso_error, struct endp_data), > VMSTATE_UINT8(interrupt_started, struct endp_data), > -VMSTATE_UINT8(interrupt_error, struct endp_data), > +VMSTATE_UINT8(zero, struct endp_data), /* Was interrupt_error */ > VMSTATE_UINT8(bufpq_prefilled, struct endp_data), > VMSTATE_UINT8(bufpq_dropping_packets, struct endp_data), > { >
Re: [Qemu-devel] [PATCH] Fix out-of-tree and cross compile builds for pixman
On 11/03/12 21:15, Blue Swirl wrote: > On Sat, Nov 3, 2012 at 7:02 PM, Peter Maydell > wrote: >> On 3 November 2012 19:47, Blue Swirl wrote: >>> --- a/Makefile >>> +++ b/Makefile >>> @@ -122,7 +122,7 @@ subdir-pixman: pixman/Makefile >>> $(call quiet-command,$(MAKE) $(SUBDIR_MAKEFLAGS) -C pixman V="$(V)" >>> all,) >>> >>> pixman/Makefile: $(SRC_PATH)/pixman/configure >>> - (cd pixman; $(SRC_PATH)/pixman/configure --disable-shared >>> --enable-static) >>> + (cd pixman; CC=$(CC) LD=$(LD) AR=$(AR) NM=$(NM) RANLIB=$(RANLIB) >>> $(SRC_PATH)/pixman/configure --disable-shared --enable-static) >> >> Not tested, but aren't there quoting issues here if you're >> building with --cc='ccache gcc' ? > > Yes. Also configure fails because the variables are not expanded and > directory pixman/pixman does not exist. Funny how it worked earlier. Turned out part of the issue is that having pixman-devel installed masked some of the build issues of the internal pixman even when building --without-pixman-system, so my build testing was incomplete. Pushed test branch: git://git.kraxel.org/qemu rebase/pixman Dependency issue isn't tackled yet, but non-parallel builds are working fine for me. Feedback is welcome. cheers, Gerd
Re: [Qemu-devel] [PATCH] Fix out-of-tree and cross compile builds for pixman
Hi, > The internal pixman code is also too old for cross compilations with > MinGW-w64. It already fails when running configure. > > Newer versions of pixman compile after a trivial modification which > is needed to avoid redefined symbols: I'd prefer to not have local patches. Can you submit the patch to upstream pixman? Then we can just switch to a fixed checkout to get w64 going. thanks, Gerd
Re: [Qemu-devel] 64-on-32 TCG broken
> diff --git a/tcg/tcg.c b/tcg/tcg.c > index c3a7f19..1133438 100644 > --- a/tcg/tcg.c > +++ b/tcg/tcg.c > @@ -1329,8 +1329,8 @@ static void tcg_liveness_analysis(TCGContext *s) > the low part. The result can be optimized to a simple > add or sub. This happens often for x86_64 guest when the > cpu mode is set to 32 bit. */ > -if (dead_temps[args[1]]) { > -if (dead_temps[args[0]]) { > +if (dead_temps[args[1]] && !mem_temps[1]) { > +if (dead_temps[args[0]] && !mem_temps[0]) { This should be mem_temps[args[1]] and mem_temps[args[0]] I believe. > goto do_remove; > } > /* Create the single operation plus nop. */ > @@ -1355,8 +1355,8 @@ static void tcg_liveness_analysis(TCGContext *s) > nb_iargs = 2; > nb_oargs = 2; > /* Likewise, test for the high part of the operation dead. */ > -if (dead_temps[args[1]]) { > -if (dead_temps[args[0]]) { > +if (dead_temps[args[1]] && !mem_temps[1]) { > +if (dead_temps[args[0]] && !mem_temps[0]) { Same here. > goto do_remove; > } > gen_opc_buf[op_index] = op = INDEX_op_mul_i32; Looks like for x86_64 guest temp 0 is the env (always mem_temp), temp 1 - cc_op. As a result it can accidentally remove high part of operation when it is actually alive but will never optimize out whole operation even if its output is really dead. I've attached a small patch to fix this issue. I was not able to boot gentoo install CD (amd64) with current trunk. Boot process hangs soon after framebuffer initialization. With the patch it boots successfully. Command line to reproduce: qemu-system-x86_64 -cdrom install-amd64-minimal-20121013.iso -- Kirill BatuzovFrom 33e1fc03934cebea8d32c98ea34961c80f05d94a Mon Sep 17 00:00:00 2001 From: Kirill Batuzov Date: Wed, 7 Nov 2012 15:26:38 +0400 Subject: [PATCH] tcg: properly check that op's output needs to be synced to memory Fix typo introduced in b3a1be87bac3a6aaa59bb88c1410f170dc9b22d5. Reported-by: Ruslan Savchenko Signed-off-by: Kirill Batuzov --- tcg/tcg.c |8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tcg/tcg.c b/tcg/tcg.c index 42052db..35fba50 100644 --- a/tcg/tcg.c +++ b/tcg/tcg.c @@ -1337,8 +1337,8 @@ static void tcg_liveness_analysis(TCGContext *s) the low part. The result can be optimized to a simple add or sub. This happens often for x86_64 guest when the cpu mode is set to 32 bit. */ -if (dead_temps[args[1]] && !mem_temps[1]) { -if (dead_temps[args[0]] && !mem_temps[0]) { +if (dead_temps[args[1]] && !mem_temps[args[1]]) { +if (dead_temps[args[0]] && !mem_temps[args[0]]) { goto do_remove; } /* Create the single operation plus nop. */ @@ -1363,8 +1363,8 @@ static void tcg_liveness_analysis(TCGContext *s) nb_iargs = 2; nb_oargs = 2; /* Likewise, test for the high part of the operation dead. */ -if (dead_temps[args[1]] && !mem_temps[1]) { -if (dead_temps[args[0]] && !mem_temps[0]) { +if (dead_temps[args[1]] && !mem_temps[args[1]]) { +if (dead_temps[args[0]] && !mem_temps[args[0]]) { goto do_remove; } gen_opc_buf[op_index] = op = INDEX_op_mul_i32; -- 1.7.9.5
Re: [Qemu-devel] Qemu Monitor
Forwarding your mail to qemu-devel, where it really belongs. Keivn Am 07.11.2012 14:32, schrieb Muhammad Nouman: > Hi ! I am trying to use qemu monitor *info tlb* But when i enter > ctrl+a+c ,and then enter info tlb , i don't find *info tlb* option in > the monitors list given below. > > (qemu) info tlb > info balloon -- show balloon information > info block -- show the block devices > info blockstats -- show block device statistics > info capture -- show capture information > info chardev -- show the character devices > info cpus -- show infos for each CPU > info history -- show the command line history > info irq -- show the interrupts statistics (if available) > info jit -- show dynamic compiler info > info kvm -- show KVM information > info mice -- show which guest mouse is receiving events > info migrate -- show migration status > info mtree -- show memory tree > info name -- show the current VM name > info network -- show the network state > info numa -- show NUMA information > info pci -- show PCI info > info pcmcia -- show guest PCMCIA status > info pic -- show i8259 (PIC) state > info profile -- show profiling information > info qdm -- show qdev device model list > info qtree -- show device tree > info registers -- show the cpu registers > info roms -- show roms > info snapshots -- show the currently saved VM snapshots > info status -- show the current VM status (running|paused) > info trace-events -- show available trace-events & their state > info usb -- show guest USB devices > info usbhost -- show host USB devices > info usernet -- show user network stack connection states > info uuid -- show the current VM UUID > info version -- show the version of QEMU > info vnc -- show the vnc server status > > *You can see , no info tlb option in it.So, what should i do to see tlb?? > * > > Thanks > Regards > Nouman >
Re: [Qemu-devel] qemu.org DNS status
Am 02.11.2012 20:10, schrieb anth...@codemonkey.ws: Hi, I wanted to update everyone on the qemu.org DNS status. This morning it was reported that the two nameservers that qemu.org is configured to use are down. I do not have access to the DNS records for qemu.org as they are graciously donated by a third party. I've contacted the owner of the records who has been fairly responsive in the past. In the interim, I've setup an alternative hostname, qemu-project.org, that can be used as an alternative to qemu.org. This hostname will remain active even when qemu.org is restored. Sorry for the inconvenience. Regards, Anthony Liguori Hi, the domain owner has updated the DNS server entries, so git.qemu.org, www.qemu.org and wiki.qemu.org work again. Regards, Stefan Weil
Re: [Qemu-devel] scsi-hd with discard_granularity and unmap results in Aborted Commands
Am 06.11.2012 23:42, schrieb Paolo Bonzini: i wantes to use scsi unmap with rbd. rbd documention says you need to set discard_granularity=512 for the device. I'm using qemu 1.2. If i set this and send an UNMAP command i get this kernel output: The discard request is failing. Please check why with a breakpoint on rbd_aio_discard_wrapper or scsi_handle_rw_error for example. I've no idea about setting breakpoints and analyse what happens... no C coder just perl. I can for sure modify code and compile... but i don't know how todo that. Greets, Stefan
Re: [Qemu-devel] [PATCH] Fix out-of-tree and cross compile builds for pixman
This may not be the prettiest fix for the pixman dependency but it seems to work. diff --git a/configure b/configure index f0bc726..fcb744e 100755 --- a/configure +++ b/configure @@ -4154,6 +4154,10 @@ echo "QEMU_CFLAGS+=$cflags" >> $config_target_mak echo "QEMU_INCLUDES+=$includes" >> $config_target_mak done # for target in $targets + +if [ "$pixman" = "internal" ]; then + echo "config-host.h: pixman/Makefile" >> $config_host_mak +fi # build tree in object directory in case the source is not in the current directory DIRS="tests tests/tcg tests/tcg/cris tests/tcg/lm32" > -Original Message- > From: qemu-devel-bounces+ericj=mips@nongnu.org [mailto:qemu-devel- > bounces+ericj=mips@nongnu.org] On Behalf Of Gerd Hoffmann > Sent: Wednesday, November 07, 2012 3:43 AM > To: Blue Swirl > Cc: Peter Maydell; qemu-devel@nongnu.org > Subject: Re: [Qemu-devel] [PATCH] Fix out-of-tree and cross compile builds > for pixman > > On 11/03/12 21:15, Blue Swirl wrote: > > On Sat, Nov 3, 2012 at 7:02 PM, Peter Maydell > wrote: > >> On 3 November 2012 19:47, Blue Swirl wrote: > >>> --- a/Makefile > >>> +++ b/Makefile > >>> @@ -122,7 +122,7 @@ subdir-pixman: pixman/Makefile > >>> $(call quiet-command,$(MAKE) $(SUBDIR_MAKEFLAGS) -C pixman > V="$(V)" all,) > >>> > >>> pixman/Makefile: $(SRC_PATH)/pixman/configure > >>> - (cd pixman; $(SRC_PATH)/pixman/configure --disable-shared -- > enable-static) > >>> + (cd pixman; CC=$(CC) LD=$(LD) AR=$(AR) NM=$(NM) > RANLIB=$(RANLIB) $(SRC_PATH)/pixman/configure --disable-shared --enable- > static) > >> > >> Not tested, but aren't there quoting issues here if you're > >> building with --cc='ccache gcc' ? > > > > Yes. Also configure fails because the variables are not expanded and > > directory pixman/pixman does not exist. Funny how it worked earlier. > > Turned out part of the issue is that having pixman-devel installed > masked some of the build issues of the internal pixman even when > building --without-pixman-system, so my build testing was incomplete. > > Pushed test branch: > git://git.kraxel.org/qemu rebase/pixman > > Dependency issue isn't tackled yet, but non-parallel builds are working > fine for me. Feedback is welcome. > > cheers, > Gerd >
Re: [Qemu-devel] [PATCH] Fix out-of-tree and cross compile builds for pixman
Sorry, I didn’t let the make finish but I think there will be linking errors with the previous because libpixman-1.a may not be built. The following changes to Gerd's rebase/pixman branch will completely build (except s390x). On RHEL 5.7 (no pixman on system): $ ../kraxel.org/configure --without-system-pixman $ make -k -j8 diff --git a/configure b/configure index f0bc726..d946937 100755 --- a/configure +++ b/configure @@ -3955,9 +3955,6 @@ if test "$target_softmmu" = "yes" ; then if test "$smartcard_nss" = "yes" ; then echo "subdir-$target: subdir-libcacard" >> $config_host_mak fi - if test "$pixman" = "internal" ; then -echo "subdir-$target: subdir-pixman" >> $config_host_mak - fi case "$target_arch2" in i386|x86_64) echo "CONFIG_HAVE_CORE_DUMP=y" >> $config_target_mak @@ -4154,6 +4151,10 @@ echo "QEMU_CFLAGS+=$cflags" >> $config_target_mak echo "QEMU_INCLUDES+=$includes" >> $config_target_mak done # for target in $targets + +if [ "$pixman" = "internal" ]; then + echo "config-host.h: subdir-pixman" >> $config_host_mak +fi # build tree in object directory in case the source is not in the current directory DIRS="tests tests/tcg tests/tcg/cris tests/tcg/lm32" cc1: warnings being treated as errors /home/ericj/work/qemu/kraxel.org/hw/s390x/event-facility.c: In function 'command_handler': /home/ericj/work/qemu/kraxel.org/hw/s390x/event-facility.c:110: warning: 'rc' may be used uninitialized in this function make[1]: *** [hw/s390x/event-facility.o] Error 1 > -Original Message- > From: qemu-devel-bounces+ericj=mips@nongnu.org [mailto:qemu-devel- > bounces+ericj=mips@nongnu.org] On Behalf Of Johnson, Eric > Sent: Wednesday, November 07, 2012 12:07 PM > To: Gerd Hoffmann; Blue Swirl > Cc: Peter Maydell; qemu-devel@nongnu.org > Subject: Re: [Qemu-devel] [PATCH] Fix out-of-tree and cross compile builds > for pixman > > This may not be the prettiest fix for the pixman dependency but it seems > to work. > > diff --git a/configure b/configure > index f0bc726..fcb744e 100755 > --- a/configure > +++ b/configure > @@ -4154,6 +4154,10 @@ echo "QEMU_CFLAGS+=$cflags" >> $config_target_mak > echo "QEMU_INCLUDES+=$includes" >> $config_target_mak > > done # for target in $targets > + > +if [ "$pixman" = "internal" ]; then > + echo "config-host.h: pixman/Makefile" >> $config_host_mak > +fi > > # build tree in object directory in case the source is not in the current > directory > DIRS="tests tests/tcg tests/tcg/cris tests/tcg/lm32" > > > -Original Message- > > From: qemu-devel-bounces+ericj=mips@nongnu.org [mailto:qemu-devel- > > bounces+ericj=mips@nongnu.org] On Behalf Of Gerd Hoffmann > > Sent: Wednesday, November 07, 2012 3:43 AM > > To: Blue Swirl > > Cc: Peter Maydell; qemu-devel@nongnu.org > > Subject: Re: [Qemu-devel] [PATCH] Fix out-of-tree and cross compile > builds > > for pixman > > > > On 11/03/12 21:15, Blue Swirl wrote: > > > On Sat, Nov 3, 2012 at 7:02 PM, Peter Maydell > > > wrote: > > >> On 3 November 2012 19:47, Blue Swirl wrote: > > >>> --- a/Makefile > > >>> +++ b/Makefile > > >>> @@ -122,7 +122,7 @@ subdir-pixman: pixman/Makefile > > >>> $(call quiet-command,$(MAKE) $(SUBDIR_MAKEFLAGS) -C pixman > > V="$(V)" all,) > > >>> > > >>> pixman/Makefile: $(SRC_PATH)/pixman/configure > > >>> - (cd pixman; $(SRC_PATH)/pixman/configure --disable-shared -- > > enable-static) > > >>> + (cd pixman; CC=$(CC) LD=$(LD) AR=$(AR) NM=$(NM) > > RANLIB=$(RANLIB) $(SRC_PATH)/pixman/configure --disable-shared --enable- > > static) > > >> > > >> Not tested, but aren't there quoting issues here if you're > > >> building with --cc='ccache gcc' ? > > > > > > Yes. Also configure fails because the variables are not expanded and > > > directory pixman/pixman does not exist. Funny how it worked earlier. > > > > Turned out part of the issue is that having pixman-devel installed > > masked some of the build issues of the internal pixman even when > > building --without-pixman-system, so my build testing was incomplete. > > > > Pushed test branch: > > git://git.kraxel.org/qemu rebase/pixman > > > > Dependency issue isn't tackled yet, but non-parallel builds are working > > fine for me. Feedback is welcome. > > > > cheers, > > Gerd > >
[Qemu-devel] mask specific partition from guest
Hi all, I am trying to boot a real Linux OS inside qemu. The OS resides on a real disk with a partition layout: 1. data 2. os 3. data Partiton 1 is being used by the host and i would like to hide it from guest. In virtualbox/vmware, this can be done by creating a vmdk file marking corresponding extent as "ZERO" and it will ignores all writes. e.g. version=1 encoding="UTF-8" CID=0510e33b parentCID= isNativeSnapshot="no" createType="partitionedDevice" RW 34 FLAT "header" 0 RW 2014 ZERO RW 204800 ZERO RW 262144 ZERO RW 125364224 ZERO RW 1124425728 FLAT "/dev/sdc" 125833216 ... How can this be done in qemu/kvm? ching
[Qemu-devel] [QEMU PATCH] microblaze: translate.c: Fix swaph decoding
The swaph instruction was not decoding correctly. s/1e1/1e2 on the 9 LSBs on the instruction decode. Reported-by: David Holsgrove Signed-off-by: Peter Crosthwaite --- target-microblaze/translate.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/target-microblaze/translate.c b/target-microblaze/translate.c index 7d864b1..6f27c24 100644 --- a/target-microblaze/translate.c +++ b/target-microblaze/translate.c @@ -840,7 +840,7 @@ static void dec_bit(DisasContext *dc) LOG_DIS("swapb r%d r%d\n", dc->rd, dc->ra); tcg_gen_bswap32_i32(cpu_R[dc->rd], cpu_R[dc->ra]); break; -case 0x1e1: +case 0x1e2: /*swaph */ LOG_DIS("swaph r%d r%d\n", dc->rd, dc->ra); tcg_gen_rotri_i32(cpu_R[dc->rd], cpu_R[dc->ra], 16); -- 1.7.0.4
[Qemu-devel] RFC: Partial workaround for buggy guest virtio-balloon driver
Linux kernel commits 1a87228f5f1d316002c7c161316f5524592be766 "virtio_balloon: Fix endian bug" and 3ccc9372ed0fab33d20f10be3c1efd5776ff5913 "virtio_balloon: fix handling of PAGE_SIZE != 4k" fixed two serious bugs in their (guest side) handling of the virtio balloon. In practice, these bugs only affected powerpc guests, which is big-endian and frequently configured for 64k base page size. Attempting to use the balloon with the buggy guest would usually result in an immediate guest crash. The bugs are fixed now, of course and the balloon works fine with kernels v3.4 and later, but unfortunately there are many distro releases still in use which still have buggy kernels. The nature of the page size bug makes it impossible to work around from the host side (there simply isn't enough information supplied to operate the balloon correctly). However, it *is* possible with some fiddling to safely detect the endian bug in the guest kernel, and disable the balloon in this case. The two fixes were applied to the mainline kernel almost consecutively, so there are no released kernels with one fix but not the other, meaning we can use the presence of the endian bug as a proxy for the presence of the page size bug. This patch implements such a test, working as follows. For a fixed guest kernel: 1. qemu sets a state variable to "TESTING" and the initial balloon target size to 16 (4k pages). 2. When the guest balloon driver starts, it sees the target, finds either 16 unused 4k pages or 1 unused 64k page (depending on guest config) and submits the 16 resulting 4k pfns to the host. qemu, in TESTING state, ignores the submitted pages for now. 4. The guest then updates the 'actual' field in the balloon config space to 16. qemu sees this and determines that the guest is not buggy, it moves to CLEANUP state, and sets the target balloon size back to 0. 5. The guest sees the target go back to 0, and reclaims its page(s) from the balloon. qemu continues to ignore the page addresses for now in CLEANUP state. 6. The guest updates the actual field to 0. qemu now considers cleanup complete and moves to GOOD state. The balloon now operates normally. For a buggy kernel: 1. qemu sets a state variable to "TESTING" and the initial balloon target size to 16 (4k pages). 2. When the guest balloon driver starts it sees the non-zero target, and misinterprets it as 268435456 (endian bug). It starts trying to find pages to free. 3. The guest is probably newly booted, so it almost certainly finds 256 pages easily and submits incorrect addresses for them (page size bug) to the host. qemu, in TESTING state ignores the (wrong) addresses for now. 4. The guest updates the actual field in config space to 256. qemu sees this, and determines that the guest is buggy. It moves to BUGGY state and sets the balloon target back to zero. 5. The guest, before attempting to find the next batch of pages to free, rechecks the target and discovers it is now zero. It reclaims the pages by submitting more wrong addresses, which qemu ignores. 6. The balloon is now disabled, if the user attempts to change the balloon size, qemu print an error message and otherwise ignore it. I'm aware that this patch needs a bunch more comments (largely based on the info above), but otherwise do people think this is a reasonable approach. It doesn't (and can't) fix the balloon for buggy kernels, but it does make the failure mode a lot less ugly. >From dbc721f5e50a39ca3b40d81f060d8bb0e6312995 Mon Sep 17 00:00:00 2001 From: David Gibson Date: Thu, 8 Nov 2012 14:49:38 +1100 Subject: [PATCH] Detection of buggy guest balloon --- hw/virtio-balloon.c | 77 +++ 1 file changed, 72 insertions(+), 5 deletions(-) diff --git a/hw/virtio-balloon.c b/hw/virtio-balloon.c index dd1a650..6a9cd3f 100644 --- a/hw/virtio-balloon.c +++ b/hw/virtio-balloon.c @@ -37,8 +37,16 @@ typedef struct VirtIOBalloon VirtQueueElement stats_vq_elem; size_t stats_vq_offset; DeviceState *qdev; + +int guest_bug_state; +#define GUEST_BUG_TESTING 0 +#define GUEST_BUG_CLEANUP 1 +#define GUEST_BUG_BUGGY 2 +#define GUEST_BUG_GOOD 3 } VirtIOBalloon; +#define GUEST_BUG_TARGET16 + static VirtIOBalloon *to_virtio_balloon(VirtIODevice *vdev) { return (VirtIOBalloon *)vdev; @@ -84,6 +92,11 @@ static void virtio_balloon_handle_output(VirtIODevice *vdev, VirtQueue *vq) pa = (ram_addr_t)ldl_p(&pfn) << VIRTIO_BALLOON_PFN_SHIFT; offset += 4; +if (s->guest_bug_state != GUEST_BUG_GOOD) { +/* Still bug testing, not ready to use balloon yet */ +continue; +} + /* FIXME: remove get_system_memory(), but how? */ section = memory_region_find(get_system_memory(),
[Qemu-devel] [PATCH v5 0/3] refactor PC machine, i440fx and piix3 to take advantage of QOM
This series aggressively refactors the PC machine initialization to be more modelled and less ad-hoc. The highlights of this series are: 1) Things like -m and -bios-name are now device model properties 2) The i440fx and piix3 are now modelled in a thorough fashion 3) i440fx_init is trivialized to creating devices and setting properties 4) convert PCI host bridge to QOM The point (3) is the most important one. As we refactor in this fashion, we should quickly get to the point where machine->init disappears completely in favor of just creating a handful of devices. The two stage initialization of QOM is important here. instance_init() is when composed devices are created which means that after you've created a device, all of its children are visible in the device model. This lets you set properties of the parent and its children. realize() (which is still called DeviceState::init today) will be called right before the guest starts up for the first time. Changes in v5: * fix bisect issues * take advantage of Andreas's pci_host patchset * drop convert MemoryRegion to QOM * drop prepare to create HPET, RTC and i8254 through composition Changes in v4: *rebase patchset Changes in v3: * fix coding style issues * fix rebase error * add changes log Changes in v2: * Rebase patch series of i440fx in Anthony's qom-rebase.12 branch to upstream * convert MemoryRegion to QOM * convert pci_host to QOM Anthony Liguori (3): eliminate piix_pci.c and module i440fx and piix3 merge pc_piix.c to pc.c convert pci-host to QOM hw/i386/Makefile.objs |3 +- hw/i440fx.c | 434 hw/i440fx.h | 76 + hw/pc.c | 753 ++--- hw/pc.h | 41 +--- hw/pc_piix.c | 716 -- hw/pci_host.c |9 + hw/piix3.c| 258 + hw/piix3.h| 73 + hw/piix_pci.c | 622 10 files changed, 1558 insertions(+), 1427 deletions(-) create mode 100644 hw/i440fx.c create mode 100644 hw/i440fx.h delete mode 100644 hw/pc_piix.c create mode 100644 hw/piix3.c create mode 100644 hw/piix3.h delete mode 100644 hw/piix_pci.c -- 1.7.7.6
[Qemu-devel] [PATCH v5 3/3] convert pci-host to QOM
Take advantage of Andreas's pci-host patchset, add instance_init function to fully implement convert pci-host to QOM. Signed-off-by: Anthony Liguori Signed-off-by: Wanpeng Li --- hw/pci_host.c |9 + 1 files changed, 9 insertions(+), 0 deletions(-) diff --git a/hw/pci_host.c b/hw/pci_host.c index 68e328c..ce6b28f 100644 --- a/hw/pci_host.c +++ b/hw/pci_host.c @@ -165,11 +165,20 @@ const MemoryRegionOps pci_host_data_be_ops = { .endianness = DEVICE_BIG_ENDIAN, }; +static void pci_host_initfn(Object *obj) +{ +PCIHostState *s = PCI_HOST_BRIDGE(obj); + +object_property_add_link(obj, "mmio", "memory-region", +(Object **)&s->address_space, NULL); +} + static const TypeInfo pci_host_type_info = { .name = TYPE_PCI_HOST_BRIDGE, .parent = TYPE_SYS_BUS_DEVICE, .abstract = true, .instance_size = sizeof(PCIHostState), +.instance_init = pci_host_initfn, }; static void pci_host_register_types(void) -- 1.7.7.6
[Qemu-devel] [PATCH 01/10] convert RTC as piix3 proper QOM child
convert RTC as piix3 proper QOM child. RTC creation for the PIIX3 is done by calling object_init() with qdev_init() being called for each child device in the PIIX3 ::init function. Signed-off-by: Anthony Liguori Signed-off-by: Wanpeng Li --- hw/mc146818rtc.c | 29 + hw/mc146818rtc.h | 30 ++ hw/pc.c | 13 +++-- hw/piix3.c | 14 ++ hw/piix3.h |5 + 5 files changed, 57 insertions(+), 34 deletions(-) diff --git a/hw/mc146818rtc.c b/hw/mc146818rtc.c index 98839f2..f385f4c 100644 --- a/hw/mc146818rtc.c +++ b/hw/mc146818rtc.c @@ -56,33 +56,6 @@ #define RTC_CLOCK_RATE32768 #define UIP_HOLD_LENGTH (8 * NSEC_PER_SEC / 32768) -typedef struct RTCState { -ISADevice dev; -MemoryRegion io; -uint8_t cmos_data[128]; -uint8_t cmos_index; -int32_t base_year; -uint64_t base_rtc; -uint64_t last_update; -int64_t offset; -qemu_irq irq; -qemu_irq sqw_irq; -int it_shift; -/* periodic timer */ -QEMUTimer *periodic_timer; -int64_t next_periodic_time; -/* update-ended timer */ -QEMUTimer *update_timer; -uint64_t next_alarm_time; -uint16_t irq_reinject_on_ack_count; -uint32_t irq_coalesced; -uint32_t period; -QEMUTimer *coalesced_timer; -Notifier clock_reset_notifier; -LostTickPolicy lost_tick_policy; -Notifier suspend_notifier; -} RTCState; - static void rtc_set_time(RTCState *s); static void rtc_update_time(RTCState *s); static void rtc_set_cmos(RTCState *s, const struct tm *tm); @@ -894,7 +867,7 @@ static void rtc_class_initfn(ObjectClass *klass, void *data) } static TypeInfo mc146818rtc_info = { -.name = "mc146818rtc", +.name = TYPE_RTC, .parent= TYPE_ISA_DEVICE, .instance_size = sizeof(RTCState), .class_init= rtc_class_initfn, diff --git a/hw/mc146818rtc.h b/hw/mc146818rtc.h index f286b6a..a8f1428 100644 --- a/hw/mc146818rtc.h +++ b/hw/mc146818rtc.h @@ -3,6 +3,36 @@ #include "isa.h" #include "mc146818rtc_regs.h" +#include "notify.h" + +#define TYPE_RTC "mc146818rtc" + +typedef struct RTCState { +ISADevice dev; +MemoryRegion io; +uint8_t cmos_data[128]; +uint8_t cmos_index; +int32_t base_year; +uint64_t base_rtc; +uint64_t last_update; +int64_t offset; +qemu_irq irq; +qemu_irq sqw_irq; +int it_shift; +/* periodic timer */ +QEMUTimer *periodic_timer; +int64_t next_periodic_time; +/* update-ended timer */ +QEMUTimer *update_timer; +uint64_t next_alarm_time; +uint16_t irq_reinject_on_ack_count; +uint32_t irq_coalesced; +uint32_t period; +QEMUTimer *coalesced_timer; +Notifier clock_reset_notifier; +LostTickPolicy lost_tick_policy; +Notifier suspend_notifier; +} RTCState; ISADevice *rtc_init(ISABus *bus, int base_year, qemu_irq intercept_irq); void rtc_set_memory(ISADevice *dev, int addr, int val); diff --git a/hw/pc.c b/hw/pc.c index c40e112..7fed363 100644 --- a/hw/pc.c +++ b/hw/pc.c @@ -90,6 +90,8 @@ struct e820_table { struct e820_entry entry[E820_NR_ENTRIES]; } QEMU_PACKED __attribute((__aligned__(4))); +qemu_irq rtc_irq; + static const int ide_iobase[MAX_IDE_BUS] = { 0x1f0, 0x170 }; static const int ide_iobase2[MAX_IDE_BUS] = { 0x3f6, 0x376 }; static const int ide_irq[MAX_IDE_BUS] = { 14, 15 }; @@ -941,7 +943,6 @@ static void cpu_request_exit(void *opaque, int irq, int level) } static void pc_basic_device_init(ISABus *isa_bus, qemu_irq *gsi, - ISADevice **rtc_state, ISADevice **floppy, bool no_vmport) { @@ -950,7 +951,6 @@ static void pc_basic_device_init(ISABus *isa_bus, qemu_irq *gsi, DeviceState *hpet = NULL; int pit_isa_irq = 0; qemu_irq pit_alt_irq = NULL; -qemu_irq rtc_irq = NULL; qemu_irq *a20_line; ISADevice *i8042, *port92, *vmmouse, *pit = NULL; qemu_irq *cpu_exit_irq; @@ -977,9 +977,6 @@ static void pc_basic_device_init(ISABus *isa_bus, qemu_irq *gsi, rtc_irq = qdev_get_gpio_in(hpet, HPET_LEGACY_RTC_INT); } } -*rtc_state = rtc_init(isa_bus, 2000, rtc_irq); - -qemu_register_boot_set(pc_boot_set, *rtc_state); if (!xen_enabled()) { if (kvm_irqchip_in_kernel()) { @@ -1237,7 +1234,7 @@ static void pc_init1(MemoryRegion *system_memory, } /* init basic PC hardware */ -pc_basic_device_init(isa_bus, gsi, &rtc_state, &floppy, xen_enabled()); +pc_basic_device_init(isa_bus, gsi, &floppy, xen_enabled()); for (i = 0; i < nb_nics; i++) { NICInfo *nd = &nd_table[i]; @@ -1269,6 +1266,10 @@ static void pc_init1(MemoryRegion *system_memory, } } +/* FIXME */ +rtc_state = ISA_DEVICE(object_resolve_path("rtc", NULL)); +qemu_register_boot_set(pc_boot_set, rtc_state); + audio_init(isa_bus, pci_ena
[Qemu-devel] [PATCH 04/10] convert PCSPK as piix3 proper QOM child
convert PCSPK as piix3 proper QOM child. PCSPK creation for the PIIX3 is done by calling object_init() with qdev_init() being called for each child device in the PIIX3 ::init function. Signed-off-by: Wanpeng Li --- hw/pcspk.c | 19 +-- hw/pcspk.h | 19 +++ hw/piix3.c |8 hw/piix3.h |2 ++ 4 files changed, 30 insertions(+), 18 deletions(-) diff --git a/hw/pcspk.c b/hw/pcspk.c index ad6491b..fc8bc99 100644 --- a/hw/pcspk.c +++ b/hw/pcspk.c @@ -25,31 +25,14 @@ #include "hw.h" #include "pc.h" #include "isa.h" -#include "audio/audio.h" #include "qemu-timer.h" #include "i8254.h" #include "pcspk.h" -#define PCSPK_BUF_LEN 1792 #define PCSPK_SAMPLE_RATE 32000 #define PCSPK_MAX_FREQ (PCSPK_SAMPLE_RATE >> 1) #define PCSPK_MIN_COUNT ((PIT_FREQ + PCSPK_MAX_FREQ - 1) / PCSPK_MAX_FREQ) -typedef struct { -ISADevice dev; -MemoryRegion ioport; -uint32_t iobase; -uint8_t sample_buf[PCSPK_BUF_LEN]; -QEMUSoundCard card; -SWVoiceOut *voice; -void *pit; -unsigned int pit_count; -unsigned int samples; -unsigned int play_pos; -int data_on; -int dummy_refresh_clock; -} PCSpkState; - static const char *s_spk = "pcspk"; static PCSpkState *pcspk_state; @@ -188,7 +171,7 @@ static void pcspk_class_initfn(ObjectClass *klass, void *data) } static TypeInfo pcspk_info = { -.name = "isa-pcspk", +.name = TYPE_PCSPK, .parent = TYPE_ISA_DEVICE, .instance_size = sizeof(PCSpkState), .class_init = pcspk_class_initfn, diff --git a/hw/pcspk.h b/hw/pcspk.h index 7f42bac..07b3a8f 100644 --- a/hw/pcspk.h +++ b/hw/pcspk.h @@ -27,6 +27,25 @@ #include "hw.h" #include "isa.h" +#include "audio/audio.h" + +#define PCSPK_BUF_LEN 1792 +#define TYPE_PCSPK "isa-pcspk" + +typedef struct { +ISADevice dev; +MemoryRegion ioport; +uint32_t iobase; +uint8_t sample_buf[PCSPK_BUF_LEN]; +QEMUSoundCard card; +SWVoiceOut *voice; +void *pit; +unsigned int pit_count; +unsigned int samples; +unsigned int play_pos; +int data_on; +int dummy_refresh_clock; +} PCSpkState; static inline ISADevice *pcspk_init(ISABus *bus, ISADevice *pit) { diff --git a/hw/piix3.c b/hw/piix3.c index 41739bd..35a0de9 100644 --- a/hw/piix3.c +++ b/hw/piix3.c @@ -250,6 +250,11 @@ static int piix3_realize(PCIDevice *dev) qdev_get_gpio_in(DEVICE(&s->pit), 0)); } } +/* Realize the PCSPK */ +qdev_set_parent_bus(DEVICE(&s->pcspk), BUS(s->bus)); +qdev_prop_set_uint32(DEVICE(&s->pcspk), "iobase", 0x61); +qdev_prop_set_ptr(DEVICE(&s->pcspk), "pit", ISA_DEVICE(&s->pit)); +qdev_init_nofail(DEVICE(&s->pcspk)); return 0; } @@ -280,6 +285,9 @@ static void piix3_initfn(Object *obj) qdev_prop_set_int32(DEVICE(&s->pit), "iobase", 0x40); } } + +object_initialize(&s->pcspk, TYPE_PCSPK); +object_property_add_child(obj, "pcspk", OBJECT(&s->pcspk), NULL); } static void piix3_class_init(ObjectClass *klass, void *data) diff --git a/hw/piix3.h b/hw/piix3.h index 58486b9..32f7a95 100644 --- a/hw/piix3.h +++ b/hw/piix3.h @@ -34,6 +34,7 @@ #include "hpet_emul.h" #include "i8254.h" #include "i8254_internal.h" +#include "pcspk.h" #define PIIX_NUM_PIC_IRQS 16 /* i8259 * 2 */ #define PIIX_NUM_PIRQS 4ULL/* PIRQ[A-D] */ @@ -77,6 +78,7 @@ typedef struct PIIX3State { KVMPITState kvm_pit; } pit; #endif +PCSpkState pcspk; qemu_irq *pic; -- 1.7.7.6
[Qemu-devel] [PATCH 06/10] convert i8042 as piix3 proper QOM child
convert i8042 as piix3 proper QOM child. I8042 creation for the PIIX3 is done by calling object_init() with qdev_init() being called for each child device in the PIIX3 ::init function. Signed-off-by: Wanpeng Li --- hw/pc.c|9 ++--- hw/pckbd.c | 24 +--- hw/piix3.c | 13 +++-- hw/piix3.h | 24 hw/ps2.h |3 +++ 5 files changed, 41 insertions(+), 32 deletions(-) diff --git a/hw/pc.c b/hw/pc.c index 94fdea9..a14bf5a 100644 --- a/hw/pc.c +++ b/hw/pc.c @@ -931,8 +931,7 @@ static void pc_basic_device_init(ISABus *isa_bus, qemu_irq *gsi, { int i; DriveInfo *fd[MAX_FD]; -qemu_irq *a20_line; -ISADevice *i8042, *vmmouse; +ISADevice *vmmouse; qemu_irq *cpu_exit_irq; register_ioport_write(0x80, 1, 1, ioport80_write, NULL); @@ -951,9 +950,6 @@ static void pc_basic_device_init(ISABus *isa_bus, qemu_irq *gsi, } } -a20_line = qemu_allocate_irqs(handle_a20_line_change, first_cpu, 1); -i8042 = isa_create_simple(isa_bus, "i8042"); -i8042_setup_a20_line(i8042, &a20_line[0]); if (!no_vmport) { vmport_init(isa_bus); vmmouse = isa_try_create(isa_bus, "vmmouse"); @@ -961,7 +957,6 @@ static void pc_basic_device_init(ISABus *isa_bus, qemu_irq *gsi, vmmouse = NULL; } if (vmmouse) { -qdev_prop_set_ptr(&vmmouse->qdev, "ps2_mouse", i8042); qdev_init_nofail(&vmmouse->qdev); } @@ -1153,8 +1148,8 @@ static void pc_init1(MemoryRegion *system_memory, i440fx_state = NULL; isa_bus = isa_bus_new(NULL, system_io); no_hpet = 1; +isa_bus_irqs(isa_bus, gsi); } -isa_bus_irqs(isa_bus, gsi); if (kvm_irqchip_in_kernel()) { i8259 = kvm_i8259_init(isa_bus); diff --git a/hw/pckbd.c b/hw/pckbd.c index 5bb3e0a..d76bcbb 100644 --- a/hw/pckbd.c +++ b/hw/pckbd.c @@ -126,22 +126,6 @@ #define KBD_PENDING_KBD 1 #define KBD_PENDING_AUX 2 -typedef struct KBDState { -uint8_t write_cmd; /* if non zero, write data to port 60 is expected */ -uint8_t status; -uint8_t mode; -uint8_t outport; -/* Bitmask of devices with data available. */ -uint8_t pending; -void *kbd; -void *mouse; - -qemu_irq irq_kbd; -qemu_irq irq_mouse; -qemu_irq *a20_out; -hwaddr mask; -} KBDState; - /* update irq and KBD_STAT_[MOUSE_]OBF */ /* XXX: not generating the irqs if KBD_MODE_DISABLE_KBD is set may be incorrect, but it avoids having to simulate exact delays */ @@ -431,12 +415,6 @@ void i8042_mm_init(qemu_irq kbd_irq, qemu_irq mouse_irq, qemu_register_reset(kbd_reset, s); } -typedef struct ISAKBDState { -ISADevice dev; -KBDState kbd; -MemoryRegion io[2]; -} ISAKBDState; - void i8042_isa_mouse_fake_event(void *opaque) { ISADevice *dev = opaque; @@ -513,7 +491,7 @@ static void i8042_class_initfn(ObjectClass *klass, void *data) } static TypeInfo i8042_info = { -.name = "i8042", +.name = TYPE_I8042, .parent= TYPE_ISA_DEVICE, .instance_size = sizeof(ISAKBDState), .class_init= i8042_class_initfn, diff --git a/hw/piix3.c b/hw/piix3.c index 675212e..c6bf3cb 100644 --- a/hw/piix3.c +++ b/hw/piix3.c @@ -202,6 +202,8 @@ static int piix3_realize(PCIDevice *dev) s->bus = isa_bus_new(DEVICE(dev), pci_address_space_io(dev)); isa_bus_irqs(s->bus, s->pic); +a20_line = qemu_allocate_irqs(handle_a20_line_change, first_cpu, 2); + /* Realize the RTC */ qdev_set_parent_bus(DEVICE(&s->rtc), BUS(s->bus)); qdev_init_nofail(DEVICE(&s->rtc)); @@ -260,8 +262,12 @@ static int piix3_realize(PCIDevice *dev) /* Realize the PORT92 */ qdev_set_parent_bus(DEVICE(&s->port92), BUS(s->bus)); qdev_init_nofail(DEVICE(&s->port92)); -a20_line = qemu_allocate_irqs(handle_a20_line_change, first_cpu, 1); -s->port92.a20_out = &a20_line[0]; +s->port92.a20_out = &a20_line[1]; + +/* Realize the I8042 */ +qdev_set_parent_bus(DEVICE(&s->i8042), BUS(s->bus)); +i8042_setup_a20_line(ISA_DEVICE(&s->i8042), &a20_line[0]); +qdev_init_nofail(DEVICE(&s->i8042)); return 0; } @@ -298,6 +304,9 @@ static void piix3_initfn(Object *obj) object_initialize(&s->port92, TYPE_PORT92); object_property_add_child(obj, "port92", OBJECT(&s->port92), NULL); + +object_initialize(&s->i8042, TYPE_I8042); +object_property_add_child(obj, "i8042", OBJECT(&s->i8042), NULL); } static void piix3_class_init(ObjectClass *klass, void *data) diff --git a/hw/piix3.h b/hw/piix3.h index 4e5ee20..94a0daf 100644 --- a/hw/piix3.h +++ b/hw/piix3.h @@ -35,6 +35,7 @@ #include "i8254.h" #include "i8254_internal.h" #include "pcspk.h" +#include "ps2.h" #define PIIX_NUM_PIC_IRQS 16 /* i8259 * 2 */ #define PIIX_NUM_PIRQS 4ULL/* PIRQ[A-D] */ @@ -61,6 +62,28 @@ typedef struct Port92State { qemu_irq *a20_out; } Port92State; +typ
[Qemu-devel] [PATCH 07/10] convert VMPORT as piix3 proper QOM child
convert VMPORT as piix3 proper QOM child. VMPORT creation for the PIIX3 is done by calling object_init() with qdev_init() being called for each child device in the PIIX3 ::init function. Signed-off-by: Wanpeng Li --- hw/pc.c |1 - hw/pc.h |5 - hw/piix3.c | 11 +++ hw/piix3.h | 11 +++ hw/vmport.c | 10 +- 5 files changed, 23 insertions(+), 15 deletions(-) diff --git a/hw/pc.c b/hw/pc.c index a14bf5a..99cd314 100644 --- a/hw/pc.c +++ b/hw/pc.c @@ -951,7 +951,6 @@ static void pc_basic_device_init(ISABus *isa_bus, qemu_irq *gsi, } if (!no_vmport) { -vmport_init(isa_bus); vmmouse = isa_try_create(isa_bus, "vmmouse"); } else { vmmouse = NULL; diff --git a/hw/pc.h b/hw/pc.h index 17d48a0..5b7bc26 100644 --- a/hw/pc.h +++ b/hw/pc.h @@ -54,11 +54,6 @@ typedef struct GSIState { qemu_irq ioapic_irq[IOAPIC_NUM_PINS]; } GSIState; -/* vmport.c */ -static inline void vmport_init(ISABus *bus) -{ -isa_create_simple(bus, "vmport"); -} void vmport_register(unsigned char command, IOPortReadFunc *func, void *opaque); void vmmouse_get_data(uint32_t *data); void vmmouse_set_data(const uint32_t *data); diff --git a/hw/piix3.c b/hw/piix3.c index c6bf3cb..27c8f50 100644 --- a/hw/piix3.c +++ b/hw/piix3.c @@ -269,6 +269,12 @@ static int piix3_realize(PCIDevice *dev) i8042_setup_a20_line(ISA_DEVICE(&s->i8042), &a20_line[0]); qdev_init_nofail(DEVICE(&s->i8042)); +/* Realize the VMPORT */ +if (!xen_enabled()) { +qdev_set_parent_bus(DEVICE(&s->vmport), BUS(s->bus)); +qdev_init_nofail(DEVICE(&s->vmport)); +} + return 0; } @@ -307,6 +313,11 @@ static void piix3_initfn(Object *obj) object_initialize(&s->i8042, TYPE_I8042); object_property_add_child(obj, "i8042", OBJECT(&s->i8042), NULL); + +if (!xen_enabled()) { +object_initialize(&s->vmport, TYPE_VMPORT); +object_property_add_child(obj, "vmport", OBJECT(&s->vmport), NULL); +} } static void piix3_class_init(ObjectClass *klass, void *data) diff --git a/hw/piix3.h b/hw/piix3.h index 94a0daf..477e39e 100644 --- a/hw/piix3.h +++ b/hw/piix3.h @@ -54,6 +54,16 @@ typedef struct KVMPITState { #define TYPE_PORT92 "port92" +#define TYPE_VMPORT "vmport" +#define VMPORT_ENTRIES 0x2c + +typedef struct _VMPortState { +ISADevice dev; +MemoryRegion io; +IOPortReadFunc *func[VMPORT_ENTRIES]; +void *opaque[VMPORT_ENTRIES]; +} VMPortState; + /* port 92 stuff: could be split off */ typedef struct Port92State { ISADevice dev; @@ -110,6 +120,7 @@ typedef struct PIIX3State { PITCommonState pit; KVMPITState kvm_pit; } pit; +VMPortState vmport; #endif PCSpkState pcspk; Port92State port92; diff --git a/hw/vmport.c b/hw/vmport.c index 3ab3a14..45daef6 100644 --- a/hw/vmport.c +++ b/hw/vmport.c @@ -35,14 +35,6 @@ #define VMPORT_ENTRIES 0x2c #define VMPORT_MAGIC 0x564D5868 -typedef struct _VMPortState -{ -ISADevice dev; -MemoryRegion io; -IOPortReadFunc *func[VMPORT_ENTRIES]; -void *opaque[VMPORT_ENTRIES]; -} VMPortState; - static VMPortState *port_state; void vmport_register(unsigned char command, IOPortReadFunc *func, void *opaque) @@ -156,7 +148,7 @@ static void vmport_class_initfn(ObjectClass *klass, void *data) } static TypeInfo vmport_info = { -.name = "vmport", +.name = TYPE_VMPORT, .parent= TYPE_ISA_DEVICE, .instance_size = sizeof(VMPortState), .class_init= vmport_class_initfn, -- 1.7.7.6
[Qemu-devel] [PATCH 08/10] convert VMMOUSE as piix3 proper QOM child
convert VMMOUSE as piix3 proper QOM child. VMMOUSE creation for the PIIX3 is done by calling object_init() with qdev_init() being called for each child device in the PIIX3 ::init function. Signed-off-by: Wanpeng Li --- hw/pc.c | 15 ++- hw/piix3.c | 10 ++ hw/piix3.h | 16 hw/vmmouse.c | 14 -- 4 files changed, 28 insertions(+), 27 deletions(-) diff --git a/hw/pc.c b/hw/pc.c index 99cd314..9798c24 100644 --- a/hw/pc.c +++ b/hw/pc.c @@ -926,12 +926,10 @@ static void cpu_request_exit(void *opaque, int irq, int level) } static void pc_basic_device_init(ISABus *isa_bus, qemu_irq *gsi, - ISADevice **floppy, - bool no_vmport) + ISADevice **floppy) { int i; DriveInfo *fd[MAX_FD]; -ISADevice *vmmouse; qemu_irq *cpu_exit_irq; register_ioport_write(0x80, 1, 1, ioport80_write, NULL); @@ -950,15 +948,6 @@ static void pc_basic_device_init(ISABus *isa_bus, qemu_irq *gsi, } } -if (!no_vmport) { -vmmouse = isa_try_create(isa_bus, "vmmouse"); -} else { -vmmouse = NULL; -} -if (vmmouse) { -qdev_init_nofail(&vmmouse->qdev); -} - cpu_exit_irq = qemu_allocate_irqs(cpu_request_exit, NULL, 1); DMA_init(0, cpu_exit_irq); @@ -1174,7 +1163,7 @@ static void pc_init1(MemoryRegion *system_memory, } /* init basic PC hardware */ -pc_basic_device_init(isa_bus, gsi, &floppy, xen_enabled()); +pc_basic_device_init(isa_bus, gsi, &floppy); for (i = 0; i < nb_nics; i++) { NICInfo *nd = &nd_table[i]; diff --git a/hw/piix3.c b/hw/piix3.c index 27c8f50..2922fd4 100644 --- a/hw/piix3.c +++ b/hw/piix3.c @@ -271,8 +271,15 @@ static int piix3_realize(PCIDevice *dev) /* Realize the VMPORT */ if (!xen_enabled()) { +/* Realize the VMPORT */ qdev_set_parent_bus(DEVICE(&s->vmport), BUS(s->bus)); qdev_init_nofail(DEVICE(&s->vmport)); + +/* Realize the VMMOUSE */ +qdev_set_parent_bus(DEVICE(&s->vmmouse), BUS(s->bus)); +qdev_prop_set_ptr(DEVICE(&s->vmmouse), + "ps2_mouse", ISA_DEVICE(&s->i8042)); +qdev_init_nofail(DEVICE(&s->vmmouse)); } return 0; @@ -318,6 +325,9 @@ static void piix3_initfn(Object *obj) object_initialize(&s->vmport, TYPE_VMPORT); object_property_add_child(obj, "vmport", OBJECT(&s->vmport), NULL); } + +object_initialize(&s->vmmouse, TYPE_VMMOUSE); +object_property_add_child(obj, "vmmouse", OBJECT(&s->vmmouse), NULL); } static void piix3_class_init(ObjectClass *klass, void *data) diff --git a/hw/piix3.h b/hw/piix3.h index 477e39e..29ae820 100644 --- a/hw/piix3.h +++ b/hw/piix3.h @@ -36,6 +36,7 @@ #include "i8254_internal.h" #include "pcspk.h" #include "ps2.h" +#include "console.h" #define PIIX_NUM_PIC_IRQS 16 /* i8259 * 2 */ #define PIIX_NUM_PIRQS 4ULL/* PIRQ[A-D] */ @@ -57,6 +58,20 @@ typedef struct KVMPITState { #define TYPE_VMPORT "vmport" #define VMPORT_ENTRIES 0x2c +#define TYPE_VMMOUSE "vmmouse" +#define VMMOUSE_QUEUE_SIZE 1024 + +typedef struct _VMMouseState { +ISADevice dev; +uint32_t queue[VMMOUSE_QUEUE_SIZE]; +int32_t queue_size; +uint16_t nb_queue; +uint16_t status; +uint8_t absolute; +QEMUPutMouseEntry *entry; +void *ps2_mouse; +} VMMouseState; + typedef struct _VMPortState { ISADevice dev; MemoryRegion io; @@ -121,6 +136,7 @@ typedef struct PIIX3State { KVMPITState kvm_pit; } pit; VMPortState vmport; +VMMouseState vmmouse; #endif PCSpkState pcspk; Port92State port92; diff --git a/hw/vmmouse.c b/hw/vmmouse.c index 6338efa..022e493 100644 --- a/hw/vmmouse.c +++ b/hw/vmmouse.c @@ -41,8 +41,6 @@ #define VMMOUSE_REQUEST_RELATIVE 0x4c455252 #define VMMOUSE_REQUEST_ABSOLUTE 0x53424152 -#define VMMOUSE_QUEUE_SIZE 1024 - #define VMMOUSE_VERSION0x3442554a #ifdef DEBUG_VMMOUSE @@ -51,18 +49,6 @@ #define DPRINTF(fmt, ...) do { } while (0) #endif -typedef struct _VMMouseState -{ -ISADevice dev; -uint32_t queue[VMMOUSE_QUEUE_SIZE]; -int32_t queue_size; -uint16_t nb_queue; -uint16_t status; -uint8_t absolute; -QEMUPutMouseEntry *entry; -void *ps2_mouse; -} VMMouseState; - static uint32_t vmmouse_get_status(VMMouseState *s) { DPRINTF("vmmouse_get_status()\n"); -- 1.7.7.6
[Qemu-devel] [PATCH 10/10] convert IOAPIC as piix3 proper QOM child
convert IOAPIC as piix3 proper QOM child. IOAPIC creation for the PIIX3 is done by calling object_init() with qdev_init() being called for each child device in the PIIX3 ::init function. Signed-off-by: Wanpeng Li --- hw/ioapic.c |2 +- hw/ioapic.h |2 -- hw/ioapic_internal.h |2 ++ hw/kvm/ioapic.c |9 + hw/pc.c | 30 ++ hw/pc.h |2 ++ hw/piix3.c | 38 ++ hw/piix3.h | 13 + 8 files changed, 59 insertions(+), 39 deletions(-) diff --git a/hw/ioapic.c b/hw/ioapic.c index 7273095..927a099 100644 --- a/hw/ioapic.c +++ b/hw/ioapic.c @@ -245,7 +245,7 @@ static void ioapic_class_init(ObjectClass *klass, void *data) } static TypeInfo ioapic_info = { -.name = "ioapic", +.name = TYPE_IOAPIC, .parent= TYPE_IOAPIC_COMMON, .instance_size = sizeof(IOAPICCommonState), .class_init= ioapic_class_init, diff --git a/hw/ioapic.h b/hw/ioapic.h index 86e63da..649dd0c 100644 --- a/hw/ioapic.h +++ b/hw/ioapic.h @@ -20,8 +20,6 @@ #ifndef HW_IOAPIC_H #define HW_IOAPIC_H -#define IOAPIC_NUM_PINS 24 - void ioapic_eoi_broadcast(int vector); #endif /* !HW_IOAPIC_H */ diff --git a/hw/ioapic_internal.h b/hw/ioapic_internal.h index e04c9f3..d3cb4c9 100644 --- a/hw/ioapic_internal.h +++ b/hw/ioapic_internal.h @@ -88,6 +88,8 @@ typedef struct IOAPICCommonClass { void (*post_load)(IOAPICCommonState *s); } IOAPICCommonClass; +#define IOAPIC_NUM_PINS 24 + struct IOAPICCommonState { SysBusDevice busdev; MemoryRegion io_memory; diff --git a/hw/kvm/ioapic.c b/hw/kvm/ioapic.c index 6c3b8fe..e88843e 100644 --- a/hw/kvm/ioapic.c +++ b/hw/kvm/ioapic.c @@ -15,13 +15,6 @@ #include "hw/apic_internal.h" #include "kvm.h" -typedef struct KVMIOAPICState KVMIOAPICState; - -struct KVMIOAPICState { -IOAPICCommonState ioapic; -uint32_t kvm_gsi_base; -}; - static void kvm_ioapic_get(IOAPICCommonState *s) { struct kvm_irqchip chip; @@ -111,7 +104,7 @@ static void kvm_ioapic_class_init(ObjectClass *klass, void *data) } static TypeInfo kvm_ioapic_info = { -.name = "kvm-ioapic", +.name = TYPE_KVM_IOAPIC, .parent = TYPE_IOAPIC_COMMON, .instance_size = sizeof(KVMIOAPICState), .class_init = kvm_ioapic_class_init, diff --git a/hw/pc.c b/hw/pc.c index 74cec55..31031fa 100644 --- a/hw/pc.c +++ b/hw/pc.c @@ -79,6 +79,8 @@ BusState *idebus[MAX_IDE_BUS]; +GSIState *gsi_state; + struct e820_entry { uint64_t address; uint64_t length; @@ -1011,30 +1013,6 @@ static void kvm_piix3_gsi_handler(void *opaque, int n, int level) } } -static void ioapic_init(GSIState *gsi_state) -{ -DeviceState *dev; -SysBusDevice *d; -unsigned int i; - -if (kvm_irqchip_in_kernel()) { -dev = qdev_create(NULL, "kvm-ioapic"); -} else { -dev = qdev_create(NULL, "ioapic"); -} - -/* FIXME: this should be under the piix3. */ -object_property_add_child(object_resolve_path("i440fx", NULL), - "ioapic", OBJECT(dev), NULL); -qdev_init_nofail(dev); -d = sysbus_from_qdev(dev); -sysbus_mmio_map(d, 0, 0xfec0); - -for (i = 0; i < IOAPIC_NUM_PINS; i++) { -gsi_state->ioapic_irq[i] = qdev_get_gpio_in(dev, i); -} -} - static PCIBus *i440fx_init(I440FXPMCState **pi440fx_state, int *piix3_devfn, ISABus **isa_bus, qemu_irq *pic, MemoryRegion *address_space_mem, @@ -1091,7 +1069,6 @@ static void pc_init1(MemoryRegion *system_memory, qemu_irq *gsi; qemu_irq *i8259; qemu_irq *smi_irq; -GSIState *gsi_state; ISADevice *rtc_state; ISADevice *floppy; @@ -1153,9 +1130,6 @@ static void pc_init1(MemoryRegion *system_memory, for (i = 0; i < ISA_NUM_IRQS; i++) { gsi_state->i8259_irq[i] = i8259[i]; } -if (pci_enabled) { -ioapic_init(gsi_state); -} pc_register_ferr_irq(gsi[13]); diff --git a/hw/pc.h b/hw/pc.h index 620349f..7f6ff93 100644 --- a/hw/pc.h +++ b/hw/pc.h @@ -54,6 +54,8 @@ typedef struct GSIState { qemu_irq ioapic_irq[IOAPIC_NUM_PINS]; } GSIState; +extern GSIState *gsi_state; + void vmport_register(unsigned char command, IOPortReadFunc *func, void *opaque); void vmmouse_get_data(uint32_t *data); void vmmouse_set_data(const uint32_t *data); diff --git a/hw/piix3.c b/hw/piix3.c index 7ca0f83..99b1ecc 100644 --- a/hw/piix3.c +++ b/hw/piix3.c @@ -203,6 +203,7 @@ static int piix3_realize(PCIDevice *dev) qemu_irq *a20_line; DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS]; int i; +SysBusDevice *d; /* Initialize ISA Bus */ s->bus = isa_bus_new(DEVICE(dev), pci_address_space_io(dev)); @@ -313,6 +314,31 @@ static int piix3_realize(PCIDevice *dev) } } +/* Realize the IOAPIC */ +if (pci_is_enabled) { +
[Qemu-devel] [PATCH v5 2/3] merge pc_piix.c to pc.c
A long time ago, there was a grand plan to merge q35 chipset support. The start of that series was a refactoring of pc.c which split a bunch of the "common" functionality into a separate file that could be shared by the two. But q35 never got merged and the refactoring, in retrospect, just made things worse. Making things proper objects and using composition is the right way to share common devices. By pulling these files back together, we can start to fix some of this mess. Signed-off-by: Anthony Liguori Signed-off-by: Wanpeng Li --- hw/i386/Makefile.objs |1 - hw/pc.c | 714 ++- hw/pc.h | 23 +-- hw/pc_piix.c | 740 - 4 files changed, 706 insertions(+), 772 deletions(-) delete mode 100644 hw/pc_piix.c diff --git a/hw/i386/Makefile.objs b/hw/i386/Makefile.objs index 49b32d0..868020c 100644 --- a/hw/i386/Makefile.objs +++ b/hw/i386/Makefile.objs @@ -4,7 +4,6 @@ obj-y += sga.o ioapic_common.o ioapic.o i440fx.o piix3.o obj-y += vmport.o obj-y += pci-hotplug.o smbios.o wdt_ib700.o obj-y += debugcon.o multiboot.o -obj-y += pc_piix.o obj-y += pc_sysfw.o obj-$(CONFIG_XEN) += xen_platform.o xen_apic.o obj-$(CONFIG_XEN_PCI_PASSTHROUGH) += xen-host-pci-device.o diff --git a/hw/pc.c b/hw/pc.c index 60919e4..55bb797 100644 --- a/hw/pc.c +++ b/hw/pc.c @@ -28,6 +28,7 @@ #include "fdc.h" #include "ide.h" #include "pci.h" +#include "usb.h" #include "monitor.h" #include "fw_cfg.h" #include "hpet_emul.h" @@ -49,8 +50,11 @@ #include "ui/qemu-spice.h" #include "memory.h" #include "exec-memory.h" +#include "kvm/clock.h" #include "arch_init.h" #include "bitmap.h" +#include "smbus.h" +#include "boards.h" /* debug PC/ISA interrupts */ //#define DEBUG_IRQ @@ -73,6 +77,8 @@ #define E820_NR_ENTRIES16 +#define MAX_IDE_BUS 2 + struct e820_entry { uint64_t address; uint64_t length; @@ -84,10 +90,14 @@ struct e820_table { struct e820_entry entry[E820_NR_ENTRIES]; } QEMU_PACKED __attribute((__aligned__(4))); +static const int ide_iobase[MAX_IDE_BUS] = { 0x1f0, 0x170 }; +static const int ide_iobase2[MAX_IDE_BUS] = { 0x3f6, 0x376 }; +static const int ide_irq[MAX_IDE_BUS] = { 14, 15 }; + static struct e820_table e820_table; struct hpet_fw_config hpet_cfg = {.count = UINT8_MAX}; -void gsi_handler(void *opaque, int n, int level) +static void gsi_handler(void *opaque, int n, int level) { GSIState *s = opaque; @@ -105,7 +115,7 @@ static void ioport80_write(void *opaque, uint32_t addr, uint32_t data) /* MSDOS compatibility mode FPU exception support */ static qemu_irq ferr_irq; -void pc_register_ferr_irq(qemu_irq irq) +static void pc_register_ferr_irq(qemu_irq irq) { ferr_irq = irq; } @@ -320,7 +330,7 @@ static void pc_cmos_init_late(void *opaque) qemu_unregister_reset(pc_cmos_init_late, opaque); } -void pc_cmos_init(ram_addr_t ram_size, ram_addr_t above_4g_mem_size, +static void pc_cmos_init(ram_addr_t ram_size, ram_addr_t above_4g_mem_size, const char *boot_device, ISADevice *floppy, BusState *idebus0, BusState *idebus1, ISADevice *s) @@ -827,7 +837,7 @@ static const int ne2000_irq[NE2000_NB_MAX] = { 9, 10, 11, 3, 4, 5 }; static const int parallel_io[MAX_PARALLEL_PORTS] = { 0x378, 0x278, 0x3bc }; static const int parallel_irq[MAX_PARALLEL_PORTS] = { 7, 7, 7 }; -void pc_init_ne2k_isa(ISABus *bus, NICInfo *nd) +static void pc_init_ne2k_isa(ISABus *bus, NICInfo *nd) { static int nb_ne2k = 0; @@ -877,7 +887,7 @@ void pc_cpus_init(const char *cpu_model) } } -void *pc_memory_init(MemoryRegion *system_memory, +static void *pc_memory_init(MemoryRegion *system_memory, const char *kernel_filename, const char *kernel_cmdline, const char *initrd_filename, @@ -902,12 +912,12 @@ void *pc_memory_init(MemoryRegion *system_memory, return fw_cfg; } -qemu_irq *pc_allocate_cpu_irq(void) +static qemu_irq *pc_allocate_cpu_irq(void) { return qemu_allocate_irqs(pic_irq_request, NULL, 1); } -DeviceState *pc_vga_init(ISABus *isa_bus, PCIBus *pci_bus) +static DeviceState *pc_vga_init(ISABus *isa_bus, PCIBus *pci_bus) { DeviceState *dev = NULL; @@ -930,7 +940,7 @@ static void cpu_request_exit(void *opaque, int irq, int level) } } -void pc_basic_device_init(ISABus *isa_bus, qemu_irq *gsi, +static void pc_basic_device_init(ISABus *isa_bus, qemu_irq *gsi, ISADevice **rtc_state, ISADevice **floppy, bool no_vmport) @@ -1021,7 +1031,7 @@ void pc_basic_device_init(ISABus *isa_bus, qemu_irq *gsi, *floppy = fdctrl_init_isa(isa_bus, fd); } -void pc_pci_device_init(PCIBus *pci_bus) +static void pc_pci_device_init(PCIBus *pci_bus) { int max_bus; int bus; @@ -1031,3 +1041,689 @@
[Qemu-devel] [PATCH 02/10] convert HPET as piix3 proper QOM child
convert HPET as piix3 proper QOM child. HPET creation for the PIIX3 is done by calling object_init() with qdev_init() being called for each child device in the PIIX3 ::init function. Signed-off-by: Anthony Liguori Signed-off-by: Wanpeng Li --- hw/hpet.c | 35 --- hw/hpet_emul.h | 40 hw/pc.c| 21 - hw/piix3.c | 28 ++-- hw/piix3.h |4 ++-- 5 files changed, 68 insertions(+), 60 deletions(-) diff --git a/hw/hpet.c b/hw/hpet.c index 50ac067..b128505 100644 --- a/hw/hpet.c +++ b/hw/hpet.c @@ -42,41 +42,6 @@ #define HPET_MSI_SUPPORT0 -struct HPETState; -typedef struct HPETTimer { /* timers */ -uint8_t tn; /*timer number*/ -QEMUTimer *qemu_timer; -struct HPETState *state; -/* Memory-mapped, software visible timer registers */ -uint64_t config;/* configuration/cap */ -uint64_t cmp; /* comparator */ -uint64_t fsb; /* FSB route */ -/* Hidden register state */ -uint64_t period;/* Last value written to comparator */ -uint8_t wrap_flag; /* timer pop will indicate wrap for one-shot 32-bit - * mode. Next pop will be actual timer expiration. - */ -} HPETTimer; - -typedef struct HPETState { -SysBusDevice busdev; -MemoryRegion iomem; -uint64_t hpet_offset; -qemu_irq irqs[HPET_NUM_IRQ_ROUTES]; -uint32_t flags; -uint8_t rtc_irq_level; -qemu_irq pit_enabled; -uint8_t num_timers; -HPETTimer timer[HPET_MAX_TIMERS]; - -/* Memory-mapped, software visible registers */ -uint64_t capability;/* capabilities */ -uint64_t config;/* configuration */ -uint64_t isr; /* interrupt status reg */ -uint64_t hpet_counter; /* main counter */ -uint8_t hpet_id; /* instance id */ -} HPETState; - static uint32_t hpet_in_legacy_mode(HPETState *s) { return s->config & HPET_CFG_LEGACY; diff --git a/hw/hpet_emul.h b/hw/hpet_emul.h index 757f79f..46dee92 100644 --- a/hw/hpet_emul.h +++ b/hw/hpet_emul.h @@ -13,6 +13,8 @@ #ifndef QEMU_HPET_EMUL_H #define QEMU_HPET_EMUL_H +#include "sysbus.h" + #define HPET_BASE 0xfed0 #define HPET_CLK_PERIOD 1000ULL /* 1000 femtoseconds == 10ns*/ @@ -71,4 +73,42 @@ struct hpet_fw_config } QEMU_PACKED; extern struct hpet_fw_config hpet_cfg; + +#define TYPE_HPET "hpet" + +struct HPETState; +typedef struct HPETTimer { /* timers */ +uint8_t tn; /*timer number*/ +QEMUTimer *qemu_timer; +struct HPETState *state; +/* Memory-mapped, software visible timer registers */ +uint64_t config;/* configuration/cap */ +uint64_t cmp; /* comparator */ +uint64_t fsb; /* FSB route */ +/* Hidden register state */ +uint64_t period;/* Last value written to comparator */ +uint8_t wrap_flag; /* timer pop will indicate wrap for one-shot 32-bit + * mode. Next pop will be actual timer expiration. + */ +} HPETTimer; + +typedef struct HPETState { +SysBusDevice busdev; +MemoryRegion iomem; +uint64_t hpet_offset; +qemu_irq irqs[HPET_NUM_IRQ_ROUTES]; +uint32_t flags; +uint8_t rtc_irq_level; +qemu_irq pit_enabled; +uint8_t num_timers; +HPETTimer timer[HPET_MAX_TIMERS]; + +/* Memory-mapped, software visible registers */ +uint64_t capability;/* capabilities */ +uint64_t config;/* configuration */ +uint64_t isr; /* interrupt status reg */ +uint64_t hpet_counter; /* main counter */ +uint8_t hpet_id; /* instance id */ +} HPETState; + #endif diff --git a/hw/pc.c b/hw/pc.c index 7fed363..7105f4e 100644 --- a/hw/pc.c +++ b/hw/pc.c @@ -90,8 +90,6 @@ struct e820_table { struct e820_entry entry[E820_NR_ENTRIES]; } QEMU_PACKED __attribute((__aligned__(4))); -qemu_irq rtc_irq; - static const int ide_iobase[MAX_IDE_BUS] = { 0x1f0, 0x170 }; static const int ide_iobase2[MAX_IDE_BUS] = { 0x3f6, 0x376 }; static const int ide_irq[MAX_IDE_BUS] = { 14, 15 }; @@ -959,25 +957,6 @@ static void pc_basic_device_init(ISABus *isa_bus, qemu_irq *gsi, register_ioport_write(0xf0, 1, 1, ioportF0_write, NULL); -/* - * Check if an HPET shall be created. - * - * Without KVM_CAP_PIT_STATE2, we cannot switch off the in-kernel PIT - * when the HPET wants to take over. Thus we have to disable the latter. - */ -if (!no_hpet && (!kvm_irqchip_in_kernel() || kvm_has_pit_state2())) { -hpet = sysbus_try_create_simple("hpet", HPET_BASE, NULL); - -if (hpet) { -for (i = 0; i < GSI_NUM_PINS; i++) { -sysbus_connect_irq(sysbus_from_qdev(hpet), i, gsi[i]); -} -pit_
[Qemu-devel] [PATCH 05/10] convert PORT92 as piix3 proper QOM child
convert PORT92 as piix3 proper QOM child. PORT92 creation for the PIIX3 is done by calling object_init() with qdev_init() being called for each child device in the PIIX3 ::init function. Signed-off-by: Wanpeng Li --- hw/pc.c| 25 - hw/pc.h|3 +++ hw/piix3.c | 10 ++ hw/piix3.h | 11 +++ 4 files changed, 28 insertions(+), 21 deletions(-) diff --git a/hw/pc.c b/hw/pc.c index 80b437f..94fdea9 100644 --- a/hw/pc.c +++ b/hw/pc.c @@ -421,14 +421,6 @@ static void pc_cmos_init(ram_addr_t ram_size, ram_addr_t above_4g_mem_size, qemu_register_reset(pc_cmos_init_late, &arg); } -/* port 92 stuff: could be split off */ -typedef struct Port92State { -ISADevice dev; -MemoryRegion io; -uint8_t outport; -qemu_irq *a20_out; -} Port92State; - static void port92_write(void *opaque, hwaddr addr, uint64_t val, unsigned size) { @@ -453,13 +445,6 @@ static uint64_t port92_read(void *opaque, hwaddr addr, return ret; } -static void port92_init(ISADevice *dev, qemu_irq *a20_out) -{ -Port92State *s = DO_UPCAST(Port92State, dev, dev); - -s->a20_out = a20_out; -} - static const VMStateDescription vmstate_port92_isa = { .name = "port92", .version_id = 1, @@ -510,7 +495,7 @@ static void port92_class_initfn(ObjectClass *klass, void *data) } static TypeInfo port92_info = { -.name = "port92", +.name = TYPE_PORT92, .parent= TYPE_ISA_DEVICE, .instance_size = sizeof(Port92State), .class_init= port92_class_initfn, @@ -523,7 +508,7 @@ static void port92_register_types(void) type_init(port92_register_types) -static void handle_a20_line_change(void *opaque, int irq, int level) +void handle_a20_line_change(void *opaque, int irq, int level) { CPUX86State *cpu = opaque; @@ -947,7 +932,7 @@ static void pc_basic_device_init(ISABus *isa_bus, qemu_irq *gsi, int i; DriveInfo *fd[MAX_FD]; qemu_irq *a20_line; -ISADevice *i8042, *port92, *vmmouse; +ISADevice *i8042, *vmmouse; qemu_irq *cpu_exit_irq; register_ioport_write(0x80, 1, 1, ioport80_write, NULL); @@ -966,7 +951,7 @@ static void pc_basic_device_init(ISABus *isa_bus, qemu_irq *gsi, } } -a20_line = qemu_allocate_irqs(handle_a20_line_change, first_cpu, 2); +a20_line = qemu_allocate_irqs(handle_a20_line_change, first_cpu, 1); i8042 = isa_create_simple(isa_bus, "i8042"); i8042_setup_a20_line(i8042, &a20_line[0]); if (!no_vmport) { @@ -979,8 +964,6 @@ static void pc_basic_device_init(ISABus *isa_bus, qemu_irq *gsi, qdev_prop_set_ptr(&vmmouse->qdev, "ps2_mouse", i8042); qdev_init_nofail(&vmmouse->qdev); } -port92 = isa_create_simple(isa_bus, "port92"); -port92_init(port92, &a20_line[1]); cpu_exit_irq = qemu_allocate_irqs(cpu_request_exit, NULL, 1); DMA_init(0, cpu_exit_irq); diff --git a/hw/pc.h b/hw/pc.h index d4b149e..17d48a0 100644 --- a/hw/pc.h +++ b/hw/pc.h @@ -9,6 +9,7 @@ #include "net.h" #include "memory.h" #include "ioapic.h" +#include "piix3.h" #include "i440fx.h" /* PC-style peripherals (also used by other machines). */ @@ -144,4 +145,6 @@ void pc_system_firmware_init(MemoryRegion *rom_memory); int e820_add_entry(uint64_t, uint64_t, uint32_t); +void handle_a20_line_change(void *opaque, int irq, int level); + #endif diff --git a/hw/piix3.c b/hw/piix3.c index 35a0de9..675212e 100644 --- a/hw/piix3.c +++ b/hw/piix3.c @@ -196,6 +196,7 @@ static int piix3_realize(PCIDevice *dev) qemu_irq rtc_irq; int pit_isa_irq = 0; qemu_irq pit_alt_irq = NULL; +qemu_irq *a20_line; /* Initialize ISA Bus */ s->bus = isa_bus_new(DEVICE(dev), pci_address_space_io(dev)); @@ -256,6 +257,12 @@ static int piix3_realize(PCIDevice *dev) qdev_prop_set_ptr(DEVICE(&s->pcspk), "pit", ISA_DEVICE(&s->pit)); qdev_init_nofail(DEVICE(&s->pcspk)); +/* Realize the PORT92 */ +qdev_set_parent_bus(DEVICE(&s->port92), BUS(s->bus)); +qdev_init_nofail(DEVICE(&s->port92)); +a20_line = qemu_allocate_irqs(handle_a20_line_change, first_cpu, 1); +s->port92.a20_out = &a20_line[0]; + return 0; } @@ -288,6 +295,9 @@ static void piix3_initfn(Object *obj) object_initialize(&s->pcspk, TYPE_PCSPK); object_property_add_child(obj, "pcspk", OBJECT(&s->pcspk), NULL); + +object_initialize(&s->port92, TYPE_PORT92); +object_property_add_child(obj, "port92", OBJECT(&s->port92), NULL); } static void piix3_class_init(ObjectClass *klass, void *data) diff --git a/hw/piix3.h b/hw/piix3.h index 32f7a95..4e5ee20 100644 --- a/hw/piix3.h +++ b/hw/piix3.h @@ -51,6 +51,16 @@ typedef struct KVMPITState { int64_t kernel_clock_offset; } KVMPITState; +#define TYPE_PORT92 "port92" + +/* port 92 stuff: could be split off */ +typedef struct Port92State { +ISADevice dev; +MemoryRegion io; +uint8_t outport; +qemu_irq *a20_
[Qemu-devel] [PATCH 00/10] piix3: create all child devices as proper QOM children
All of the devices described in the PIIX3 as being implemented within the PIIX3 are created as child devices of the PIIX3 object in QEMU. PIIX3 has-a RTC, has-a I8042, has-a PCSPK, etc. All child device creation for the PIIX3 is done by calling object_init() with qdev_init() being called for each child device in the PIIX3 ::init function. Anthony Liguori (3): convert RTC as piix3 proper QOM child convert HPET as piix3 proper QOM child convert PIT as piix3 proper QOM child Wanpeng Li (7): convert PCSPK as piix3 proper QOM child convert PORT92 as piix3 proper QOM child convert I8042 as piixe proper QOM child convert VMPORT piix3 proper QOM child convert VMMOUSE as piix3 proper QOM child convert IDE as piix3 proper QOM child convert IOAPIC as piix3 proper QOM child hw/hpet.c| 35 - hw/hpet_emul.h | 40 ++ hw/i440fx.c |6 ++ hw/i8254.c |2 +- hw/i8254_internal.h |3 +- hw/ide.h |6 +- hw/ide/internal.h|9 ++ hw/ide/isa.c | 14 +--- hw/ide/piix.c| 24 +-- hw/ioapic.c |2 +- hw/ioapic.h |2 - hw/ioapic_internal.h |2 + hw/kvm/i8254.c |8 +-- hw/kvm/ioapic.c |9 +-- hw/mc146818rtc.c | 29 +--- hw/mc146818rtc.h | 30 +++ hw/pc.c | 144 --- hw/pc.h | 14 ++- hw/pckbd.c | 24 +-- hw/pcspk.c | 19 +- hw/pcspk.h | 19 + hw/piix3.c | 205 ++ hw/piix3.h | 104 + hw/ps2.h |3 + hw/vmmouse.c | 14 hw/vmport.c | 10 +-- sysemu.h |2 - 27 files changed, 459 insertions(+), 320 deletions(-) -- 1.7.7.6
[Qemu-devel] [PATCH 03/10] convert PIT as piix3 proper QOM child
convert PIT as piix3 proper QOM child. PIT creation for the PIIX3 is done by calling object_init() with qdev_init() being called for each child device in the PIIX3 ::init function. Signed-off-by: Anthony Liguori Signed-off-by: Wanpeng Li --- hw/i8254.c |2 +- hw/i8254_internal.h |3 ++- hw/kvm/i8254.c |8 +--- hw/pc.c | 18 +- hw/piix3.c | 34 ++ hw/piix3.h | 15 +++ 6 files changed, 54 insertions(+), 26 deletions(-) diff --git a/hw/i8254.c b/hw/i8254.c index bea5f92..8d3616d 100644 --- a/hw/i8254.c +++ b/hw/i8254.c @@ -348,7 +348,7 @@ static void pit_class_initfn(ObjectClass *klass, void *data) } static TypeInfo pit_info = { -.name = "isa-pit", +.name = TYPE_PIT, .parent= TYPE_PIT_COMMON, .instance_size = sizeof(PITCommonState), .class_init= pit_class_initfn, diff --git a/hw/i8254_internal.h b/hw/i8254_internal.h index 686f0c2..1aecad3 100644 --- a/hw/i8254_internal.h +++ b/hw/i8254_internal.h @@ -26,7 +26,6 @@ #define QEMU_I8254_INTERNAL_H #include "hw.h" -#include "pc.h" #include "isa.h" typedef struct PITChannelState { @@ -57,6 +56,8 @@ typedef struct PITCommonState { PITChannelState channels[3]; } PITCommonState; +#define TYPE_KVM_PIT "kvm-pit" +#define TYPE_PIT "isa-pit" #define TYPE_PIT_COMMON "pit-common" #define PIT_COMMON(obj) \ OBJECT_CHECK(PITCommonState, (obj), TYPE_PIT_COMMON) diff --git a/hw/kvm/i8254.c b/hw/kvm/i8254.c index 53d13e3..9f8fb7c 100644 --- a/hw/kvm/i8254.c +++ b/hw/kvm/i8254.c @@ -27,18 +27,12 @@ #include "hw/i8254.h" #include "hw/i8254_internal.h" #include "kvm.h" +#include "hw/piix3.h" #define KVM_PIT_REINJECT_BIT 0 #define CALIBRATION_ROUNDS 3 -typedef struct KVMPITState { -PITCommonState pit; -LostTickPolicy lost_tick_policy; -bool vm_stopped; -int64_t kernel_clock_offset; -} KVMPITState; - static int64_t abs64(int64_t v) { return v < 0 ? -v : v; diff --git a/hw/pc.c b/hw/pc.c index 7105f4e..80b437f 100644 --- a/hw/pc.c +++ b/hw/pc.c @@ -946,30 +946,14 @@ static void pc_basic_device_init(ISABus *isa_bus, qemu_irq *gsi, { int i; DriveInfo *fd[MAX_FD]; -DeviceState *hpet = NULL; -int pit_isa_irq = 0; -qemu_irq pit_alt_irq = NULL; qemu_irq *a20_line; -ISADevice *i8042, *port92, *vmmouse, *pit = NULL; +ISADevice *i8042, *port92, *vmmouse; qemu_irq *cpu_exit_irq; register_ioport_write(0x80, 1, 1, ioport80_write, NULL); register_ioport_write(0xf0, 1, 1, ioportF0_write, NULL); -if (!xen_enabled()) { -if (kvm_irqchip_in_kernel()) { -pit = kvm_pit_init(isa_bus, 0x40); -} else { -pit = pit_init(isa_bus, 0x40, pit_isa_irq, pit_alt_irq); -} -if (hpet) { -/* connect PIT to output control line of the HPET */ -qdev_connect_gpio_out(hpet, 0, qdev_get_gpio_in(&pit->qdev, 0)); -} -pcspk_init(isa_bus, pit); -} - for(i = 0; i < MAX_SERIAL_PORTS; i++) { if (serial_hds[i]) { serial_isa_init(isa_bus, i, serial_hds[i]); diff --git a/hw/piix3.c b/hw/piix3.c index 5fe41cd..41739bd 100644 --- a/hw/piix3.c +++ b/hw/piix3.c @@ -194,6 +194,8 @@ static int piix3_realize(PCIDevice *dev) { PIIX3State *s = PIIX3(dev); qemu_irq rtc_irq; +int pit_isa_irq = 0; +qemu_irq pit_alt_irq = NULL; /* Initialize ISA Bus */ s->bus = isa_bus_new(DEVICE(dev), pci_address_space_io(dev)); @@ -222,6 +224,8 @@ static int piix3_realize(PCIDevice *dev) sysbus_connect_irq(SYS_BUS_DEVICE(&s->hpet), i, s->pic[i]); } +pit_isa_irq = -1; +pit_alt_irq = qdev_get_gpio_in(DEVICE(&s->hpet), HPET_LEGACY_PIT_INT); rtc_irq = qdev_get_gpio_in(DEVICE(&s->hpet), HPET_LEGACY_RTC_INT); } else { isa_init_irq(ISA_DEVICE(&s->rtc), &rtc_irq, RTC_ISA_IRQ); @@ -230,6 +234,23 @@ static int piix3_realize(PCIDevice *dev) /* Setup the RTC IRQ */ s->rtc.irq = rtc_irq; +/* Realize the PIT */ +if (!xen_enabled()) { +if (kvm_irqchip_in_kernel()) { +qdev_set_parent_bus(DEVICE(&s->pit.kvm_pit), BUS(s->bus)); +qdev_init_nofail(DEVICE(&s->pit.kvm_pit)); +qdev_connect_gpio_out(DEVICE(&s->hpet), 0, +qdev_get_gpio_in(DEVICE(&s->pit.kvm_pit), 0)); +} else { +qdev_set_parent_bus(DEVICE(&s->pit), BUS(s->bus)); +qdev_init_nofail(DEVICE(&s->pit)); +qdev_connect_gpio_out(DEVICE(&s->pit), 0, pit_isa_irq >= 0 ? + isa_get_irq(ISA_DEVICE(&s->pit), pit_isa_irq) : pit_alt_irq); +qdev_connect_gpio_out(DEVICE(&s->hpet), 0, +qdev_get_gpio_in(DEVICE(&s->pit), 0)); +} +} + return 0; } @@ -246,6 +267,19 @@ static void piix3_initfn(Object *obj) object_initialize(
[Qemu-devel] [PATCH 09/10] convert IDE as piix3 proper QOM child
convert IDE as piix3 proper QOM child. IDE creation for the PIIX3 is done by calling object_init() with qdev_init() being called for each child device in the PIIX3 ::init function. Signed-off-by: Wanpeng Li --- hw/i440fx.c |6 ++ hw/ide.h |6 -- hw/ide/internal.h |9 + hw/ide/isa.c | 14 +- hw/ide/piix.c | 24 ++-- hw/pc.c | 28 +--- hw/pc.h |4 hw/piix3.c| 47 +++ hw/piix3.h|7 +++ sysemu.h |2 -- 10 files changed, 85 insertions(+), 62 deletions(-) diff --git a/hw/i440fx.c b/hw/i440fx.c index 5196201..e994722 100644 --- a/hw/i440fx.c +++ b/hw/i440fx.c @@ -193,6 +193,12 @@ static int i440fx_realize(SysBusDevice *dev) h->bus = pci_bus_new(DEVICE(s), NULL, &s->pci_address_space, s->address_space_io, 0); +if (pci_is_enabled) { +qdev_set_parent_bus(DEVICE(&s->piix3.ide.pci), BUS(h->bus)); +} else { +qdev_set_parent_bus(DEVICE(&s->piix3.ide.isa), BUS(h->bus)); +} + memory_region_init_io(&h->conf_mem, &pci_host_conf_le_ops, s, "pci-conf-idx", 4); sysbus_add_io(dev, 0xcf8, &h->conf_mem); diff --git a/hw/ide.h b/hw/ide.h index add742c..7060124 100644 --- a/hw/ide.h +++ b/hw/ide.h @@ -7,6 +7,10 @@ #define MAX_IDE_DEVS 2 +#define TYPE_PIIX3_IDE_XEN "piix3-ide-xen" +#define TYPE_PIIX3_IDE "piix3-ide" +#define TYPE_ISA_IDE "isa-ide" + /* ide-isa.c */ ISADevice *isa_ide_init(ISABus *bus, int iobase, int iobase2, int isairq, DriveInfo *hd0, DriveInfo *hd1); @@ -14,8 +18,6 @@ ISADevice *isa_ide_init(ISABus *bus, int iobase, int iobase2, int isairq, /* ide-pci.c */ void pci_cmd646_ide_init(PCIBus *bus, DriveInfo **hd_table, int secondary_ide_enabled); -PCIDevice *pci_piix3_xen_ide_init(PCIBus *bus, DriveInfo **hd_table, int devfn); -PCIDevice *pci_piix3_ide_init(PCIBus *bus, DriveInfo **hd_table, int devfn); PCIDevice *pci_piix4_ide_init(PCIBus *bus, DriveInfo **hd_table, int devfn); void vt82c686b_ide_init(PCIBus *bus, DriveInfo **hd_table, int devfn); diff --git a/hw/ide/internal.h b/hw/ide/internal.h index bf7d313..3114f8c 100644 --- a/hw/ide/internal.h +++ b/hw/ide/internal.h @@ -483,6 +483,15 @@ struct IDEDevice { uint64_t wwn; }; +typedef struct ISAIDEState { +ISADevice dev; +IDEBusbus; +uint32_t iobase; +uint32_t iobase2; +uint32_t isairq; +qemu_irq irq; +} ISAIDEState; + #define BM_STATUS_DMAING 0x01 #define BM_STATUS_ERROR 0x02 #define BM_STATUS_INT0x04 diff --git a/hw/ide/isa.c b/hw/ide/isa.c index 8ab2718..ca206ca 100644 --- a/hw/ide/isa.c +++ b/hw/ide/isa.c @@ -30,18 +30,6 @@ #include -/***/ -/* ISA IDE definitions */ - -typedef struct ISAIDEState { -ISADevice dev; -IDEBusbus; -uint32_t iobase; -uint32_t iobase2; -uint32_t isairq; -qemu_irq irq; -} ISAIDEState; - static void isa_ide_reset(DeviceState *d) { ISAIDEState *s = container_of(d, ISAIDEState, dev.qdev); @@ -112,7 +100,7 @@ static void isa_ide_class_initfn(ObjectClass *klass, void *data) } static TypeInfo isa_ide_info = { -.name = "isa-ide", +.name = TYPE_ISA_IDE, .parent= TYPE_ISA_DEVICE, .instance_size = sizeof(ISAIDEState), .class_init= isa_ide_class_initfn, diff --git a/hw/ide/piix.c b/hw/ide/piix.c index 9431bad..3e53302 100644 --- a/hw/ide/piix.c +++ b/hw/ide/piix.c @@ -192,15 +192,6 @@ static int pci_piix3_xen_ide_unplug(DeviceState *dev) return 0; } -PCIDevice *pci_piix3_xen_ide_init(PCIBus *bus, DriveInfo **hd_table, int devfn) -{ -PCIDevice *dev; - -dev = pci_create_simple(bus, devfn, "piix3-ide-xen"); -pci_ide_create_devs(dev, hd_table); -return dev; -} - static void pci_piix_ide_exitfn(PCIDevice *dev) { PCIIDEState *d = DO_UPCAST(PCIIDEState, dev, dev); @@ -216,17 +207,6 @@ static void pci_piix_ide_exitfn(PCIDevice *dev) } /* hd_table must contain 4 block drivers */ -/* NOTE: for the PIIX3, the IRQs and IOports are hardcoded */ -PCIDevice *pci_piix3_ide_init(PCIBus *bus, DriveInfo **hd_table, int devfn) -{ -PCIDevice *dev; - -dev = pci_create_simple(bus, devfn, "piix3-ide"); -pci_ide_create_devs(dev, hd_table); -return dev; -} - -/* hd_table must contain 4 block drivers */ /* NOTE: for the PIIX4, the IRQs and IOports are hardcoded */ PCIDevice *pci_piix4_ide_init(PCIBus *bus, DriveInfo **hd_table, int devfn) { @@ -252,7 +232,7 @@ static void piix3_ide_class_init(ObjectClass *klass, void *data) } static TypeInfo piix3_ide_info = { -.name = "piix3-ide", +.name = TYPE_PIIX3_IDE, .parent= TYPE_PCI_DEVICE, .instance_size = sizeof(PCIIDEState), .c