Compare commits
	
		
			183 Commits
		
	
	
		
			v1.6.0-rc1
			...
			baseline_f
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					23fe2b3f9e | ||
| 
						 | 
					a0dba644c1 | ||
| 
						 | 
					c165473269 | ||
| 
						 | 
					3bf4dfdd11 | ||
| 
						 | 
					1466cef32d | ||
| 
						 | 
					9eda7d373e | ||
| 
						 | 
					1ae2757c6c | ||
| 
						 | 
					1e09955619 | ||
| 
						 | 
					396f79f45e | ||
| 
						 | 
					89b439f313 | ||
| 
						 | 
					43a52ce657 | ||
| 
						 | 
					3b6fb9cab2 | ||
| 
						 | 
					5650f5f48b | ||
| 
						 | 
					9223836745 | ||
| 
						 | 
					ee87e32f83 | ||
| 
						 | 
					6b63ef4d0f | ||
| 
						 | 
					4b38e989b4 | ||
| 
						 | 
					04920fc0fa | ||
| 
						 | 
					0851c9f75c | ||
| 
						 | 
					c0b4cc1f9f | ||
| 
						 | 
					ecfe10c9a6 | ||
| 
						 | 
					9176e8fb8f | ||
| 
						 | 
					72420ce9f0 | ||
| 
						 | 
					237e4f92a8 | ||
| 
						 | 
					230058106a | ||
| 
						 | 
					66aae5e1ec | ||
| 
						 | 
					6033e840c7 | ||
| 
						 | 
					55d284af8e | ||
| 
						 | 
					2452731c88 | ||
| 
						 | 
					22d9e1a986 | ||
| 
						 | 
					b643e4b90b | ||
| 
						 | 
					e4a6540ded | ||
| 
						 | 
					fe9120a5d1 | ||
| 
						 | 
					bace999f8a | ||
| 
						 | 
					4f071cf9b5 | ||
| 
						 | 
					033ee5a5ac | ||
| 
						 | 
					437f0f10a4 | ||
| 
						 | 
					fcef61ec6b | ||
| 
						 | 
					2f69ba1736 | ||
| 
						 | 
					99d228d6e9 | ||
| 
						 | 
					9188dbf71a | ||
| 
						 | 
					ad666d91f4 | ||
| 
						 | 
					de3a658f5b | ||
| 
						 | 
					7c1840b686 | ||
| 
						 | 
					3f1beaca88 | ||
| 
						 | 
					f2e5dca46b | ||
| 
						 | 
					1b9ecdb164 | ||
| 
						 | 
					bb52b14be1 | ||
| 
						 | 
					ce689368bb | ||
| 
						 | 
					f0d3576599 | ||
| 
						 | 
					d6d94c6785 | ||
| 
						 | 
					5d289cc724 | ||
| 
						 | 
					bed2e759eb | ||
| 
						 | 
					94473d0c06 | ||
| 
						 | 
					70ecdc6e4e | ||
| 
						 | 
					372835fbc3 | ||
| 
						 | 
					bc02fb304c | ||
| 
						 | 
					0d1460226f | ||
| 
						 | 
					164a101f28 | ||
| 
						 | 
					35ecde2601 | ||
| 
						 | 
					24d1a6d9d5 | ||
| 
						 | 
					bf0da4df83 | ||
| 
						 | 
					88266f5aa7 | ||
| 
						 | 
					e1b5c52e04 | ||
| 
						 | 
					b83c4db895 | ||
| 
						 | 
					b114b68adf | ||
| 
						 | 
					a9ead83261 | ||
| 
						 | 
					ba96394e20 | ||
| 
						 | 
					321bc0b2b2 | ||
| 
						 | 
					92067bf4bf | ||
| 
						 | 
					99a0b03650 | ||
| 
						 | 
					8231c2dd22 | ||
| 
						 | 
					747b0cb4b5 | ||
| 
						 | 
					35143f0164 | ||
| 
						 | 
					f202039811 | ||
| 
						 | 
					1ee2daeb64 | ||
| 
						 | 
					cc413a3935 | ||
| 
						 | 
					8b7a5415f9 | ||
| 
						 | 
					3a3567d337 | ||
| 
						 | 
					02653c5ea7 | ||
| 
						 | 
					328465fd9f | ||
| 
						 | 
					9d054ea543 | ||
| 
						 | 
					9fb7aaaf4c | ||
| 
						 | 
					a5d3f640a0 | ||
| 
						 | 
					7f3e341a00 | ||
| 
						 | 
					56383703c0 | ||
| 
						 | 
					8f3067bd86 | ||
| 
						 | 
					7fc5b13fd7 | ||
| 
						 | 
					6470215b79 | ||
| 
						 | 
					8857188251 | ||
| 
						 | 
					6f1484edad | ||
| 
						 | 
					885e8f984e | ||
| 
						 | 
					6dd2a5c98a | ||
| 
						 | 
					a904410af5 | ||
| 
						 | 
					133bb095ac | ||
| 
						 | 
					0b516ef0df | ||
| 
						 | 
					cb77d1925a | ||
| 
						 | 
					8571fa57cd | ||
| 
						 | 
					7748c1bd50 | ||
| 
						 | 
					3ee1ee80d2 | ||
| 
						 | 
					6624fecd8e | ||
| 
						 | 
					3bba9c115b | ||
| 
						 | 
					4a9a8876a1 | ||
| 
						 | 
					283c8733b5 | ||
| 
						 | 
					2aa09da823 | ||
| 
						 | 
					f7b803b377 | ||
| 
						 | 
					3561ba1418 | ||
| 
						 | 
					6793dfd1b6 | ||
| 
						 | 
					4965b7f056 | ||
| 
						 | 
					9604f70fdf | ||
| 
						 | 
					6db5f5d68e | ||
| 
						 | 
					f6049f4483 | ||
| 
						 | 
					2e985fe000 | ||
| 
						 | 
					85711e6baf | ||
| 
						 | 
					56c4bfb3f0 | ||
| 
						 | 
					c5d7f60f06 | ||
| 
						 | 
					5ee163e8ea | ||
| 
						 | 
					2cac260768 | ||
| 
						 | 
					dad5b9ea08 | ||
| 
						 | 
					9b9734ef82 | ||
| 
						 | 
					6fdf98f281 | ||
| 
						 | 
					e9a72359a5 | ||
| 
						 | 
					f71d4c4673 | ||
| 
						 | 
					35ebcb2b7a | ||
| 
						 | 
					469296f157 | ||
| 
						 | 
					171777a4b3 | ||
| 
						 | 
					a7d6b9f084 | ||
| 
						 | 
					0dd5ce38fb | ||
| 
						 | 
					6c0f48f5b6 | ||
| 
						 | 
					cafffa5454 | ||
| 
						 | 
					cd7b87ffe9 | ||
| 
						 | 
					ca8804ced9 | ||
| 
						 | 
					bf81507de3 | ||
| 
						 | 
					2c43e43c8c | ||
| 
						 | 
					f8ce04036e | ||
| 
						 | 
					8aa1331c09 | ||
| 
						 | 
					ca6cbb657d | ||
| 
						 | 
					23ea2ecc2a | ||
| 
						 | 
					e98768d437 | ||
| 
						 | 
					5d8caa543c | ||
| 
						 | 
					a1fc6246b3 | ||
| 
						 | 
					e4f5c1bf8f | ||
| 
						 | 
					9580498b9a | ||
| 
						 | 
					8400429017 | ||
| 
						 | 
					526eda14a6 | ||
| 
						 | 
					fc11eb26ce | ||
| 
						 | 
					79761c6681 | ||
| 
						 | 
					e1d0fb378a | ||
| 
						 | 
					877726397f | ||
| 
						 | 
					1f22364bb5 | ||
| 
						 | 
					44b5949491 | ||
| 
						 | 
					6698894125 | ||
| 
						 | 
					8cd31adc7c | ||
| 
						 | 
					b58c8552bd | ||
| 
						 | 
					be2f78b6b0 | ||
| 
						 | 
					03a15a5436 | ||
| 
						 | 
					64160cd2a3 | ||
| 
						 | 
					144f28fa58 | ||
| 
						 | 
					59a88774d9 | ||
| 
						 | 
					56105bd5c0 | ||
| 
						 | 
					f5e7dad8ee | ||
| 
						 | 
					d94c426d46 | ||
| 
						 | 
					ee76c1f821 | ||
| 
						 | 
					b9ac5d923b | ||
| 
						 | 
					8afaefb891 | ||
| 
						 | 
					8e50724313 | ||
| 
						 | 
					437de2adc6 | ||
| 
						 | 
					f5075224d6 | ||
| 
						 | 
					e8ef31a351 | ||
| 
						 | 
					2ddc463725 | ||
| 
						 | 
					00f90df093 | ||
| 
						 | 
					a14ff8a650 | ||
| 
						 | 
					75cc1c1fcb | ||
| 
						 | 
					5c9736789b | ||
| 
						 | 
					768d7e2c7f | ||
| 
						 | 
					e0d4794458 | ||
| 
						 | 
					9a949b94f6 | ||
| 
						 | 
					908c67fca4 | ||
| 
						 | 
					0857a06ef7 | ||
| 
						 | 
					aaa2ebc567 | ||
| 
						 | 
					a00817cc4c | ||
| 
						 | 
					5739006b9a | ||
| 
						 | 
					7be9d0e6d1 | 
							
								
								
									
										2
									
								
								.mailmap
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								.mailmap
									
									
									
									
									
								
							@@ -2,7 +2,7 @@
 | 
			
		||||
# into proper addresses so that they are counted properly in git shortlog output.
 | 
			
		||||
#
 | 
			
		||||
Andrzej Zaborowski <balrogg@gmail.com> balrog <balrog@c046a42c-6fe2-441c-8c8c-71466251a162>
 | 
			
		||||
Anthony Liguori <aliguori@us.ibm.com> aliguori <aliguori@c046a42c-6fe2-441c-8c8c-71466251a162>
 | 
			
		||||
Anthony Liguori <anthony@codemonkey.ws> aliguori <aliguori@c046a42c-6fe2-441c-8c8c-71466251a162>
 | 
			
		||||
Aurelien Jarno <aurelien@aurel32.net> aurel32 <aurel32@c046a42c-6fe2-441c-8c8c-71466251a162>
 | 
			
		||||
Blue Swirl <blauwirbel@gmail.com> blueswir1 <blueswir1@c046a42c-6fe2-441c-8c8c-71466251a162>
 | 
			
		||||
Edgar E. Iglesias <edgar.iglesias@gmail.com> edgar_igl <edgar_igl@c046a42c-6fe2-441c-8c8c-71466251a162>
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										15
									
								
								LICENSE
									
									
									
									
									
								
							
							
						
						
									
										15
									
								
								LICENSE
									
									
									
									
									
								
							@@ -1,16 +1,21 @@
 | 
			
		||||
The following points clarify the QEMU license:
 | 
			
		||||
 | 
			
		||||
1) QEMU as a whole is released under the GNU General Public License
 | 
			
		||||
1) QEMU as a whole is released under the GNU General Public License,
 | 
			
		||||
version 2.
 | 
			
		||||
 | 
			
		||||
2) Parts of QEMU have specific licenses which are compatible with the
 | 
			
		||||
GNU General Public License. Hence each source file contains its own
 | 
			
		||||
licensing information.
 | 
			
		||||
GNU General Public License, version 2. Hence each source file contains
 | 
			
		||||
its own licensing information.  Source files with no licensing information
 | 
			
		||||
are released under the GNU General Public License, version 2 or (at your
 | 
			
		||||
option) any later version.
 | 
			
		||||
 | 
			
		||||
Many hardware device emulation sources are released under the BSD license.
 | 
			
		||||
As of July 2013, contributions under version 2 of the GNU General Public
 | 
			
		||||
License (and no later version) are only accepted for the following files
 | 
			
		||||
or directories: bsd-user/, linux-user/, hw/misc/vfio.c, hw/xen/xen_pt*.
 | 
			
		||||
 | 
			
		||||
3) The Tiny Code Generator (TCG) is released under the BSD license
 | 
			
		||||
   (see license headers in files).
 | 
			
		||||
 | 
			
		||||
4) QEMU is a trademark of Fabrice Bellard.
 | 
			
		||||
 | 
			
		||||
Fabrice Bellard.
 | 
			
		||||
Fabrice Bellard and the QEMU team
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										14
									
								
								MAINTAINERS
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								MAINTAINERS
									
									
									
									
									
								
							@@ -50,7 +50,7 @@ Descriptions of section entries:
 | 
			
		||||
 | 
			
		||||
General Project Administration
 | 
			
		||||
------------------------------
 | 
			
		||||
M: Anthony Liguori <aliguori@us.ibm.com>
 | 
			
		||||
M: Anthony Liguori <anthony@codemonkey.ws>
 | 
			
		||||
M: Paul Brook <paul@codesourcery.com>
 | 
			
		||||
 | 
			
		||||
Guest CPU cores (TCG):
 | 
			
		||||
@@ -509,7 +509,7 @@ F: hw/unicore32/
 | 
			
		||||
X86 Machines
 | 
			
		||||
------------
 | 
			
		||||
PC
 | 
			
		||||
M: Anthony Liguori <aliguori@us.ibm.com>
 | 
			
		||||
M: Anthony Liguori <anthony@codemonkey.ws>
 | 
			
		||||
S: Supported
 | 
			
		||||
F: hw/i386/pc.[ch]
 | 
			
		||||
F: hw/i386/pc_piix.c
 | 
			
		||||
@@ -593,7 +593,7 @@ S: Supported
 | 
			
		||||
F: hw/*/*vhost*
 | 
			
		||||
 | 
			
		||||
virtio
 | 
			
		||||
M: Anthony Liguori <aliguori@us.ibm.com>
 | 
			
		||||
M: Anthony Liguori <anthony@codemonkey.ws>
 | 
			
		||||
S: Supported
 | 
			
		||||
F: hw/*/virtio*
 | 
			
		||||
 | 
			
		||||
@@ -651,7 +651,7 @@ F: block/
 | 
			
		||||
F: hw/block/
 | 
			
		||||
 | 
			
		||||
Character Devices
 | 
			
		||||
M: Anthony Liguori <aliguori@us.ibm.com>
 | 
			
		||||
M: Anthony Liguori <anthony@codemonkey.ws>
 | 
			
		||||
S: Maintained
 | 
			
		||||
F: qemu-char.c
 | 
			
		||||
 | 
			
		||||
@@ -689,7 +689,7 @@ F: audio/spiceaudio.c
 | 
			
		||||
F: hw/display/qxl*
 | 
			
		||||
 | 
			
		||||
Graphics
 | 
			
		||||
M: Anthony Liguori <aliguori@us.ibm.com>
 | 
			
		||||
M: Anthony Liguori <anthony@codemonkey.ws>
 | 
			
		||||
S: Maintained
 | 
			
		||||
F: ui/
 | 
			
		||||
 | 
			
		||||
@@ -699,7 +699,7 @@ S: Odd Fixes
 | 
			
		||||
F: ui/cocoa.m
 | 
			
		||||
 | 
			
		||||
Main loop
 | 
			
		||||
M: Anthony Liguori <aliguori@us.ibm.com>
 | 
			
		||||
M: Anthony Liguori <anthony@codemonkey.ws>
 | 
			
		||||
S: Supported
 | 
			
		||||
F: vl.c
 | 
			
		||||
 | 
			
		||||
@@ -711,7 +711,7 @@ F: hmp.c
 | 
			
		||||
F: hmp-commands.hx
 | 
			
		||||
 | 
			
		||||
Network device layer
 | 
			
		||||
M: Anthony Liguori <aliguori@us.ibm.com>
 | 
			
		||||
M: Anthony Liguori <anthony@codemonkey.ws>
 | 
			
		||||
M: Stefan Hajnoczi <stefanha@redhat.com>
 | 
			
		||||
S: Maintained
 | 
			
		||||
F: net/
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										7
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										7
									
								
								Makefile
									
									
									
									
									
								
							@@ -167,11 +167,8 @@ recurse-all: $(SUBDIR_RULES) $(ROMSUBDIR_RULES)
 | 
			
		||||
 | 
			
		||||
bt-host.o: QEMU_CFLAGS += $(BLUEZ_CFLAGS)
 | 
			
		||||
 | 
			
		||||
version.o: $(SRC_PATH)/version.rc config-host.h | version.lo
 | 
			
		||||
version.lo: $(SRC_PATH)/version.rc config-host.h
 | 
			
		||||
 | 
			
		||||
version-obj-$(CONFIG_WIN32) += version.o
 | 
			
		||||
version-lobj-$(CONFIG_WIN32) += version.lo
 | 
			
		||||
$(BUILD_DIR)/version.o: $(SRC_PATH)/version.rc $(BUILD_DIR)/config-host.h | $(BUILD_DIR)/version.lo
 | 
			
		||||
$(BUILD_DIR)/version.lo: $(SRC_PATH)/version.rc $(BUILD_DIR)/config-host.h
 | 
			
		||||
 | 
			
		||||
Makefile: $(version-obj-y) $(version-lobj-y)
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -98,6 +98,11 @@ common-obj-y += hw/
 | 
			
		||||
common-obj-y += qom/
 | 
			
		||||
common-obj-y += disas/
 | 
			
		||||
 | 
			
		||||
######################################################################
 | 
			
		||||
# Resource file for Windows executables
 | 
			
		||||
version-obj-$(CONFIG_WIN32) += $(BUILD_DIR)/version.o
 | 
			
		||||
version-lobj-$(CONFIG_WIN32) += $(BUILD_DIR)/version.lo
 | 
			
		||||
 | 
			
		||||
######################################################################
 | 
			
		||||
# guest agent
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										36
									
								
								aio-posix.c
									
									
									
									
									
								
							
							
						
						
									
										36
									
								
								aio-posix.c
									
									
									
									
									
								
							@@ -23,7 +23,6 @@ struct AioHandler
 | 
			
		||||
    GPollFD pfd;
 | 
			
		||||
    IOHandler *io_read;
 | 
			
		||||
    IOHandler *io_write;
 | 
			
		||||
    AioFlushHandler *io_flush;
 | 
			
		||||
    int deleted;
 | 
			
		||||
    int pollfds_idx;
 | 
			
		||||
    void *opaque;
 | 
			
		||||
@@ -47,7 +46,6 @@ void aio_set_fd_handler(AioContext *ctx,
 | 
			
		||||
                        int fd,
 | 
			
		||||
                        IOHandler *io_read,
 | 
			
		||||
                        IOHandler *io_write,
 | 
			
		||||
                        AioFlushHandler *io_flush,
 | 
			
		||||
                        void *opaque)
 | 
			
		||||
{
 | 
			
		||||
    AioHandler *node;
 | 
			
		||||
@@ -84,7 +82,6 @@ void aio_set_fd_handler(AioContext *ctx,
 | 
			
		||||
        /* Update handler with latest information */
 | 
			
		||||
        node->io_read = io_read;
 | 
			
		||||
        node->io_write = io_write;
 | 
			
		||||
        node->io_flush = io_flush;
 | 
			
		||||
        node->opaque = opaque;
 | 
			
		||||
        node->pollfds_idx = -1;
 | 
			
		||||
 | 
			
		||||
@@ -97,12 +94,10 @@ void aio_set_fd_handler(AioContext *ctx,
 | 
			
		||||
 | 
			
		||||
void aio_set_event_notifier(AioContext *ctx,
 | 
			
		||||
                            EventNotifier *notifier,
 | 
			
		||||
                            EventNotifierHandler *io_read,
 | 
			
		||||
                            AioFlushEventNotifierHandler *io_flush)
 | 
			
		||||
                            EventNotifierHandler *io_read)
 | 
			
		||||
{
 | 
			
		||||
    aio_set_fd_handler(ctx, event_notifier_get_fd(notifier),
 | 
			
		||||
                       (IOHandler *)io_read, NULL,
 | 
			
		||||
                       (AioFlushHandler *)io_flush, notifier);
 | 
			
		||||
                       (IOHandler *)io_read, NULL, notifier);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool aio_pending(AioContext *ctx)
 | 
			
		||||
@@ -147,7 +142,11 @@ static bool aio_dispatch(AioContext *ctx)
 | 
			
		||||
            (revents & (G_IO_IN | G_IO_HUP | G_IO_ERR)) &&
 | 
			
		||||
            node->io_read) {
 | 
			
		||||
            node->io_read(node->opaque);
 | 
			
		||||
            progress = true;
 | 
			
		||||
 | 
			
		||||
            /* aio_notify() does not count as progress */
 | 
			
		||||
            if (node->opaque != &ctx->notifier) {
 | 
			
		||||
                progress = true;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        if (!node->deleted &&
 | 
			
		||||
            (revents & (G_IO_OUT | G_IO_ERR)) &&
 | 
			
		||||
@@ -173,7 +172,7 @@ bool aio_poll(AioContext *ctx, bool blocking)
 | 
			
		||||
{
 | 
			
		||||
    AioHandler *node;
 | 
			
		||||
    int ret;
 | 
			
		||||
    bool busy, progress;
 | 
			
		||||
    bool progress;
 | 
			
		||||
 | 
			
		||||
    progress = false;
 | 
			
		||||
 | 
			
		||||
@@ -200,20 +199,8 @@ bool aio_poll(AioContext *ctx, bool blocking)
 | 
			
		||||
    g_array_set_size(ctx->pollfds, 0);
 | 
			
		||||
 | 
			
		||||
    /* fill pollfds */
 | 
			
		||||
    busy = false;
 | 
			
		||||
    QLIST_FOREACH(node, &ctx->aio_handlers, node) {
 | 
			
		||||
        node->pollfds_idx = -1;
 | 
			
		||||
 | 
			
		||||
        /* If there aren't pending AIO operations, don't invoke callbacks.
 | 
			
		||||
         * Otherwise, if there are no AIO requests, qemu_aio_wait() would
 | 
			
		||||
         * wait indefinitely.
 | 
			
		||||
         */
 | 
			
		||||
        if (!node->deleted && node->io_flush) {
 | 
			
		||||
            if (node->io_flush(node->opaque) == 0) {
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
            busy = true;
 | 
			
		||||
        }
 | 
			
		||||
        if (!node->deleted && node->pfd.events) {
 | 
			
		||||
            GPollFD pfd = {
 | 
			
		||||
                .fd = node->pfd.fd,
 | 
			
		||||
@@ -226,8 +213,8 @@ bool aio_poll(AioContext *ctx, bool blocking)
 | 
			
		||||
 | 
			
		||||
    ctx->walking_handlers--;
 | 
			
		||||
 | 
			
		||||
    /* No AIO operations?  Get us out of here */
 | 
			
		||||
    if (!busy) {
 | 
			
		||||
    /* early return if we only have the aio_notify() fd */
 | 
			
		||||
    if (ctx->pollfds->len == 1) {
 | 
			
		||||
        return progress;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -250,6 +237,5 @@ bool aio_poll(AioContext *ctx, bool blocking)
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    assert(progress || busy);
 | 
			
		||||
    return true;
 | 
			
		||||
    return progress;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										37
									
								
								aio-win32.c
									
									
									
									
									
								
							
							
						
						
									
										37
									
								
								aio-win32.c
									
									
									
									
									
								
							@@ -23,7 +23,6 @@
 | 
			
		||||
struct AioHandler {
 | 
			
		||||
    EventNotifier *e;
 | 
			
		||||
    EventNotifierHandler *io_notify;
 | 
			
		||||
    AioFlushEventNotifierHandler *io_flush;
 | 
			
		||||
    GPollFD pfd;
 | 
			
		||||
    int deleted;
 | 
			
		||||
    QLIST_ENTRY(AioHandler) node;
 | 
			
		||||
@@ -31,8 +30,7 @@ struct AioHandler {
 | 
			
		||||
 | 
			
		||||
void aio_set_event_notifier(AioContext *ctx,
 | 
			
		||||
                            EventNotifier *e,
 | 
			
		||||
                            EventNotifierHandler *io_notify,
 | 
			
		||||
                            AioFlushEventNotifierHandler *io_flush)
 | 
			
		||||
                            EventNotifierHandler *io_notify)
 | 
			
		||||
{
 | 
			
		||||
    AioHandler *node;
 | 
			
		||||
 | 
			
		||||
@@ -73,7 +71,6 @@ void aio_set_event_notifier(AioContext *ctx,
 | 
			
		||||
        }
 | 
			
		||||
        /* Update handler with latest information */
 | 
			
		||||
        node->io_notify = io_notify;
 | 
			
		||||
        node->io_flush = io_flush;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    aio_notify(ctx);
 | 
			
		||||
@@ -96,7 +93,7 @@ bool aio_poll(AioContext *ctx, bool blocking)
 | 
			
		||||
{
 | 
			
		||||
    AioHandler *node;
 | 
			
		||||
    HANDLE events[MAXIMUM_WAIT_OBJECTS + 1];
 | 
			
		||||
    bool busy, progress;
 | 
			
		||||
    bool progress;
 | 
			
		||||
    int count;
 | 
			
		||||
 | 
			
		||||
    progress = false;
 | 
			
		||||
@@ -126,7 +123,11 @@ bool aio_poll(AioContext *ctx, bool blocking)
 | 
			
		||||
        if (node->pfd.revents && node->io_notify) {
 | 
			
		||||
            node->pfd.revents = 0;
 | 
			
		||||
            node->io_notify(node->e);
 | 
			
		||||
            progress = true;
 | 
			
		||||
 | 
			
		||||
            /* aio_notify() does not count as progress */
 | 
			
		||||
            if (node->opaque != &ctx->notifier) {
 | 
			
		||||
                progress = true;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        tmp = node;
 | 
			
		||||
@@ -147,19 +148,8 @@ bool aio_poll(AioContext *ctx, bool blocking)
 | 
			
		||||
    ctx->walking_handlers++;
 | 
			
		||||
 | 
			
		||||
    /* fill fd sets */
 | 
			
		||||
    busy = false;
 | 
			
		||||
    count = 0;
 | 
			
		||||
    QLIST_FOREACH(node, &ctx->aio_handlers, node) {
 | 
			
		||||
        /* If there aren't pending AIO operations, don't invoke callbacks.
 | 
			
		||||
         * Otherwise, if there are no AIO requests, qemu_aio_wait() would
 | 
			
		||||
         * wait indefinitely.
 | 
			
		||||
         */
 | 
			
		||||
        if (!node->deleted && node->io_flush) {
 | 
			
		||||
            if (node->io_flush(node->e) == 0) {
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
            busy = true;
 | 
			
		||||
        }
 | 
			
		||||
        if (!node->deleted && node->io_notify) {
 | 
			
		||||
            events[count++] = event_notifier_get_handle(node->e);
 | 
			
		||||
        }
 | 
			
		||||
@@ -167,8 +157,8 @@ bool aio_poll(AioContext *ctx, bool blocking)
 | 
			
		||||
 | 
			
		||||
    ctx->walking_handlers--;
 | 
			
		||||
 | 
			
		||||
    /* No AIO operations?  Get us out of here */
 | 
			
		||||
    if (!busy) {
 | 
			
		||||
    /* early return if we only have the aio_notify() fd */
 | 
			
		||||
    if (count == 1) {
 | 
			
		||||
        return progress;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -196,7 +186,11 @@ bool aio_poll(AioContext *ctx, bool blocking)
 | 
			
		||||
                event_notifier_get_handle(node->e) == events[ret - WAIT_OBJECT_0] &&
 | 
			
		||||
                node->io_notify) {
 | 
			
		||||
                node->io_notify(node->e);
 | 
			
		||||
                progress = true;
 | 
			
		||||
 | 
			
		||||
                /* aio_notify() does not count as progress */
 | 
			
		||||
                if (node->opaque != &ctx->notifier) {
 | 
			
		||||
                    progress = true;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            tmp = node;
 | 
			
		||||
@@ -214,6 +208,5 @@ bool aio_poll(AioContext *ctx, bool blocking)
 | 
			
		||||
        events[ret - WAIT_OBJECT_0] = events[--count];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    assert(progress || busy);
 | 
			
		||||
    return true;
 | 
			
		||||
    return progress;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -342,7 +342,8 @@ ram_addr_t migration_bitmap_find_and_reset_dirty(MemoryRegion *mr,
 | 
			
		||||
{
 | 
			
		||||
    unsigned long base = mr->ram_addr >> TARGET_PAGE_BITS;
 | 
			
		||||
    unsigned long nr = base + (start >> TARGET_PAGE_BITS);
 | 
			
		||||
    unsigned long size = base + (int128_get64(mr->size) >> TARGET_PAGE_BITS);
 | 
			
		||||
    uint64_t mr_size = TARGET_PAGE_ALIGN(memory_region_size(mr));
 | 
			
		||||
    unsigned long size = base + (mr_size >> TARGET_PAGE_BITS);
 | 
			
		||||
 | 
			
		||||
    unsigned long next;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										4
									
								
								async.c
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								async.c
									
									
									
									
									
								
							@@ -201,7 +201,7 @@ aio_ctx_finalize(GSource     *source)
 | 
			
		||||
    AioContext *ctx = (AioContext *) source;
 | 
			
		||||
 | 
			
		||||
    thread_pool_free(ctx->thread_pool);
 | 
			
		||||
    aio_set_event_notifier(ctx, &ctx->notifier, NULL, NULL);
 | 
			
		||||
    aio_set_event_notifier(ctx, &ctx->notifier, NULL);
 | 
			
		||||
    event_notifier_cleanup(&ctx->notifier);
 | 
			
		||||
    qemu_mutex_destroy(&ctx->bh_lock);
 | 
			
		||||
    g_array_free(ctx->pollfds, TRUE);
 | 
			
		||||
@@ -243,7 +243,7 @@ AioContext *aio_context_new(void)
 | 
			
		||||
    event_notifier_init(&ctx->notifier, false);
 | 
			
		||||
    aio_set_event_notifier(ctx, &ctx->notifier, 
 | 
			
		||||
                           (EventNotifierHandler *)
 | 
			
		||||
                           event_notifier_test_and_clear, NULL);
 | 
			
		||||
                           event_notifier_test_and_clear);
 | 
			
		||||
 | 
			
		||||
    return ctx;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										49
									
								
								block.c
									
									
									
									
									
								
							
							
						
						
									
										49
									
								
								block.c
									
									
									
									
									
								
							@@ -148,7 +148,6 @@ static void bdrv_block_timer(void *opaque)
 | 
			
		||||
 | 
			
		||||
void bdrv_io_limits_enable(BlockDriverState *bs)
 | 
			
		||||
{
 | 
			
		||||
    qemu_co_queue_init(&bs->throttled_reqs);
 | 
			
		||||
    bs->block_timer = qemu_new_timer_ns(vm_clock, bdrv_block_timer, bs);
 | 
			
		||||
    bs->io_limits_enabled = true;
 | 
			
		||||
}
 | 
			
		||||
@@ -306,6 +305,7 @@ BlockDriverState *bdrv_new(const char *device_name)
 | 
			
		||||
    bdrv_iostatus_disable(bs);
 | 
			
		||||
    notifier_list_init(&bs->close_notifiers);
 | 
			
		||||
    notifier_with_return_list_init(&bs->before_write_notifiers);
 | 
			
		||||
    qemu_co_queue_init(&bs->throttled_reqs);
 | 
			
		||||
 | 
			
		||||
    return bs;
 | 
			
		||||
}
 | 
			
		||||
@@ -1428,6 +1428,35 @@ void bdrv_close_all(void)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Check if any requests are in-flight (including throttled requests) */
 | 
			
		||||
static bool bdrv_requests_pending(BlockDriverState *bs)
 | 
			
		||||
{
 | 
			
		||||
    if (!QLIST_EMPTY(&bs->tracked_requests)) {
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
    if (!qemu_co_queue_empty(&bs->throttled_reqs)) {
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
    if (bs->file && bdrv_requests_pending(bs->file)) {
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
    if (bs->backing_hd && bdrv_requests_pending(bs->backing_hd)) {
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
    return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static bool bdrv_requests_pending_all(void)
 | 
			
		||||
{
 | 
			
		||||
    BlockDriverState *bs;
 | 
			
		||||
    QTAILQ_FOREACH(bs, &bdrv_states, list) {
 | 
			
		||||
        if (bdrv_requests_pending(bs)) {
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Wait for pending requests to complete across all BlockDriverStates
 | 
			
		||||
 *
 | 
			
		||||
@@ -1442,12 +1471,11 @@ void bdrv_close_all(void)
 | 
			
		||||
 */
 | 
			
		||||
void bdrv_drain_all(void)
 | 
			
		||||
{
 | 
			
		||||
    /* Always run first iteration so any pending completion BHs run */
 | 
			
		||||
    bool busy = true;
 | 
			
		||||
    BlockDriverState *bs;
 | 
			
		||||
    bool busy;
 | 
			
		||||
 | 
			
		||||
    do {
 | 
			
		||||
        busy = qemu_aio_wait();
 | 
			
		||||
 | 
			
		||||
    while (busy) {
 | 
			
		||||
        /* FIXME: We do not have timer support here, so this is effectively
 | 
			
		||||
         * a busy wait.
 | 
			
		||||
         */
 | 
			
		||||
@@ -1456,12 +1484,9 @@ void bdrv_drain_all(void)
 | 
			
		||||
                busy = true;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    } while (busy);
 | 
			
		||||
 | 
			
		||||
    /* If requests are still pending there is a bug somewhere */
 | 
			
		||||
    QTAILQ_FOREACH(bs, &bdrv_states, list) {
 | 
			
		||||
        assert(QLIST_EMPTY(&bs->tracked_requests));
 | 
			
		||||
        assert(qemu_co_queue_empty(&bs->throttled_reqs));
 | 
			
		||||
        busy = bdrv_requests_pending_all();
 | 
			
		||||
        busy |= aio_poll(qemu_get_aio_context(), busy);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -1606,11 +1631,11 @@ void bdrv_delete(BlockDriverState *bs)
 | 
			
		||||
    assert(!bs->job);
 | 
			
		||||
    assert(!bs->in_use);
 | 
			
		||||
 | 
			
		||||
    bdrv_close(bs);
 | 
			
		||||
 | 
			
		||||
    /* remove from list, if necessary */
 | 
			
		||||
    bdrv_make_anon(bs);
 | 
			
		||||
 | 
			
		||||
    bdrv_close(bs);
 | 
			
		||||
 | 
			
		||||
    g_free(bs);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										25
									
								
								block/curl.c
									
									
									
									
									
								
							
							
						
						
									
										25
									
								
								block/curl.c
									
									
									
									
									
								
							@@ -86,7 +86,6 @@ typedef struct BDRVCURLState {
 | 
			
		||||
 | 
			
		||||
static void curl_clean_state(CURLState *s);
 | 
			
		||||
static void curl_multi_do(void *arg);
 | 
			
		||||
static int curl_aio_flush(void *opaque);
 | 
			
		||||
 | 
			
		||||
static int curl_sock_cb(CURL *curl, curl_socket_t fd, int action,
 | 
			
		||||
                        void *s, void *sp)
 | 
			
		||||
@@ -94,17 +93,16 @@ static int curl_sock_cb(CURL *curl, curl_socket_t fd, int action,
 | 
			
		||||
    DPRINTF("CURL (AIO): Sock action %d on fd %d\n", action, fd);
 | 
			
		||||
    switch (action) {
 | 
			
		||||
        case CURL_POLL_IN:
 | 
			
		||||
            qemu_aio_set_fd_handler(fd, curl_multi_do, NULL, curl_aio_flush, s);
 | 
			
		||||
            qemu_aio_set_fd_handler(fd, curl_multi_do, NULL, s);
 | 
			
		||||
            break;
 | 
			
		||||
        case CURL_POLL_OUT:
 | 
			
		||||
            qemu_aio_set_fd_handler(fd, NULL, curl_multi_do, curl_aio_flush, s);
 | 
			
		||||
            qemu_aio_set_fd_handler(fd, NULL, curl_multi_do, s);
 | 
			
		||||
            break;
 | 
			
		||||
        case CURL_POLL_INOUT:
 | 
			
		||||
            qemu_aio_set_fd_handler(fd, curl_multi_do, curl_multi_do,
 | 
			
		||||
                                    curl_aio_flush, s);
 | 
			
		||||
            qemu_aio_set_fd_handler(fd, curl_multi_do, curl_multi_do, s);
 | 
			
		||||
            break;
 | 
			
		||||
        case CURL_POLL_REMOVE:
 | 
			
		||||
            qemu_aio_set_fd_handler(fd, NULL, NULL, NULL, NULL);
 | 
			
		||||
            qemu_aio_set_fd_handler(fd, NULL, NULL, NULL);
 | 
			
		||||
            break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -495,21 +493,6 @@ out_noclean:
 | 
			
		||||
    return -EINVAL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int curl_aio_flush(void *opaque)
 | 
			
		||||
{
 | 
			
		||||
    BDRVCURLState *s = opaque;
 | 
			
		||||
    int i, j;
 | 
			
		||||
 | 
			
		||||
    for (i=0; i < CURL_NUM_STATES; i++) {
 | 
			
		||||
        for(j=0; j < CURL_NUM_ACB; j++) {
 | 
			
		||||
            if (s->states[i].acb[j]) {
 | 
			
		||||
                return 1;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void curl_aio_cancel(BlockDriverAIOCB *blockacb)
 | 
			
		||||
{
 | 
			
		||||
    // Do we have to implement canceling? Seems to work without...
 | 
			
		||||
 
 | 
			
		||||
@@ -32,7 +32,6 @@ typedef struct BDRVGlusterState {
 | 
			
		||||
    struct glfs *glfs;
 | 
			
		||||
    int fds[2];
 | 
			
		||||
    struct glfs_fd *fd;
 | 
			
		||||
    int qemu_aio_count;
 | 
			
		||||
    int event_reader_pos;
 | 
			
		||||
    GlusterAIOCB *event_acb;
 | 
			
		||||
} BDRVGlusterState;
 | 
			
		||||
@@ -247,7 +246,6 @@ static void qemu_gluster_complete_aio(GlusterAIOCB *acb, BDRVGlusterState *s)
 | 
			
		||||
        ret = -EIO; /* Partial read/write - fail it */
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    s->qemu_aio_count--;
 | 
			
		||||
    qemu_aio_release(acb);
 | 
			
		||||
    cb(opaque, ret);
 | 
			
		||||
    if (finished) {
 | 
			
		||||
@@ -275,13 +273,6 @@ static void qemu_gluster_aio_event_reader(void *opaque)
 | 
			
		||||
    } while (ret < 0 && errno == EINTR);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int qemu_gluster_aio_flush_cb(void *opaque)
 | 
			
		||||
{
 | 
			
		||||
    BDRVGlusterState *s = opaque;
 | 
			
		||||
 | 
			
		||||
    return (s->qemu_aio_count > 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* TODO Convert to fine grained options */
 | 
			
		||||
static QemuOptsList runtime_opts = {
 | 
			
		||||
    .name = "gluster",
 | 
			
		||||
@@ -348,7 +339,7 @@ static int qemu_gluster_open(BlockDriverState *bs,  QDict *options,
 | 
			
		||||
    }
 | 
			
		||||
    fcntl(s->fds[GLUSTER_FD_READ], F_SETFL, O_NONBLOCK);
 | 
			
		||||
    qemu_aio_set_fd_handler(s->fds[GLUSTER_FD_READ],
 | 
			
		||||
        qemu_gluster_aio_event_reader, NULL, qemu_gluster_aio_flush_cb, s);
 | 
			
		||||
        qemu_gluster_aio_event_reader, NULL, s);
 | 
			
		||||
 | 
			
		||||
out:
 | 
			
		||||
    qemu_opts_del(opts);
 | 
			
		||||
@@ -445,11 +436,9 @@ static void gluster_finish_aiocb(struct glfs_fd *fd, ssize_t ret, void *arg)
 | 
			
		||||
        qemu_mutex_lock_iothread(); /* We are in gluster thread context */
 | 
			
		||||
        acb->common.cb(acb->common.opaque, -EIO);
 | 
			
		||||
        qemu_aio_release(acb);
 | 
			
		||||
        s->qemu_aio_count--;
 | 
			
		||||
        close(s->fds[GLUSTER_FD_READ]);
 | 
			
		||||
        close(s->fds[GLUSTER_FD_WRITE]);
 | 
			
		||||
        qemu_aio_set_fd_handler(s->fds[GLUSTER_FD_READ], NULL, NULL, NULL,
 | 
			
		||||
            NULL);
 | 
			
		||||
        qemu_aio_set_fd_handler(s->fds[GLUSTER_FD_READ], NULL, NULL, NULL);
 | 
			
		||||
        bs->drv = NULL; /* Make the disk inaccessible */
 | 
			
		||||
        qemu_mutex_unlock_iothread();
 | 
			
		||||
    }
 | 
			
		||||
@@ -467,7 +456,6 @@ static BlockDriverAIOCB *qemu_gluster_aio_rw(BlockDriverState *bs,
 | 
			
		||||
 | 
			
		||||
    offset = sector_num * BDRV_SECTOR_SIZE;
 | 
			
		||||
    size = nb_sectors * BDRV_SECTOR_SIZE;
 | 
			
		||||
    s->qemu_aio_count++;
 | 
			
		||||
 | 
			
		||||
    acb = qemu_aio_get(&gluster_aiocb_info, bs, cb, opaque);
 | 
			
		||||
    acb->size = size;
 | 
			
		||||
@@ -488,7 +476,6 @@ static BlockDriverAIOCB *qemu_gluster_aio_rw(BlockDriverState *bs,
 | 
			
		||||
    return &acb->common;
 | 
			
		||||
 | 
			
		||||
out:
 | 
			
		||||
    s->qemu_aio_count--;
 | 
			
		||||
    qemu_aio_release(acb);
 | 
			
		||||
    return NULL;
 | 
			
		||||
}
 | 
			
		||||
@@ -531,7 +518,6 @@ static BlockDriverAIOCB *qemu_gluster_aio_flush(BlockDriverState *bs,
 | 
			
		||||
    acb->size = 0;
 | 
			
		||||
    acb->ret = 0;
 | 
			
		||||
    acb->finished = NULL;
 | 
			
		||||
    s->qemu_aio_count++;
 | 
			
		||||
 | 
			
		||||
    ret = glfs_fsync_async(s->fd, &gluster_finish_aiocb, acb);
 | 
			
		||||
    if (ret < 0) {
 | 
			
		||||
@@ -540,7 +526,6 @@ static BlockDriverAIOCB *qemu_gluster_aio_flush(BlockDriverState *bs,
 | 
			
		||||
    return &acb->common;
 | 
			
		||||
 | 
			
		||||
out:
 | 
			
		||||
    s->qemu_aio_count--;
 | 
			
		||||
    qemu_aio_release(acb);
 | 
			
		||||
    return NULL;
 | 
			
		||||
}
 | 
			
		||||
@@ -563,7 +548,6 @@ static BlockDriverAIOCB *qemu_gluster_aio_discard(BlockDriverState *bs,
 | 
			
		||||
    acb->size = 0;
 | 
			
		||||
    acb->ret = 0;
 | 
			
		||||
    acb->finished = NULL;
 | 
			
		||||
    s->qemu_aio_count++;
 | 
			
		||||
 | 
			
		||||
    ret = glfs_discard_async(s->fd, offset, size, &gluster_finish_aiocb, acb);
 | 
			
		||||
    if (ret < 0) {
 | 
			
		||||
@@ -572,7 +556,6 @@ static BlockDriverAIOCB *qemu_gluster_aio_discard(BlockDriverState *bs,
 | 
			
		||||
    return &acb->common;
 | 
			
		||||
 | 
			
		||||
out:
 | 
			
		||||
    s->qemu_aio_count--;
 | 
			
		||||
    qemu_aio_release(acb);
 | 
			
		||||
    return NULL;
 | 
			
		||||
}
 | 
			
		||||
@@ -611,7 +594,7 @@ static void qemu_gluster_close(BlockDriverState *bs)
 | 
			
		||||
 | 
			
		||||
    close(s->fds[GLUSTER_FD_READ]);
 | 
			
		||||
    close(s->fds[GLUSTER_FD_WRITE]);
 | 
			
		||||
    qemu_aio_set_fd_handler(s->fds[GLUSTER_FD_READ], NULL, NULL, NULL, NULL);
 | 
			
		||||
    qemu_aio_set_fd_handler(s->fds[GLUSTER_FD_READ], NULL, NULL, NULL);
 | 
			
		||||
 | 
			
		||||
    if (s->fd) {
 | 
			
		||||
        glfs_close(s->fd);
 | 
			
		||||
 
 | 
			
		||||
@@ -146,13 +146,6 @@ static const AIOCBInfo iscsi_aiocb_info = {
 | 
			
		||||
static void iscsi_process_read(void *arg);
 | 
			
		||||
static void iscsi_process_write(void *arg);
 | 
			
		||||
 | 
			
		||||
static int iscsi_process_flush(void *arg)
 | 
			
		||||
{
 | 
			
		||||
    IscsiLun *iscsilun = arg;
 | 
			
		||||
 | 
			
		||||
    return iscsi_queue_length(iscsilun->iscsi) > 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
iscsi_set_events(IscsiLun *iscsilun)
 | 
			
		||||
{
 | 
			
		||||
@@ -166,7 +159,6 @@ iscsi_set_events(IscsiLun *iscsilun)
 | 
			
		||||
        qemu_aio_set_fd_handler(iscsi_get_fd(iscsi),
 | 
			
		||||
                      iscsi_process_read,
 | 
			
		||||
                      (ev & POLLOUT) ? iscsi_process_write : NULL,
 | 
			
		||||
                      iscsi_process_flush,
 | 
			
		||||
                      iscsilun);
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
@@ -247,7 +239,9 @@ static bool is_request_lun_aligned(int64_t sector_num, int nb_sectors,
 | 
			
		||||
{
 | 
			
		||||
    if ((sector_num * BDRV_SECTOR_SIZE) % iscsilun->block_size ||
 | 
			
		||||
        (nb_sectors * BDRV_SECTOR_SIZE) % iscsilun->block_size) {
 | 
			
		||||
            error_report("iSCSI misaligned request: iscsilun->block_size %u, sector_num %ld, nb_sectors %d",
 | 
			
		||||
            error_report("iSCSI misaligned request: "
 | 
			
		||||
                         "iscsilun->block_size %u, sector_num %" PRIi64
 | 
			
		||||
                         ", nb_sectors %d",
 | 
			
		||||
                         iscsilun->block_size, sector_num, nb_sectors);
 | 
			
		||||
            return 0;
 | 
			
		||||
    }
 | 
			
		||||
@@ -1213,7 +1207,7 @@ static void iscsi_close(BlockDriverState *bs)
 | 
			
		||||
        qemu_del_timer(iscsilun->nop_timer);
 | 
			
		||||
        qemu_free_timer(iscsilun->nop_timer);
 | 
			
		||||
    }
 | 
			
		||||
    qemu_aio_set_fd_handler(iscsi_get_fd(iscsi), NULL, NULL, NULL, NULL);
 | 
			
		||||
    qemu_aio_set_fd_handler(iscsi_get_fd(iscsi), NULL, NULL, NULL);
 | 
			
		||||
    iscsi_destroy_context(iscsi);
 | 
			
		||||
    memset(iscsilun, 0, sizeof(IscsiLun));
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -39,7 +39,6 @@ struct qemu_laiocb {
 | 
			
		||||
struct qemu_laio_state {
 | 
			
		||||
    io_context_t ctx;
 | 
			
		||||
    EventNotifier e;
 | 
			
		||||
    int count;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static inline ssize_t io_event_ret(struct io_event *ev)
 | 
			
		||||
@@ -55,8 +54,6 @@ static void qemu_laio_process_completion(struct qemu_laio_state *s,
 | 
			
		||||
{
 | 
			
		||||
    int ret;
 | 
			
		||||
 | 
			
		||||
    s->count--;
 | 
			
		||||
 | 
			
		||||
    ret = laiocb->ret;
 | 
			
		||||
    if (ret != -ECANCELED) {
 | 
			
		||||
        if (ret == laiocb->nbytes) {
 | 
			
		||||
@@ -101,13 +98,6 @@ static void qemu_laio_completion_cb(EventNotifier *e)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int qemu_laio_flush_cb(EventNotifier *e)
 | 
			
		||||
{
 | 
			
		||||
    struct qemu_laio_state *s = container_of(e, struct qemu_laio_state, e);
 | 
			
		||||
 | 
			
		||||
    return (s->count > 0) ? 1 : 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void laio_cancel(BlockDriverAIOCB *blockacb)
 | 
			
		||||
{
 | 
			
		||||
    struct qemu_laiocb *laiocb = (struct qemu_laiocb *)blockacb;
 | 
			
		||||
@@ -177,14 +167,11 @@ BlockDriverAIOCB *laio_submit(BlockDriverState *bs, void *aio_ctx, int fd,
 | 
			
		||||
        goto out_free_aiocb;
 | 
			
		||||
    }
 | 
			
		||||
    io_set_eventfd(&laiocb->iocb, event_notifier_get_fd(&s->e));
 | 
			
		||||
    s->count++;
 | 
			
		||||
 | 
			
		||||
    if (io_submit(s->ctx, 1, &iocbs) < 0)
 | 
			
		||||
        goto out_dec_count;
 | 
			
		||||
        goto out_free_aiocb;
 | 
			
		||||
    return &laiocb->common;
 | 
			
		||||
 | 
			
		||||
out_dec_count:
 | 
			
		||||
    s->count--;
 | 
			
		||||
out_free_aiocb:
 | 
			
		||||
    qemu_aio_release(laiocb);
 | 
			
		||||
    return NULL;
 | 
			
		||||
@@ -203,8 +190,7 @@ void *laio_init(void)
 | 
			
		||||
        goto out_close_efd;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    qemu_aio_set_event_notifier(&s->e, qemu_laio_completion_cb,
 | 
			
		||||
                                qemu_laio_flush_cb);
 | 
			
		||||
    qemu_aio_set_event_notifier(&s->e, qemu_laio_completion_cb);
 | 
			
		||||
 | 
			
		||||
    return s;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										18
									
								
								block/nbd.c
									
									
									
									
									
								
							
							
						
						
									
										18
									
								
								block/nbd.c
									
									
									
									
									
								
							@@ -279,13 +279,6 @@ static void nbd_coroutine_start(BDRVNBDState *s, struct nbd_request *request)
 | 
			
		||||
    request->handle = INDEX_TO_HANDLE(s, i);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int nbd_have_request(void *opaque)
 | 
			
		||||
{
 | 
			
		||||
    BDRVNBDState *s = opaque;
 | 
			
		||||
 | 
			
		||||
    return s->in_flight > 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void nbd_reply_ready(void *opaque)
 | 
			
		||||
{
 | 
			
		||||
    BDRVNBDState *s = opaque;
 | 
			
		||||
@@ -341,8 +334,7 @@ static int nbd_co_send_request(BDRVNBDState *s, struct nbd_request *request,
 | 
			
		||||
 | 
			
		||||
    qemu_co_mutex_lock(&s->send_mutex);
 | 
			
		||||
    s->send_coroutine = qemu_coroutine_self();
 | 
			
		||||
    qemu_aio_set_fd_handler(s->sock, nbd_reply_ready, nbd_restart_write,
 | 
			
		||||
                            nbd_have_request, s);
 | 
			
		||||
    qemu_aio_set_fd_handler(s->sock, nbd_reply_ready, nbd_restart_write, s);
 | 
			
		||||
    if (qiov) {
 | 
			
		||||
        if (!s->is_unix) {
 | 
			
		||||
            socket_set_cork(s->sock, 1);
 | 
			
		||||
@@ -361,8 +353,7 @@ static int nbd_co_send_request(BDRVNBDState *s, struct nbd_request *request,
 | 
			
		||||
    } else {
 | 
			
		||||
        rc = nbd_send_request(s->sock, request);
 | 
			
		||||
    }
 | 
			
		||||
    qemu_aio_set_fd_handler(s->sock, nbd_reply_ready, NULL,
 | 
			
		||||
                            nbd_have_request, s);
 | 
			
		||||
    qemu_aio_set_fd_handler(s->sock, nbd_reply_ready, NULL, s);
 | 
			
		||||
    s->send_coroutine = NULL;
 | 
			
		||||
    qemu_co_mutex_unlock(&s->send_mutex);
 | 
			
		||||
    return rc;
 | 
			
		||||
@@ -438,8 +429,7 @@ static int nbd_establish_connection(BlockDriverState *bs)
 | 
			
		||||
    /* Now that we're connected, set the socket to be non-blocking and
 | 
			
		||||
     * kick the reply mechanism.  */
 | 
			
		||||
    qemu_set_nonblock(sock);
 | 
			
		||||
    qemu_aio_set_fd_handler(sock, nbd_reply_ready, NULL,
 | 
			
		||||
                            nbd_have_request, s);
 | 
			
		||||
    qemu_aio_set_fd_handler(sock, nbd_reply_ready, NULL, s);
 | 
			
		||||
 | 
			
		||||
    s->sock = sock;
 | 
			
		||||
    s->size = size;
 | 
			
		||||
@@ -459,7 +449,7 @@ static void nbd_teardown_connection(BlockDriverState *bs)
 | 
			
		||||
    request.len = 0;
 | 
			
		||||
    nbd_send_request(s->sock, &request);
 | 
			
		||||
 | 
			
		||||
    qemu_aio_set_fd_handler(s->sock, NULL, NULL, NULL, NULL);
 | 
			
		||||
    qemu_aio_set_fd_handler(s->sock, NULL, NULL, NULL);
 | 
			
		||||
    closesocket(s->sock);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										23
									
								
								block/raw.c
									
									
									
									
									
								
							
							
						
						
									
										23
									
								
								block/raw.c
									
									
									
									
									
								
							@@ -1,3 +1,26 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Block driver for RAW format
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (c) 2006 Fabrice Bellard
 | 
			
		||||
 *
 | 
			
		||||
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 | 
			
		||||
 * of this software and associated documentation files (the "Software"), to deal
 | 
			
		||||
 * in the Software without restriction, including without limitation the rights
 | 
			
		||||
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 | 
			
		||||
 * copies of the Software, and to permit persons to whom the Software is
 | 
			
		||||
 * furnished to do so, subject to the following conditions:
 | 
			
		||||
 *
 | 
			
		||||
 * The above copyright notice and this permission notice shall be included in
 | 
			
		||||
 * all copies or substantial portions of the Software.
 | 
			
		||||
 *
 | 
			
		||||
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
			
		||||
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 | 
			
		||||
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
			
		||||
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 | 
			
		||||
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 | 
			
		||||
 * THE SOFTWARE.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "qemu-common.h"
 | 
			
		||||
#include "block/block_int.h"
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										16
									
								
								block/rbd.c
									
									
									
									
									
								
							
							
						
						
									
										16
									
								
								block/rbd.c
									
									
									
									
									
								
							@@ -100,7 +100,6 @@ typedef struct BDRVRBDState {
 | 
			
		||||
    rados_ioctx_t io_ctx;
 | 
			
		||||
    rbd_image_t image;
 | 
			
		||||
    char name[RBD_MAX_IMAGE_NAME_SIZE];
 | 
			
		||||
    int qemu_aio_count;
 | 
			
		||||
    char *snap;
 | 
			
		||||
    int event_reader_pos;
 | 
			
		||||
    RADOSCB *event_rcb;
 | 
			
		||||
@@ -428,19 +427,11 @@ static void qemu_rbd_aio_event_reader(void *opaque)
 | 
			
		||||
            if (s->event_reader_pos == sizeof(s->event_rcb)) {
 | 
			
		||||
                s->event_reader_pos = 0;
 | 
			
		||||
                qemu_rbd_complete_aio(s->event_rcb);
 | 
			
		||||
                s->qemu_aio_count--;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    } while (ret < 0 && errno == EINTR);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int qemu_rbd_aio_flush_cb(void *opaque)
 | 
			
		||||
{
 | 
			
		||||
    BDRVRBDState *s = opaque;
 | 
			
		||||
 | 
			
		||||
    return (s->qemu_aio_count > 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* TODO Convert to fine grained options */
 | 
			
		||||
static QemuOptsList runtime_opts = {
 | 
			
		||||
    .name = "rbd",
 | 
			
		||||
@@ -554,7 +545,7 @@ static int qemu_rbd_open(BlockDriverState *bs, QDict *options, int flags)
 | 
			
		||||
    fcntl(s->fds[0], F_SETFL, O_NONBLOCK);
 | 
			
		||||
    fcntl(s->fds[1], F_SETFL, O_NONBLOCK);
 | 
			
		||||
    qemu_aio_set_fd_handler(s->fds[RBD_FD_READ], qemu_rbd_aio_event_reader,
 | 
			
		||||
                            NULL, qemu_rbd_aio_flush_cb, s);
 | 
			
		||||
                            NULL, s);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    qemu_opts_del(opts);
 | 
			
		||||
@@ -578,7 +569,7 @@ static void qemu_rbd_close(BlockDriverState *bs)
 | 
			
		||||
 | 
			
		||||
    close(s->fds[0]);
 | 
			
		||||
    close(s->fds[1]);
 | 
			
		||||
    qemu_aio_set_fd_handler(s->fds[RBD_FD_READ], NULL, NULL, NULL, NULL);
 | 
			
		||||
    qemu_aio_set_fd_handler(s->fds[RBD_FD_READ], NULL, NULL, NULL);
 | 
			
		||||
 | 
			
		||||
    rbd_close(s->image);
 | 
			
		||||
    rados_ioctx_destroy(s->io_ctx);
 | 
			
		||||
@@ -741,8 +732,6 @@ static BlockDriverAIOCB *rbd_start_aio(BlockDriverState *bs,
 | 
			
		||||
    off = sector_num * BDRV_SECTOR_SIZE;
 | 
			
		||||
    size = nb_sectors * BDRV_SECTOR_SIZE;
 | 
			
		||||
 | 
			
		||||
    s->qemu_aio_count++; /* All the RADOSCB */
 | 
			
		||||
 | 
			
		||||
    rcb = g_malloc(sizeof(RADOSCB));
 | 
			
		||||
    rcb->done = 0;
 | 
			
		||||
    rcb->acb = acb;
 | 
			
		||||
@@ -779,7 +768,6 @@ static BlockDriverAIOCB *rbd_start_aio(BlockDriverState *bs,
 | 
			
		||||
 | 
			
		||||
failed:
 | 
			
		||||
    g_free(rcb);
 | 
			
		||||
    s->qemu_aio_count--;
 | 
			
		||||
    qemu_aio_release(acb);
 | 
			
		||||
    return NULL;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -509,13 +509,6 @@ static void restart_co_req(void *opaque)
 | 
			
		||||
    qemu_coroutine_enter(co, NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int have_co_req(void *opaque)
 | 
			
		||||
{
 | 
			
		||||
    /* this handler is set only when there is a pending request, so
 | 
			
		||||
     * always returns 1. */
 | 
			
		||||
    return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
typedef struct SheepdogReqCo {
 | 
			
		||||
    int sockfd;
 | 
			
		||||
    SheepdogReq *hdr;
 | 
			
		||||
@@ -538,14 +531,14 @@ static coroutine_fn void do_co_req(void *opaque)
 | 
			
		||||
    unsigned int *rlen = srco->rlen;
 | 
			
		||||
 | 
			
		||||
    co = qemu_coroutine_self();
 | 
			
		||||
    qemu_aio_set_fd_handler(sockfd, NULL, restart_co_req, have_co_req, co);
 | 
			
		||||
    qemu_aio_set_fd_handler(sockfd, NULL, restart_co_req, co);
 | 
			
		||||
 | 
			
		||||
    ret = send_co_req(sockfd, hdr, data, wlen);
 | 
			
		||||
    if (ret < 0) {
 | 
			
		||||
        goto out;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    qemu_aio_set_fd_handler(sockfd, restart_co_req, NULL, have_co_req, co);
 | 
			
		||||
    qemu_aio_set_fd_handler(sockfd, restart_co_req, NULL, co);
 | 
			
		||||
 | 
			
		||||
    ret = qemu_co_recv(sockfd, hdr, sizeof(*hdr));
 | 
			
		||||
    if (ret < sizeof(*hdr)) {
 | 
			
		||||
@@ -570,7 +563,7 @@ static coroutine_fn void do_co_req(void *opaque)
 | 
			
		||||
out:
 | 
			
		||||
    /* there is at most one request for this sockfd, so it is safe to
 | 
			
		||||
     * set each handler to NULL. */
 | 
			
		||||
    qemu_aio_set_fd_handler(sockfd, NULL, NULL, NULL, NULL);
 | 
			
		||||
    qemu_aio_set_fd_handler(sockfd, NULL, NULL, NULL);
 | 
			
		||||
 | 
			
		||||
    srco->ret = ret;
 | 
			
		||||
    srco->finished = true;
 | 
			
		||||
@@ -796,14 +789,6 @@ static void co_write_request(void *opaque)
 | 
			
		||||
    qemu_coroutine_enter(s->co_send, NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int aio_flush_request(void *opaque)
 | 
			
		||||
{
 | 
			
		||||
    BDRVSheepdogState *s = opaque;
 | 
			
		||||
 | 
			
		||||
    return !QLIST_EMPTY(&s->inflight_aio_head) ||
 | 
			
		||||
        !QLIST_EMPTY(&s->pending_aio_head);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Return a socket discriptor to read/write objects.
 | 
			
		||||
 *
 | 
			
		||||
@@ -819,7 +804,7 @@ static int get_sheep_fd(BDRVSheepdogState *s)
 | 
			
		||||
        return fd;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    qemu_aio_set_fd_handler(fd, co_read_response, NULL, aio_flush_request, s);
 | 
			
		||||
    qemu_aio_set_fd_handler(fd, co_read_response, NULL, s);
 | 
			
		||||
    return fd;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -1069,8 +1054,7 @@ static int coroutine_fn add_aio_request(BDRVSheepdogState *s, AIOReq *aio_req,
 | 
			
		||||
 | 
			
		||||
    qemu_co_mutex_lock(&s->lock);
 | 
			
		||||
    s->co_send = qemu_coroutine_self();
 | 
			
		||||
    qemu_aio_set_fd_handler(s->fd, co_read_response, co_write_request,
 | 
			
		||||
                            aio_flush_request, s);
 | 
			
		||||
    qemu_aio_set_fd_handler(s->fd, co_read_response, co_write_request, s);
 | 
			
		||||
    socket_set_cork(s->fd, 1);
 | 
			
		||||
 | 
			
		||||
    /* send a header */
 | 
			
		||||
@@ -1091,8 +1075,7 @@ static int coroutine_fn add_aio_request(BDRVSheepdogState *s, AIOReq *aio_req,
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    socket_set_cork(s->fd, 0);
 | 
			
		||||
    qemu_aio_set_fd_handler(s->fd, co_read_response, NULL,
 | 
			
		||||
                            aio_flush_request, s);
 | 
			
		||||
    qemu_aio_set_fd_handler(s->fd, co_read_response, NULL, s);
 | 
			
		||||
    qemu_co_mutex_unlock(&s->lock);
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
@@ -1350,7 +1333,7 @@ static int sd_open(BlockDriverState *bs, QDict *options, int flags)
 | 
			
		||||
    g_free(buf);
 | 
			
		||||
    return 0;
 | 
			
		||||
out:
 | 
			
		||||
    qemu_aio_set_fd_handler(s->fd, NULL, NULL, NULL, NULL);
 | 
			
		||||
    qemu_aio_set_fd_handler(s->fd, NULL, NULL, NULL);
 | 
			
		||||
    if (s->fd >= 0) {
 | 
			
		||||
        closesocket(s->fd);
 | 
			
		||||
    }
 | 
			
		||||
@@ -1578,7 +1561,7 @@ static void sd_close(BlockDriverState *bs)
 | 
			
		||||
        error_report("%s, %s", sd_strerror(rsp->result), s->name);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    qemu_aio_set_fd_handler(s->fd, NULL, NULL, NULL, NULL);
 | 
			
		||||
    qemu_aio_set_fd_handler(s->fd, NULL, NULL, NULL);
 | 
			
		||||
    closesocket(s->fd);
 | 
			
		||||
    g_free(s->host_spec);
 | 
			
		||||
}
 | 
			
		||||
@@ -2347,6 +2330,7 @@ static BlockDriver bdrv_sheepdog = {
 | 
			
		||||
    .bdrv_file_open = sd_open,
 | 
			
		||||
    .bdrv_close     = sd_close,
 | 
			
		||||
    .bdrv_create    = sd_create,
 | 
			
		||||
    .bdrv_has_zero_init = bdrv_has_zero_init_1,
 | 
			
		||||
    .bdrv_getlength = sd_getlength,
 | 
			
		||||
    .bdrv_truncate  = sd_truncate,
 | 
			
		||||
 | 
			
		||||
@@ -2374,6 +2358,7 @@ static BlockDriver bdrv_sheepdog_tcp = {
 | 
			
		||||
    .bdrv_file_open = sd_open,
 | 
			
		||||
    .bdrv_close     = sd_close,
 | 
			
		||||
    .bdrv_create    = sd_create,
 | 
			
		||||
    .bdrv_has_zero_init = bdrv_has_zero_init_1,
 | 
			
		||||
    .bdrv_getlength = sd_getlength,
 | 
			
		||||
    .bdrv_truncate  = sd_truncate,
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										12
									
								
								block/ssh.c
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								block/ssh.c
									
									
									
									
									
								
							@@ -740,14 +740,6 @@ static void restart_coroutine(void *opaque)
 | 
			
		||||
    qemu_coroutine_enter(co, NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Always true because when we have called set_fd_handler there is
 | 
			
		||||
 * always a request being processed.
 | 
			
		||||
 */
 | 
			
		||||
static int return_true(void *opaque)
 | 
			
		||||
{
 | 
			
		||||
    return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static coroutine_fn void set_fd_handler(BDRVSSHState *s)
 | 
			
		||||
{
 | 
			
		||||
    int r;
 | 
			
		||||
@@ -766,13 +758,13 @@ static coroutine_fn void set_fd_handler(BDRVSSHState *s)
 | 
			
		||||
    DPRINTF("s->sock=%d rd_handler=%p wr_handler=%p", s->sock,
 | 
			
		||||
            rd_handler, wr_handler);
 | 
			
		||||
 | 
			
		||||
    qemu_aio_set_fd_handler(s->sock, rd_handler, wr_handler, return_true, co);
 | 
			
		||||
    qemu_aio_set_fd_handler(s->sock, rd_handler, wr_handler, co);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static coroutine_fn void clear_fd_handler(BDRVSSHState *s)
 | 
			
		||||
{
 | 
			
		||||
    DPRINTF("s->sock=%d", s->sock);
 | 
			
		||||
    qemu_aio_set_fd_handler(s->sock, NULL, NULL, NULL, NULL);
 | 
			
		||||
    qemu_aio_set_fd_handler(s->sock, NULL, NULL, NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* A non-blocking call returned EAGAIN, so yield, ensuring the
 | 
			
		||||
 
 | 
			
		||||
@@ -57,6 +57,11 @@ static void close_unused_images(BlockDriverState *top, BlockDriverState *base,
 | 
			
		||||
    BlockDriverState *intermediate;
 | 
			
		||||
    intermediate = top->backing_hd;
 | 
			
		||||
 | 
			
		||||
    /* Must assign before bdrv_delete() to prevent traversing dangling pointer
 | 
			
		||||
     * while we delete backing image instances.
 | 
			
		||||
     */
 | 
			
		||||
    top->backing_hd = base;
 | 
			
		||||
 | 
			
		||||
    while (intermediate) {
 | 
			
		||||
        BlockDriverState *unused;
 | 
			
		||||
 | 
			
		||||
@@ -70,7 +75,6 @@ static void close_unused_images(BlockDriverState *top, BlockDriverState *base,
 | 
			
		||||
        unused->backing_hd = NULL;
 | 
			
		||||
        bdrv_delete(unused);
 | 
			
		||||
    }
 | 
			
		||||
    top->backing_hd = base;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void coroutine_fn stream_run(void *opaque)
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										123
									
								
								block/vmdk.c
									
									
									
									
									
								
							
							
						
						
									
										123
									
								
								block/vmdk.c
									
									
									
									
									
								
							@@ -62,19 +62,20 @@ typedef struct {
 | 
			
		||||
    uint32_t cylinders;
 | 
			
		||||
    uint32_t heads;
 | 
			
		||||
    uint32_t sectors_per_track;
 | 
			
		||||
} VMDK3Header;
 | 
			
		||||
} QEMU_PACKED VMDK3Header;
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
    uint32_t version;
 | 
			
		||||
    uint32_t flags;
 | 
			
		||||
    int64_t capacity;
 | 
			
		||||
    int64_t granularity;
 | 
			
		||||
    int64_t desc_offset;
 | 
			
		||||
    int64_t desc_size;
 | 
			
		||||
    int32_t num_gtes_per_gte;
 | 
			
		||||
    int64_t rgd_offset;
 | 
			
		||||
    int64_t gd_offset;
 | 
			
		||||
    int64_t grain_offset;
 | 
			
		||||
    uint64_t capacity;
 | 
			
		||||
    uint64_t granularity;
 | 
			
		||||
    uint64_t desc_offset;
 | 
			
		||||
    uint64_t desc_size;
 | 
			
		||||
    /* Number of GrainTableEntries per GrainTable */
 | 
			
		||||
    uint32_t num_gtes_per_gt;
 | 
			
		||||
    uint64_t rgd_offset;
 | 
			
		||||
    uint64_t gd_offset;
 | 
			
		||||
    uint64_t grain_offset;
 | 
			
		||||
    char filler[1];
 | 
			
		||||
    char check_bytes[4];
 | 
			
		||||
    uint16_t compressAlgorithm;
 | 
			
		||||
@@ -109,7 +110,7 @@ typedef struct VmdkExtent {
 | 
			
		||||
 | 
			
		||||
typedef struct BDRVVmdkState {
 | 
			
		||||
    CoMutex lock;
 | 
			
		||||
    int desc_offset;
 | 
			
		||||
    uint64_t desc_offset;
 | 
			
		||||
    bool cid_updated;
 | 
			
		||||
    uint32_t parent_cid;
 | 
			
		||||
    int num_extents;
 | 
			
		||||
@@ -131,7 +132,7 @@ typedef struct VmdkGrainMarker {
 | 
			
		||||
    uint64_t lba;
 | 
			
		||||
    uint32_t size;
 | 
			
		||||
    uint8_t  data[0];
 | 
			
		||||
} VmdkGrainMarker;
 | 
			
		||||
} QEMU_PACKED VmdkGrainMarker;
 | 
			
		||||
 | 
			
		||||
enum {
 | 
			
		||||
    MARKER_END_OF_STREAM    = 0,
 | 
			
		||||
@@ -385,15 +386,22 @@ static int vmdk_parent_open(BlockDriverState *bs)
 | 
			
		||||
 | 
			
		||||
/* Create and append extent to the extent array. Return the added VmdkExtent
 | 
			
		||||
 * address. return NULL if allocation failed. */
 | 
			
		||||
static VmdkExtent *vmdk_add_extent(BlockDriverState *bs,
 | 
			
		||||
static int vmdk_add_extent(BlockDriverState *bs,
 | 
			
		||||
                           BlockDriverState *file, bool flat, int64_t sectors,
 | 
			
		||||
                           int64_t l1_offset, int64_t l1_backup_offset,
 | 
			
		||||
                           uint32_t l1_size,
 | 
			
		||||
                           int l2_size, unsigned int cluster_sectors)
 | 
			
		||||
                           int l2_size, uint64_t cluster_sectors,
 | 
			
		||||
                           VmdkExtent **new_extent)
 | 
			
		||||
{
 | 
			
		||||
    VmdkExtent *extent;
 | 
			
		||||
    BDRVVmdkState *s = bs->opaque;
 | 
			
		||||
 | 
			
		||||
    if (cluster_sectors > 0x200000) {
 | 
			
		||||
        /* 0x200000 * 512Bytes = 1GB for one cluster is unrealistic */
 | 
			
		||||
        error_report("invalid granularity, image may be corrupt");
 | 
			
		||||
        return -EINVAL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    s->extents = g_realloc(s->extents,
 | 
			
		||||
                              (s->num_extents + 1) * sizeof(VmdkExtent));
 | 
			
		||||
    extent = &s->extents[s->num_extents];
 | 
			
		||||
@@ -416,7 +424,10 @@ static VmdkExtent *vmdk_add_extent(BlockDriverState *bs,
 | 
			
		||||
        extent->end_sector = extent->sectors;
 | 
			
		||||
    }
 | 
			
		||||
    bs->total_sectors = extent->end_sector;
 | 
			
		||||
    return extent;
 | 
			
		||||
    if (new_extent) {
 | 
			
		||||
        *new_extent = extent;
 | 
			
		||||
    }
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int vmdk_init_tables(BlockDriverState *bs, VmdkExtent *extent)
 | 
			
		||||
@@ -475,12 +486,17 @@ static int vmdk_open_vmdk3(BlockDriverState *bs,
 | 
			
		||||
    if (ret < 0) {
 | 
			
		||||
        return ret;
 | 
			
		||||
    }
 | 
			
		||||
    extent = vmdk_add_extent(bs,
 | 
			
		||||
 | 
			
		||||
    ret = vmdk_add_extent(bs,
 | 
			
		||||
                             bs->file, false,
 | 
			
		||||
                             le32_to_cpu(header.disk_sectors),
 | 
			
		||||
                             le32_to_cpu(header.l1dir_offset) << 9,
 | 
			
		||||
                             0, 1 << 6, 1 << 9,
 | 
			
		||||
                             le32_to_cpu(header.granularity));
 | 
			
		||||
                             le32_to_cpu(header.granularity),
 | 
			
		||||
                             &extent);
 | 
			
		||||
    if (ret < 0) {
 | 
			
		||||
        return ret;
 | 
			
		||||
    }
 | 
			
		||||
    ret = vmdk_init_tables(bs, extent);
 | 
			
		||||
    if (ret) {
 | 
			
		||||
        /* free extent allocated by vmdk_add_extent */
 | 
			
		||||
@@ -490,7 +506,7 @@ static int vmdk_open_vmdk3(BlockDriverState *bs,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int vmdk_open_desc_file(BlockDriverState *bs, int flags,
 | 
			
		||||
                               int64_t desc_offset);
 | 
			
		||||
                               uint64_t desc_offset);
 | 
			
		||||
 | 
			
		||||
static int vmdk_open_vmdk4(BlockDriverState *bs,
 | 
			
		||||
                           BlockDriverState *file,
 | 
			
		||||
@@ -508,7 +524,7 @@ static int vmdk_open_vmdk4(BlockDriverState *bs,
 | 
			
		||||
        return ret;
 | 
			
		||||
    }
 | 
			
		||||
    if (header.capacity == 0) {
 | 
			
		||||
        int64_t desc_offset = le64_to_cpu(header.desc_offset);
 | 
			
		||||
        uint64_t desc_offset = le64_to_cpu(header.desc_offset);
 | 
			
		||||
        if (desc_offset) {
 | 
			
		||||
            return vmdk_open_desc_file(bs, flags, desc_offset << 9);
 | 
			
		||||
        }
 | 
			
		||||
@@ -570,23 +586,40 @@ static int vmdk_open_vmdk4(BlockDriverState *bs,
 | 
			
		||||
        return -ENOTSUP;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    l1_entry_sectors = le32_to_cpu(header.num_gtes_per_gte)
 | 
			
		||||
    if (le32_to_cpu(header.num_gtes_per_gt) > 512) {
 | 
			
		||||
        error_report("L2 table size too big");
 | 
			
		||||
        return -EINVAL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    l1_entry_sectors = le32_to_cpu(header.num_gtes_per_gt)
 | 
			
		||||
                        * le64_to_cpu(header.granularity);
 | 
			
		||||
    if (l1_entry_sectors == 0) {
 | 
			
		||||
        return -EINVAL;
 | 
			
		||||
    }
 | 
			
		||||
    l1_size = (le64_to_cpu(header.capacity) + l1_entry_sectors - 1)
 | 
			
		||||
                / l1_entry_sectors;
 | 
			
		||||
    if (l1_size > 512 * 1024 * 1024) {
 | 
			
		||||
        /* although with big capacity and small l1_entry_sectors, we can get a
 | 
			
		||||
         * big l1_size, we don't want unbounded value to allocate the table.
 | 
			
		||||
         * Limit it to 512M, which is 16PB for default cluster and L2 table
 | 
			
		||||
         * size */
 | 
			
		||||
        error_report("L1 size too big");
 | 
			
		||||
        return -EFBIG;
 | 
			
		||||
    }
 | 
			
		||||
    if (le32_to_cpu(header.flags) & VMDK4_FLAG_RGD) {
 | 
			
		||||
        l1_backup_offset = le64_to_cpu(header.rgd_offset) << 9;
 | 
			
		||||
    }
 | 
			
		||||
    extent = vmdk_add_extent(bs, file, false,
 | 
			
		||||
    ret = vmdk_add_extent(bs, file, false,
 | 
			
		||||
                          le64_to_cpu(header.capacity),
 | 
			
		||||
                          le64_to_cpu(header.gd_offset) << 9,
 | 
			
		||||
                          l1_backup_offset,
 | 
			
		||||
                          l1_size,
 | 
			
		||||
                          le32_to_cpu(header.num_gtes_per_gte),
 | 
			
		||||
                          le64_to_cpu(header.granularity));
 | 
			
		||||
                          le32_to_cpu(header.num_gtes_per_gt),
 | 
			
		||||
                          le64_to_cpu(header.granularity),
 | 
			
		||||
                          &extent);
 | 
			
		||||
    if (ret < 0) {
 | 
			
		||||
        return ret;
 | 
			
		||||
    }
 | 
			
		||||
    extent->compressed =
 | 
			
		||||
        le16_to_cpu(header.compressAlgorithm) == VMDK4_COMPRESSION_DEFLATE;
 | 
			
		||||
    extent->has_marker = le32_to_cpu(header.flags) & VMDK4_FLAG_MARKER;
 | 
			
		||||
@@ -702,8 +735,11 @@ static int vmdk_parse_extents(const char *desc, BlockDriverState *bs,
 | 
			
		||||
            /* FLAT extent */
 | 
			
		||||
            VmdkExtent *extent;
 | 
			
		||||
 | 
			
		||||
            extent = vmdk_add_extent(bs, extent_file, true, sectors,
 | 
			
		||||
                            0, 0, 0, 0, sectors);
 | 
			
		||||
            ret = vmdk_add_extent(bs, extent_file, true, sectors,
 | 
			
		||||
                            0, 0, 0, 0, sectors, &extent);
 | 
			
		||||
            if (ret < 0) {
 | 
			
		||||
                return ret;
 | 
			
		||||
            }
 | 
			
		||||
            extent->flat_start_offset = flat_offset << 9;
 | 
			
		||||
        } else if (!strcmp(type, "SPARSE")) {
 | 
			
		||||
            /* SPARSE extent */
 | 
			
		||||
@@ -728,7 +764,7 @@ next_line:
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int vmdk_open_desc_file(BlockDriverState *bs, int flags,
 | 
			
		||||
                               int64_t desc_offset)
 | 
			
		||||
                               uint64_t desc_offset)
 | 
			
		||||
{
 | 
			
		||||
    int ret;
 | 
			
		||||
    char *buf = NULL;
 | 
			
		||||
@@ -807,16 +843,17 @@ static int get_whole_cluster(BlockDriverState *bs,
 | 
			
		||||
                uint64_t offset,
 | 
			
		||||
                bool allocate)
 | 
			
		||||
{
 | 
			
		||||
    /* 128 sectors * 512 bytes each = grain size 64KB */
 | 
			
		||||
    uint8_t  whole_grain[extent->cluster_sectors * 512];
 | 
			
		||||
    int ret = VMDK_OK;
 | 
			
		||||
    uint8_t *whole_grain = NULL;
 | 
			
		||||
 | 
			
		||||
    /* we will be here if it's first write on non-exist grain(cluster).
 | 
			
		||||
     * try to read from parent image, if exist */
 | 
			
		||||
    if (bs->backing_hd) {
 | 
			
		||||
        int ret;
 | 
			
		||||
 | 
			
		||||
        whole_grain =
 | 
			
		||||
            qemu_blockalign(bs, extent->cluster_sectors << BDRV_SECTOR_BITS);
 | 
			
		||||
        if (!vmdk_is_cid_valid(bs)) {
 | 
			
		||||
            return VMDK_ERROR;
 | 
			
		||||
            ret = VMDK_ERROR;
 | 
			
		||||
            goto exit;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /* floor offset to cluster */
 | 
			
		||||
@@ -824,17 +861,21 @@ static int get_whole_cluster(BlockDriverState *bs,
 | 
			
		||||
        ret = bdrv_read(bs->backing_hd, offset >> 9, whole_grain,
 | 
			
		||||
                extent->cluster_sectors);
 | 
			
		||||
        if (ret < 0) {
 | 
			
		||||
            return VMDK_ERROR;
 | 
			
		||||
            ret = VMDK_ERROR;
 | 
			
		||||
            goto exit;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /* Write grain only into the active image */
 | 
			
		||||
        ret = bdrv_write(extent->file, cluster_offset, whole_grain,
 | 
			
		||||
                extent->cluster_sectors);
 | 
			
		||||
        if (ret < 0) {
 | 
			
		||||
            return VMDK_ERROR;
 | 
			
		||||
            ret = VMDK_ERROR;
 | 
			
		||||
            goto exit;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    return VMDK_OK;
 | 
			
		||||
exit:
 | 
			
		||||
    qemu_vfree(whole_grain);
 | 
			
		||||
    return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int vmdk_L2update(VmdkExtent *extent, VmdkMetaData *m_data)
 | 
			
		||||
@@ -1200,8 +1241,10 @@ static coroutine_fn int vmdk_co_read(BlockDriverState *bs, int64_t sector_num,
 | 
			
		||||
/**
 | 
			
		||||
 * vmdk_write:
 | 
			
		||||
 * @zeroed:       buf is ignored (data is zero), use zeroed_grain GTE feature
 | 
			
		||||
 * if possible, otherwise return -ENOTSUP.
 | 
			
		||||
 * @zero_dry_run: used for zeroed == true only, don't update L2 table, just
 | 
			
		||||
 *                if possible, otherwise return -ENOTSUP.
 | 
			
		||||
 * @zero_dry_run: used for zeroed == true only, don't update L2 table, just try
 | 
			
		||||
 *                with each cluster. By dry run we can find if the zero write
 | 
			
		||||
 *                is possible without modifying image data.
 | 
			
		||||
 *
 | 
			
		||||
 * Returns: error code with 0 for success.
 | 
			
		||||
 */
 | 
			
		||||
@@ -1328,6 +1371,8 @@ static int coroutine_fn vmdk_co_write_zeroes(BlockDriverState *bs,
 | 
			
		||||
    int ret;
 | 
			
		||||
    BDRVVmdkState *s = bs->opaque;
 | 
			
		||||
    qemu_co_mutex_lock(&s->lock);
 | 
			
		||||
    /* write zeroes could fail if sectors not aligned to cluster, test it with
 | 
			
		||||
     * dry_run == true before really updating image */
 | 
			
		||||
    ret = vmdk_write(bs, sector_num, NULL, nb_sectors, true, true);
 | 
			
		||||
    if (!ret) {
 | 
			
		||||
        ret = vmdk_write(bs, sector_num, NULL, nb_sectors, true, false);
 | 
			
		||||
@@ -1367,12 +1412,12 @@ static int vmdk_create_extent(const char *filename, int64_t filesize,
 | 
			
		||||
    header.compressAlgorithm = compress ? VMDK4_COMPRESSION_DEFLATE : 0;
 | 
			
		||||
    header.capacity = filesize / 512;
 | 
			
		||||
    header.granularity = 128;
 | 
			
		||||
    header.num_gtes_per_gte = 512;
 | 
			
		||||
    header.num_gtes_per_gt = 512;
 | 
			
		||||
 | 
			
		||||
    grains = (filesize / 512 + header.granularity - 1) / header.granularity;
 | 
			
		||||
    gt_size = ((header.num_gtes_per_gte * sizeof(uint32_t)) + 511) >> 9;
 | 
			
		||||
    gt_size = ((header.num_gtes_per_gt * sizeof(uint32_t)) + 511) >> 9;
 | 
			
		||||
    gt_count =
 | 
			
		||||
        (grains + header.num_gtes_per_gte - 1) / header.num_gtes_per_gte;
 | 
			
		||||
        (grains + header.num_gtes_per_gt - 1) / header.num_gtes_per_gt;
 | 
			
		||||
    gd_size = (gt_count * sizeof(uint32_t) + 511) >> 9;
 | 
			
		||||
 | 
			
		||||
    header.desc_offset = 1;
 | 
			
		||||
@@ -1388,7 +1433,7 @@ static int vmdk_create_extent(const char *filename, int64_t filesize,
 | 
			
		||||
    header.flags = cpu_to_le32(header.flags);
 | 
			
		||||
    header.capacity = cpu_to_le64(header.capacity);
 | 
			
		||||
    header.granularity = cpu_to_le64(header.granularity);
 | 
			
		||||
    header.num_gtes_per_gte = cpu_to_le32(header.num_gtes_per_gte);
 | 
			
		||||
    header.num_gtes_per_gt = cpu_to_le32(header.num_gtes_per_gt);
 | 
			
		||||
    header.desc_offset = cpu_to_le64(header.desc_offset);
 | 
			
		||||
    header.desc_size = cpu_to_le64(header.desc_size);
 | 
			
		||||
    header.rgd_offset = cpu_to_le64(header.rgd_offset);
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										156
									
								
								blockdev.c
									
									
									
									
									
								
							
							
						
						
									
										156
									
								
								blockdev.c
									
									
									
									
									
								
							@@ -46,6 +46,7 @@
 | 
			
		||||
 | 
			
		||||
static QTAILQ_HEAD(drivelist, DriveInfo) drives = QTAILQ_HEAD_INITIALIZER(drives);
 | 
			
		||||
extern QemuOptsList qemu_common_drive_opts;
 | 
			
		||||
extern QemuOptsList qemu_old_drive_opts;
 | 
			
		||||
 | 
			
		||||
static const char *const if_name[IF_COUNT] = {
 | 
			
		||||
    [IF_NONE] = "none",
 | 
			
		||||
@@ -339,6 +340,7 @@ static DriveInfo *blockdev_init(QemuOpts *all_opts,
 | 
			
		||||
    QDict *bs_opts;
 | 
			
		||||
    const char *id;
 | 
			
		||||
    bool has_driver_specific_opts;
 | 
			
		||||
    BlockDriver *drv = NULL;
 | 
			
		||||
 | 
			
		||||
    translation = BIOS_ATA_TRANSLATION_AUTO;
 | 
			
		||||
    media = MEDIA_DISK;
 | 
			
		||||
@@ -452,7 +454,6 @@ static DriveInfo *blockdev_init(QemuOpts *all_opts,
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bdrv_flags = 0;
 | 
			
		||||
    if (qemu_opt_get_bool(opts, "cache.writeback", true)) {
 | 
			
		||||
        bdrv_flags |= BDRV_O_CACHE_WB;
 | 
			
		||||
    }
 | 
			
		||||
@@ -484,7 +485,11 @@ static DriveInfo *blockdev_init(QemuOpts *all_opts,
 | 
			
		||||
            return NULL;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        qdict_put(bs_opts, "driver", qstring_from_str(buf));
 | 
			
		||||
        drv = bdrv_find_whitelisted_format(buf, ro);
 | 
			
		||||
        if (!drv) {
 | 
			
		||||
            error_report("'%s' invalid format", buf);
 | 
			
		||||
            return NULL;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* disk I/O throttling */
 | 
			
		||||
@@ -699,12 +704,13 @@ static DriveInfo *blockdev_init(QemuOpts *all_opts,
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    QINCREF(bs_opts);
 | 
			
		||||
    ret = bdrv_open(dinfo->bdrv, file, bs_opts, bdrv_flags, NULL);
 | 
			
		||||
    ret = bdrv_open(dinfo->bdrv, file, bs_opts, bdrv_flags, drv);
 | 
			
		||||
 | 
			
		||||
    if (ret < 0) {
 | 
			
		||||
        if (ret == -EMEDIUMTYPE) {
 | 
			
		||||
            error_report("could not open disk image %s: not in %s format",
 | 
			
		||||
                         file ?: dinfo->id, qdict_get_str(bs_opts, "driver"));
 | 
			
		||||
                         file ?: dinfo->id, drv ? drv->format_name :
 | 
			
		||||
                         qdict_get_str(bs_opts, "driver"));
 | 
			
		||||
        } else {
 | 
			
		||||
            error_report("could not open disk image %s: %s",
 | 
			
		||||
                         file ?: dinfo->id, strerror(-ret));
 | 
			
		||||
@@ -745,6 +751,26 @@ DriveInfo *drive_init(QemuOpts *all_opts, BlockInterfaceType block_default_type)
 | 
			
		||||
{
 | 
			
		||||
    const char *value;
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
     * Check that only old options are used by copying into a QemuOpts with
 | 
			
		||||
     * stricter checks. Going through a QDict seems to be the easiest way to
 | 
			
		||||
     * achieve this...
 | 
			
		||||
     */
 | 
			
		||||
    QemuOpts* check_opts;
 | 
			
		||||
    QDict *qdict;
 | 
			
		||||
    Error *local_err = NULL;
 | 
			
		||||
 | 
			
		||||
    qdict = qemu_opts_to_qdict(all_opts, NULL);
 | 
			
		||||
    check_opts = qemu_opts_from_qdict(&qemu_old_drive_opts, qdict, &local_err);
 | 
			
		||||
    QDECREF(qdict);
 | 
			
		||||
 | 
			
		||||
    if (error_is_set(&local_err)) {
 | 
			
		||||
        qerror_report_err(local_err);
 | 
			
		||||
        error_free(local_err);
 | 
			
		||||
        return NULL;
 | 
			
		||||
    }
 | 
			
		||||
    qemu_opts_del(check_opts);
 | 
			
		||||
 | 
			
		||||
    /* Change legacy command line options into QMP ones */
 | 
			
		||||
    qemu_opt_rename(all_opts, "iops", "throttling.iops-total");
 | 
			
		||||
    qemu_opt_rename(all_opts, "iops_rd", "throttling.iops-read");
 | 
			
		||||
@@ -1971,6 +1997,128 @@ QemuOptsList qemu_common_drive_opts = {
 | 
			
		||||
    },
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
QemuOptsList qemu_old_drive_opts = {
 | 
			
		||||
    .name = "drive",
 | 
			
		||||
    .head = QTAILQ_HEAD_INITIALIZER(qemu_old_drive_opts.head),
 | 
			
		||||
    .desc = {
 | 
			
		||||
        {
 | 
			
		||||
            .name = "bus",
 | 
			
		||||
            .type = QEMU_OPT_NUMBER,
 | 
			
		||||
            .help = "bus number",
 | 
			
		||||
        },{
 | 
			
		||||
            .name = "unit",
 | 
			
		||||
            .type = QEMU_OPT_NUMBER,
 | 
			
		||||
            .help = "unit number (i.e. lun for scsi)",
 | 
			
		||||
        },{
 | 
			
		||||
            .name = "if",
 | 
			
		||||
            .type = QEMU_OPT_STRING,
 | 
			
		||||
            .help = "interface (ide, scsi, sd, mtd, floppy, pflash, virtio)",
 | 
			
		||||
        },{
 | 
			
		||||
            .name = "index",
 | 
			
		||||
            .type = QEMU_OPT_NUMBER,
 | 
			
		||||
            .help = "index number",
 | 
			
		||||
        },{
 | 
			
		||||
            .name = "cyls",
 | 
			
		||||
            .type = QEMU_OPT_NUMBER,
 | 
			
		||||
            .help = "number of cylinders (ide disk geometry)",
 | 
			
		||||
        },{
 | 
			
		||||
            .name = "heads",
 | 
			
		||||
            .type = QEMU_OPT_NUMBER,
 | 
			
		||||
            .help = "number of heads (ide disk geometry)",
 | 
			
		||||
        },{
 | 
			
		||||
            .name = "secs",
 | 
			
		||||
            .type = QEMU_OPT_NUMBER,
 | 
			
		||||
            .help = "number of sectors (ide disk geometry)",
 | 
			
		||||
        },{
 | 
			
		||||
            .name = "trans",
 | 
			
		||||
            .type = QEMU_OPT_STRING,
 | 
			
		||||
            .help = "chs translation (auto, lba. none)",
 | 
			
		||||
        },{
 | 
			
		||||
            .name = "media",
 | 
			
		||||
            .type = QEMU_OPT_STRING,
 | 
			
		||||
            .help = "media type (disk, cdrom)",
 | 
			
		||||
        },{
 | 
			
		||||
            .name = "snapshot",
 | 
			
		||||
            .type = QEMU_OPT_BOOL,
 | 
			
		||||
            .help = "enable/disable snapshot mode",
 | 
			
		||||
        },{
 | 
			
		||||
            .name = "file",
 | 
			
		||||
            .type = QEMU_OPT_STRING,
 | 
			
		||||
            .help = "disk image",
 | 
			
		||||
        },{
 | 
			
		||||
            .name = "discard",
 | 
			
		||||
            .type = QEMU_OPT_STRING,
 | 
			
		||||
            .help = "discard operation (ignore/off, unmap/on)",
 | 
			
		||||
        },{
 | 
			
		||||
            .name = "cache",
 | 
			
		||||
            .type = QEMU_OPT_STRING,
 | 
			
		||||
            .help = "host cache usage (none, writeback, writethrough, "
 | 
			
		||||
                    "directsync, unsafe)",
 | 
			
		||||
        },{
 | 
			
		||||
            .name = "aio",
 | 
			
		||||
            .type = QEMU_OPT_STRING,
 | 
			
		||||
            .help = "host AIO implementation (threads, native)",
 | 
			
		||||
        },{
 | 
			
		||||
            .name = "format",
 | 
			
		||||
            .type = QEMU_OPT_STRING,
 | 
			
		||||
            .help = "disk format (raw, qcow2, ...)",
 | 
			
		||||
        },{
 | 
			
		||||
            .name = "serial",
 | 
			
		||||
            .type = QEMU_OPT_STRING,
 | 
			
		||||
            .help = "disk serial number",
 | 
			
		||||
        },{
 | 
			
		||||
            .name = "rerror",
 | 
			
		||||
            .type = QEMU_OPT_STRING,
 | 
			
		||||
            .help = "read error action",
 | 
			
		||||
        },{
 | 
			
		||||
            .name = "werror",
 | 
			
		||||
            .type = QEMU_OPT_STRING,
 | 
			
		||||
            .help = "write error action",
 | 
			
		||||
        },{
 | 
			
		||||
            .name = "addr",
 | 
			
		||||
            .type = QEMU_OPT_STRING,
 | 
			
		||||
            .help = "pci address (virtio only)",
 | 
			
		||||
        },{
 | 
			
		||||
            .name = "readonly",
 | 
			
		||||
            .type = QEMU_OPT_BOOL,
 | 
			
		||||
            .help = "open drive file as read-only",
 | 
			
		||||
        },{
 | 
			
		||||
            .name = "iops",
 | 
			
		||||
            .type = QEMU_OPT_NUMBER,
 | 
			
		||||
            .help = "limit total I/O operations per second",
 | 
			
		||||
        },{
 | 
			
		||||
            .name = "iops_rd",
 | 
			
		||||
            .type = QEMU_OPT_NUMBER,
 | 
			
		||||
            .help = "limit read operations per second",
 | 
			
		||||
        },{
 | 
			
		||||
            .name = "iops_wr",
 | 
			
		||||
            .type = QEMU_OPT_NUMBER,
 | 
			
		||||
            .help = "limit write operations per second",
 | 
			
		||||
        },{
 | 
			
		||||
            .name = "bps",
 | 
			
		||||
            .type = QEMU_OPT_NUMBER,
 | 
			
		||||
            .help = "limit total bytes per second",
 | 
			
		||||
        },{
 | 
			
		||||
            .name = "bps_rd",
 | 
			
		||||
            .type = QEMU_OPT_NUMBER,
 | 
			
		||||
            .help = "limit read bytes per second",
 | 
			
		||||
        },{
 | 
			
		||||
            .name = "bps_wr",
 | 
			
		||||
            .type = QEMU_OPT_NUMBER,
 | 
			
		||||
            .help = "limit write bytes per second",
 | 
			
		||||
        },{
 | 
			
		||||
            .name = "copy-on-read",
 | 
			
		||||
            .type = QEMU_OPT_BOOL,
 | 
			
		||||
            .help = "copy read data from backing file into image file",
 | 
			
		||||
        },{
 | 
			
		||||
            .name = "boot",
 | 
			
		||||
            .type = QEMU_OPT_BOOL,
 | 
			
		||||
            .help = "(deprecated, ignored)",
 | 
			
		||||
        },
 | 
			
		||||
        { /* end of list */ }
 | 
			
		||||
    },
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
QemuOptsList qemu_drive_opts = {
 | 
			
		||||
    .name = "drive",
 | 
			
		||||
    .head = QTAILQ_HEAD_INITIALIZER(qemu_drive_opts.head),
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										15
									
								
								configure
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										15
									
								
								configure
									
									
									
									
										vendored
									
									
								
							@@ -231,7 +231,7 @@ libusb=""
 | 
			
		||||
usb_redir=""
 | 
			
		||||
glx=""
 | 
			
		||||
zlib="yes"
 | 
			
		||||
guest_agent="yes"
 | 
			
		||||
guest_agent=""
 | 
			
		||||
want_tools="yes"
 | 
			
		||||
libiscsi=""
 | 
			
		||||
coroutine=""
 | 
			
		||||
@@ -3444,10 +3444,15 @@ if test "$softmmu" = yes ; then
 | 
			
		||||
      virtfs=no
 | 
			
		||||
    fi
 | 
			
		||||
  fi
 | 
			
		||||
fi
 | 
			
		||||
if [ "$guest_agent" != "no" ]; then
 | 
			
		||||
  if [ "$linux" = "yes" -o "$bsd" = "yes" -o "$solaris" = "yes" ] ; then
 | 
			
		||||
    if [ "$guest_agent" = "yes" ]; then
 | 
			
		||||
      tools="qemu-ga\$(EXESUF) $tools"
 | 
			
		||||
    fi
 | 
			
		||||
      guest_agent=yes
 | 
			
		||||
  elif [ "$guest_agent" != yes ]; then
 | 
			
		||||
      guest_agent=no
 | 
			
		||||
  else
 | 
			
		||||
      error_exit "Guest agent is not supported on this platform"
 | 
			
		||||
  fi
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
@@ -4502,13 +4507,13 @@ if [ "$dtc_internal" = "yes" ]; then
 | 
			
		||||
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 tests/libqos tests/qapi-schema"
 | 
			
		||||
DIRS="tests tests/tcg tests/tcg/cris tests/tcg/lm32 tests/libqos tests/qapi-schema tests/tcg/xtensa"
 | 
			
		||||
DIRS="$DIRS pc-bios/optionrom pc-bios/spapr-rtas pc-bios/s390-ccw"
 | 
			
		||||
DIRS="$DIRS roms/seabios roms/vgabios"
 | 
			
		||||
DIRS="$DIRS qapi-generated"
 | 
			
		||||
FILES="Makefile tests/tcg/Makefile qdict-test-data.txt"
 | 
			
		||||
FILES="$FILES tests/tcg/cris/Makefile tests/tcg/cris/.gdbinit"
 | 
			
		||||
FILES="$FILES tests/tcg/lm32/Makefile po/Makefile"
 | 
			
		||||
FILES="$FILES tests/tcg/lm32/Makefile tests/tcg/xtensa/Makefile po/Makefile"
 | 
			
		||||
FILES="$FILES pc-bios/optionrom/Makefile pc-bios/keymaps"
 | 
			
		||||
FILES="$FILES pc-bios/spapr-rtas/Makefile"
 | 
			
		||||
FILES="$FILES pc-bios/s390-ccw/Makefile"
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										14
									
								
								cpus.c
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								cpus.c
									
									
									
									
									
								
							@@ -62,12 +62,17 @@
 | 
			
		||||
 | 
			
		||||
static CPUState *next_cpu;
 | 
			
		||||
 | 
			
		||||
bool cpu_is_stopped(CPUState *cpu)
 | 
			
		||||
{
 | 
			
		||||
    return cpu->stopped || !runstate_is_running();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static bool cpu_thread_is_idle(CPUState *cpu)
 | 
			
		||||
{
 | 
			
		||||
    if (cpu->stop || cpu->queued_work_first) {
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
    if (cpu->stopped || !runstate_is_running()) {
 | 
			
		||||
    if (cpu_is_stopped(cpu)) {
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
    if (!cpu->halted || qemu_cpu_has_work(cpu) ||
 | 
			
		||||
@@ -429,11 +434,6 @@ void cpu_synchronize_all_post_init(void)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool cpu_is_stopped(CPUState *cpu)
 | 
			
		||||
{
 | 
			
		||||
    return !runstate_is_running() || cpu->stopped;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int do_vm_stop(RunState state)
 | 
			
		||||
{
 | 
			
		||||
    int ret = 0;
 | 
			
		||||
@@ -457,7 +457,7 @@ static bool cpu_can_run(CPUState *cpu)
 | 
			
		||||
    if (cpu->stop) {
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
    if (cpu->stopped || !runstate_is_running()) {
 | 
			
		||||
    if (cpu_is_stopped(cpu)) {
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
    return true;
 | 
			
		||||
 
 | 
			
		||||
@@ -34,9 +34,9 @@ CONFIG_PFLASH_CFI02=y
 | 
			
		||||
CONFIG_MICRODRIVE=y
 | 
			
		||||
CONFIG_USB_MUSB=y
 | 
			
		||||
 | 
			
		||||
CONFIG_ARM9MPCORE=y
 | 
			
		||||
CONFIG_ARM11MPCORE=y
 | 
			
		||||
CONFIG_ARM15MPCORE=y
 | 
			
		||||
CONFIG_A9MPCORE=y
 | 
			
		||||
CONFIG_A15MPCORE=y
 | 
			
		||||
 | 
			
		||||
CONFIG_ARM_GIC=y
 | 
			
		||||
CONFIG_ARM_GIC_KVM=$(CONFIG_KVM)
 | 
			
		||||
 
 | 
			
		||||
@@ -33,7 +33,6 @@ CONFIG_MC146818RTC=y
 | 
			
		||||
CONFIG_PAM=y
 | 
			
		||||
CONFIG_PCI_PIIX=y
 | 
			
		||||
CONFIG_WDT_IB700=y
 | 
			
		||||
CONFIG_PC_SYSFW=y
 | 
			
		||||
CONFIG_XEN_I386=$(CONFIG_XEN)
 | 
			
		||||
CONFIG_ISA_DEBUG=y
 | 
			
		||||
CONFIG_ISA_TESTDEV=y
 | 
			
		||||
 
 | 
			
		||||
@@ -34,3 +34,4 @@ CONFIG_JAZZ_LED=y
 | 
			
		||||
CONFIG_MC146818RTC=y
 | 
			
		||||
CONFIG_VT82C686=y
 | 
			
		||||
CONFIG_ISA_TESTDEV=y
 | 
			
		||||
CONFIG_EMPTY_SLOT=y
 | 
			
		||||
 
 | 
			
		||||
@@ -34,3 +34,4 @@ CONFIG_JAZZ_LED=y
 | 
			
		||||
CONFIG_MC146818RTC=y
 | 
			
		||||
CONFIG_VT82C686=y
 | 
			
		||||
CONFIG_ISA_TESTDEV=y
 | 
			
		||||
CONFIG_EMPTY_SLOT=y
 | 
			
		||||
 
 | 
			
		||||
@@ -36,3 +36,4 @@ CONFIG_JAZZ_LED=y
 | 
			
		||||
CONFIG_MC146818RTC=y
 | 
			
		||||
CONFIG_VT82C686=y
 | 
			
		||||
CONFIG_ISA_TESTDEV=y
 | 
			
		||||
CONFIG_EMPTY_SLOT=y
 | 
			
		||||
 
 | 
			
		||||
@@ -34,3 +34,4 @@ CONFIG_JAZZ_LED=y
 | 
			
		||||
CONFIG_MC146818RTC=y
 | 
			
		||||
CONFIG_VT82C686=y
 | 
			
		||||
CONFIG_ISA_TESTDEV=y
 | 
			
		||||
CONFIG_EMPTY_SLOT=y
 | 
			
		||||
 
 | 
			
		||||
@@ -33,7 +33,6 @@ CONFIG_MC146818RTC=y
 | 
			
		||||
CONFIG_PAM=y
 | 
			
		||||
CONFIG_PCI_PIIX=y
 | 
			
		||||
CONFIG_WDT_IB700=y
 | 
			
		||||
CONFIG_PC_SYSFW=y
 | 
			
		||||
CONFIG_XEN_I386=$(CONFIG_XEN)
 | 
			
		||||
CONFIG_ISA_DEBUG=y
 | 
			
		||||
CONFIG_ISA_TESTDEV=y
 | 
			
		||||
 
 | 
			
		||||
@@ -91,6 +91,29 @@
 | 
			
		||||
  port = "4"
 | 
			
		||||
  chassis = "4"
 | 
			
		||||
 | 
			
		||||
##
 | 
			
		||||
# Example PCIe switch with two downstream ports
 | 
			
		||||
#
 | 
			
		||||
#[device "pcie-switch-upstream-port-1"]
 | 
			
		||||
#  driver = "x3130-upstream"
 | 
			
		||||
#  bus = "ich9-pcie-port-4"
 | 
			
		||||
#  addr = "00.0"
 | 
			
		||||
#
 | 
			
		||||
#[device "pcie-switch-downstream-port-1-1"]
 | 
			
		||||
#  driver = "xio3130-downstream"
 | 
			
		||||
#  multifunction = "on"
 | 
			
		||||
#  bus = "pcie-switch-upstream-port-1"
 | 
			
		||||
#  addr = "00.0"
 | 
			
		||||
#  port = "1"
 | 
			
		||||
#  chassis = "5"
 | 
			
		||||
#
 | 
			
		||||
#[device "pcie-switch-downstream-port-1-2"]
 | 
			
		||||
#  driver = "xio3130-downstream"
 | 
			
		||||
#  multifunction = "on"
 | 
			
		||||
#  bus = "pcie-switch-upstream-port-1"
 | 
			
		||||
#  addr = "00.1"
 | 
			
		||||
#  port = "1"
 | 
			
		||||
#  chassis = "6"
 | 
			
		||||
 | 
			
		||||
[device "ich9-ehci-1"]
 | 
			
		||||
  driver = "ich9-usb-ehci1"
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										185
									
								
								dump.c
									
									
									
									
									
								
							
							
						
						
									
										185
									
								
								dump.c
									
									
									
									
									
								
							@@ -59,6 +59,7 @@ static uint64_t cpu_convert_to_target64(uint64_t val, int endian)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
typedef struct DumpState {
 | 
			
		||||
    GuestPhysBlockList guest_phys_blocks;
 | 
			
		||||
    ArchDumpInfo dump_info;
 | 
			
		||||
    MemoryMappingList list;
 | 
			
		||||
    uint16_t phdr_num;
 | 
			
		||||
@@ -69,7 +70,7 @@ typedef struct DumpState {
 | 
			
		||||
    hwaddr memory_offset;
 | 
			
		||||
    int fd;
 | 
			
		||||
 | 
			
		||||
    RAMBlock *block;
 | 
			
		||||
    GuestPhysBlock *next_block;
 | 
			
		||||
    ram_addr_t start;
 | 
			
		||||
    bool has_filter;
 | 
			
		||||
    int64_t begin;
 | 
			
		||||
@@ -81,6 +82,7 @@ static int dump_cleanup(DumpState *s)
 | 
			
		||||
{
 | 
			
		||||
    int ret = 0;
 | 
			
		||||
 | 
			
		||||
    guest_phys_blocks_free(&s->guest_phys_blocks);
 | 
			
		||||
    memory_mapping_list_free(&s->list);
 | 
			
		||||
    if (s->fd != -1) {
 | 
			
		||||
        close(s->fd);
 | 
			
		||||
@@ -187,7 +189,8 @@ static int write_elf32_header(DumpState *s)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int write_elf64_load(DumpState *s, MemoryMapping *memory_mapping,
 | 
			
		||||
                            int phdr_index, hwaddr offset)
 | 
			
		||||
                            int phdr_index, hwaddr offset,
 | 
			
		||||
                            hwaddr filesz)
 | 
			
		||||
{
 | 
			
		||||
    Elf64_Phdr phdr;
 | 
			
		||||
    int ret;
 | 
			
		||||
@@ -197,15 +200,12 @@ static int write_elf64_load(DumpState *s, MemoryMapping *memory_mapping,
 | 
			
		||||
    phdr.p_type = cpu_convert_to_target32(PT_LOAD, endian);
 | 
			
		||||
    phdr.p_offset = cpu_convert_to_target64(offset, endian);
 | 
			
		||||
    phdr.p_paddr = cpu_convert_to_target64(memory_mapping->phys_addr, endian);
 | 
			
		||||
    if (offset == -1) {
 | 
			
		||||
        /* When the memory is not stored into vmcore, offset will be -1 */
 | 
			
		||||
        phdr.p_filesz = 0;
 | 
			
		||||
    } else {
 | 
			
		||||
        phdr.p_filesz = cpu_convert_to_target64(memory_mapping->length, endian);
 | 
			
		||||
    }
 | 
			
		||||
    phdr.p_filesz = cpu_convert_to_target64(filesz, endian);
 | 
			
		||||
    phdr.p_memsz = cpu_convert_to_target64(memory_mapping->length, endian);
 | 
			
		||||
    phdr.p_vaddr = cpu_convert_to_target64(memory_mapping->virt_addr, endian);
 | 
			
		||||
 | 
			
		||||
    assert(memory_mapping->length >= filesz);
 | 
			
		||||
 | 
			
		||||
    ret = fd_write_vmcore(&phdr, sizeof(Elf64_Phdr), s);
 | 
			
		||||
    if (ret < 0) {
 | 
			
		||||
        dump_error(s, "dump: failed to write program header table.\n");
 | 
			
		||||
@@ -216,7 +216,8 @@ static int write_elf64_load(DumpState *s, MemoryMapping *memory_mapping,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int write_elf32_load(DumpState *s, MemoryMapping *memory_mapping,
 | 
			
		||||
                            int phdr_index, hwaddr offset)
 | 
			
		||||
                            int phdr_index, hwaddr offset,
 | 
			
		||||
                            hwaddr filesz)
 | 
			
		||||
{
 | 
			
		||||
    Elf32_Phdr phdr;
 | 
			
		||||
    int ret;
 | 
			
		||||
@@ -226,15 +227,12 @@ static int write_elf32_load(DumpState *s, MemoryMapping *memory_mapping,
 | 
			
		||||
    phdr.p_type = cpu_convert_to_target32(PT_LOAD, endian);
 | 
			
		||||
    phdr.p_offset = cpu_convert_to_target32(offset, endian);
 | 
			
		||||
    phdr.p_paddr = cpu_convert_to_target32(memory_mapping->phys_addr, endian);
 | 
			
		||||
    if (offset == -1) {
 | 
			
		||||
        /* When the memory is not stored into vmcore, offset will be -1 */
 | 
			
		||||
        phdr.p_filesz = 0;
 | 
			
		||||
    } else {
 | 
			
		||||
        phdr.p_filesz = cpu_convert_to_target32(memory_mapping->length, endian);
 | 
			
		||||
    }
 | 
			
		||||
    phdr.p_filesz = cpu_convert_to_target32(filesz, endian);
 | 
			
		||||
    phdr.p_memsz = cpu_convert_to_target32(memory_mapping->length, endian);
 | 
			
		||||
    phdr.p_vaddr = cpu_convert_to_target32(memory_mapping->virt_addr, endian);
 | 
			
		||||
 | 
			
		||||
    assert(memory_mapping->length >= filesz);
 | 
			
		||||
 | 
			
		||||
    ret = fd_write_vmcore(&phdr, sizeof(Elf32_Phdr), s);
 | 
			
		||||
    if (ret < 0) {
 | 
			
		||||
        dump_error(s, "dump: failed to write program header table.\n");
 | 
			
		||||
@@ -393,14 +391,14 @@ static int write_data(DumpState *s, void *buf, int length)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* write the memroy to vmcore. 1 page per I/O. */
 | 
			
		||||
static int write_memory(DumpState *s, RAMBlock *block, ram_addr_t start,
 | 
			
		||||
static int write_memory(DumpState *s, GuestPhysBlock *block, ram_addr_t start,
 | 
			
		||||
                        int64_t size)
 | 
			
		||||
{
 | 
			
		||||
    int64_t i;
 | 
			
		||||
    int ret;
 | 
			
		||||
 | 
			
		||||
    for (i = 0; i < size / TARGET_PAGE_SIZE; i++) {
 | 
			
		||||
        ret = write_data(s, block->host + start + i * TARGET_PAGE_SIZE,
 | 
			
		||||
        ret = write_data(s, block->host_addr + start + i * TARGET_PAGE_SIZE,
 | 
			
		||||
                         TARGET_PAGE_SIZE);
 | 
			
		||||
        if (ret < 0) {
 | 
			
		||||
            return ret;
 | 
			
		||||
@@ -408,7 +406,7 @@ static int write_memory(DumpState *s, RAMBlock *block, ram_addr_t start,
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if ((size % TARGET_PAGE_SIZE) != 0) {
 | 
			
		||||
        ret = write_data(s, block->host + start + i * TARGET_PAGE_SIZE,
 | 
			
		||||
        ret = write_data(s, block->host_addr + start + i * TARGET_PAGE_SIZE,
 | 
			
		||||
                         size % TARGET_PAGE_SIZE);
 | 
			
		||||
        if (ret < 0) {
 | 
			
		||||
            return ret;
 | 
			
		||||
@@ -418,57 +416,71 @@ static int write_memory(DumpState *s, RAMBlock *block, ram_addr_t start,
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* get the memory's offset in the vmcore */
 | 
			
		||||
static hwaddr get_offset(hwaddr phys_addr,
 | 
			
		||||
                                     DumpState *s)
 | 
			
		||||
/* get the memory's offset and size in the vmcore */
 | 
			
		||||
static void get_offset_range(hwaddr phys_addr,
 | 
			
		||||
                             ram_addr_t mapping_length,
 | 
			
		||||
                             DumpState *s,
 | 
			
		||||
                             hwaddr *p_offset,
 | 
			
		||||
                             hwaddr *p_filesz)
 | 
			
		||||
{
 | 
			
		||||
    RAMBlock *block;
 | 
			
		||||
    GuestPhysBlock *block;
 | 
			
		||||
    hwaddr offset = s->memory_offset;
 | 
			
		||||
    int64_t size_in_block, start;
 | 
			
		||||
 | 
			
		||||
    /* When the memory is not stored into vmcore, offset will be -1 */
 | 
			
		||||
    *p_offset = -1;
 | 
			
		||||
    *p_filesz = 0;
 | 
			
		||||
 | 
			
		||||
    if (s->has_filter) {
 | 
			
		||||
        if (phys_addr < s->begin || phys_addr >= s->begin + s->length) {
 | 
			
		||||
            return -1;
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    QTAILQ_FOREACH(block, &ram_list.blocks, next) {
 | 
			
		||||
    QTAILQ_FOREACH(block, &s->guest_phys_blocks.head, next) {
 | 
			
		||||
        if (s->has_filter) {
 | 
			
		||||
            if (block->offset >= s->begin + s->length ||
 | 
			
		||||
                block->offset + block->length <= s->begin) {
 | 
			
		||||
            if (block->target_start >= s->begin + s->length ||
 | 
			
		||||
                block->target_end <= s->begin) {
 | 
			
		||||
                /* This block is out of the range */
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (s->begin <= block->offset) {
 | 
			
		||||
                start = block->offset;
 | 
			
		||||
            if (s->begin <= block->target_start) {
 | 
			
		||||
                start = block->target_start;
 | 
			
		||||
            } else {
 | 
			
		||||
                start = s->begin;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            size_in_block = block->length - (start - block->offset);
 | 
			
		||||
            if (s->begin + s->length < block->offset + block->length) {
 | 
			
		||||
                size_in_block -= block->offset + block->length -
 | 
			
		||||
                                 (s->begin + s->length);
 | 
			
		||||
            size_in_block = block->target_end - start;
 | 
			
		||||
            if (s->begin + s->length < block->target_end) {
 | 
			
		||||
                size_in_block -= block->target_end - (s->begin + s->length);
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
            start = block->offset;
 | 
			
		||||
            size_in_block = block->length;
 | 
			
		||||
            start = block->target_start;
 | 
			
		||||
            size_in_block = block->target_end - block->target_start;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (phys_addr >= start && phys_addr < start + size_in_block) {
 | 
			
		||||
            return phys_addr - start + offset;
 | 
			
		||||
            *p_offset = phys_addr - start + offset;
 | 
			
		||||
 | 
			
		||||
            /* The offset range mapped from the vmcore file must not spill over
 | 
			
		||||
             * the GuestPhysBlock, clamp it. The rest of the mapping will be
 | 
			
		||||
             * zero-filled in memory at load time; see
 | 
			
		||||
             * <http://refspecs.linuxbase.org/elf/gabi4+/ch5.pheader.html>.
 | 
			
		||||
             */
 | 
			
		||||
            *p_filesz = phys_addr + mapping_length <= start + size_in_block ?
 | 
			
		||||
                        mapping_length :
 | 
			
		||||
                        size_in_block - (phys_addr - start);
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        offset += size_in_block;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return -1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int write_elf_loads(DumpState *s)
 | 
			
		||||
{
 | 
			
		||||
    hwaddr offset;
 | 
			
		||||
    hwaddr offset, filesz;
 | 
			
		||||
    MemoryMapping *memory_mapping;
 | 
			
		||||
    uint32_t phdr_index = 1;
 | 
			
		||||
    int ret;
 | 
			
		||||
@@ -481,11 +493,15 @@ static int write_elf_loads(DumpState *s)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    QTAILQ_FOREACH(memory_mapping, &s->list.head, next) {
 | 
			
		||||
        offset = get_offset(memory_mapping->phys_addr, s);
 | 
			
		||||
        get_offset_range(memory_mapping->phys_addr,
 | 
			
		||||
                         memory_mapping->length,
 | 
			
		||||
                         s, &offset, &filesz);
 | 
			
		||||
        if (s->dump_info.d_class == ELFCLASS64) {
 | 
			
		||||
            ret = write_elf64_load(s, memory_mapping, phdr_index++, offset);
 | 
			
		||||
            ret = write_elf64_load(s, memory_mapping, phdr_index++, offset,
 | 
			
		||||
                                   filesz);
 | 
			
		||||
        } else {
 | 
			
		||||
            ret = write_elf32_load(s, memory_mapping, phdr_index++, offset);
 | 
			
		||||
            ret = write_elf32_load(s, memory_mapping, phdr_index++, offset,
 | 
			
		||||
                                   filesz);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (ret < 0) {
 | 
			
		||||
@@ -596,7 +612,7 @@ static int dump_completed(DumpState *s)
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int get_next_block(DumpState *s, RAMBlock *block)
 | 
			
		||||
static int get_next_block(DumpState *s, GuestPhysBlock *block)
 | 
			
		||||
{
 | 
			
		||||
    while (1) {
 | 
			
		||||
        block = QTAILQ_NEXT(block, next);
 | 
			
		||||
@@ -606,16 +622,16 @@ static int get_next_block(DumpState *s, RAMBlock *block)
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        s->start = 0;
 | 
			
		||||
        s->block = block;
 | 
			
		||||
        s->next_block = block;
 | 
			
		||||
        if (s->has_filter) {
 | 
			
		||||
            if (block->offset >= s->begin + s->length ||
 | 
			
		||||
                block->offset + block->length <= s->begin) {
 | 
			
		||||
            if (block->target_start >= s->begin + s->length ||
 | 
			
		||||
                block->target_end <= s->begin) {
 | 
			
		||||
                /* This block is out of the range */
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (s->begin > block->offset) {
 | 
			
		||||
                s->start = s->begin - block->offset;
 | 
			
		||||
            if (s->begin > block->target_start) {
 | 
			
		||||
                s->start = s->begin - block->target_start;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@@ -626,18 +642,18 @@ static int get_next_block(DumpState *s, RAMBlock *block)
 | 
			
		||||
/* write all memory to vmcore */
 | 
			
		||||
static int dump_iterate(DumpState *s)
 | 
			
		||||
{
 | 
			
		||||
    RAMBlock *block;
 | 
			
		||||
    GuestPhysBlock *block;
 | 
			
		||||
    int64_t size;
 | 
			
		||||
    int ret;
 | 
			
		||||
 | 
			
		||||
    while (1) {
 | 
			
		||||
        block = s->block;
 | 
			
		||||
        block = s->next_block;
 | 
			
		||||
 | 
			
		||||
        size = block->length;
 | 
			
		||||
        size = block->target_end - block->target_start;
 | 
			
		||||
        if (s->has_filter) {
 | 
			
		||||
            size -= s->start;
 | 
			
		||||
            if (s->begin + s->length < block->offset + block->length) {
 | 
			
		||||
                size -= block->offset + block->length - (s->begin + s->length);
 | 
			
		||||
            if (s->begin + s->length < block->target_end) {
 | 
			
		||||
                size -= block->target_end - (s->begin + s->length);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        ret = write_memory(s, block, s->start, size);
 | 
			
		||||
@@ -672,23 +688,23 @@ static int create_vmcore(DumpState *s)
 | 
			
		||||
 | 
			
		||||
static ram_addr_t get_start_block(DumpState *s)
 | 
			
		||||
{
 | 
			
		||||
    RAMBlock *block;
 | 
			
		||||
    GuestPhysBlock *block;
 | 
			
		||||
 | 
			
		||||
    if (!s->has_filter) {
 | 
			
		||||
        s->block = QTAILQ_FIRST(&ram_list.blocks);
 | 
			
		||||
        s->next_block = QTAILQ_FIRST(&s->guest_phys_blocks.head);
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    QTAILQ_FOREACH(block, &ram_list.blocks, next) {
 | 
			
		||||
        if (block->offset >= s->begin + s->length ||
 | 
			
		||||
            block->offset + block->length <= s->begin) {
 | 
			
		||||
    QTAILQ_FOREACH(block, &s->guest_phys_blocks.head, next) {
 | 
			
		||||
        if (block->target_start >= s->begin + s->length ||
 | 
			
		||||
            block->target_end <= s->begin) {
 | 
			
		||||
            /* This block is out of the range */
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        s->block = block;
 | 
			
		||||
        if (s->begin > block->offset) {
 | 
			
		||||
            s->start = s->begin - block->offset;
 | 
			
		||||
        s->next_block = block;
 | 
			
		||||
        if (s->begin > block->target_start) {
 | 
			
		||||
            s->start = s->begin - block->target_start;
 | 
			
		||||
        } else {
 | 
			
		||||
            s->start = 0;
 | 
			
		||||
        }
 | 
			
		||||
@@ -713,24 +729,8 @@ static int dump_init(DumpState *s, int fd, bool paging, bool has_filter,
 | 
			
		||||
        s->resume = false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    s->errp = errp;
 | 
			
		||||
    s->fd = fd;
 | 
			
		||||
    s->has_filter = has_filter;
 | 
			
		||||
    s->begin = begin;
 | 
			
		||||
    s->length = length;
 | 
			
		||||
    s->start = get_start_block(s);
 | 
			
		||||
    if (s->start == -1) {
 | 
			
		||||
        error_set(errp, QERR_INVALID_PARAMETER, "begin");
 | 
			
		||||
        goto cleanup;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
     * get dump info: endian, class and architecture.
 | 
			
		||||
     * If the target architecture is not supported, cpu_get_dump_info() will
 | 
			
		||||
     * return -1.
 | 
			
		||||
     *
 | 
			
		||||
     * If we use KVM, we should synchronize the registers before we get dump
 | 
			
		||||
     * info.
 | 
			
		||||
    /* If we use KVM, we should synchronize the registers before we get dump
 | 
			
		||||
     * info or physmap info.
 | 
			
		||||
     */
 | 
			
		||||
    cpu_synchronize_all_states();
 | 
			
		||||
    nr_cpus = 0;
 | 
			
		||||
@@ -738,7 +738,26 @@ static int dump_init(DumpState *s, int fd, bool paging, bool has_filter,
 | 
			
		||||
        nr_cpus++;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ret = cpu_get_dump_info(&s->dump_info);
 | 
			
		||||
    s->errp = errp;
 | 
			
		||||
    s->fd = fd;
 | 
			
		||||
    s->has_filter = has_filter;
 | 
			
		||||
    s->begin = begin;
 | 
			
		||||
    s->length = length;
 | 
			
		||||
 | 
			
		||||
    guest_phys_blocks_init(&s->guest_phys_blocks);
 | 
			
		||||
    guest_phys_blocks_append(&s->guest_phys_blocks);
 | 
			
		||||
 | 
			
		||||
    s->start = get_start_block(s);
 | 
			
		||||
    if (s->start == -1) {
 | 
			
		||||
        error_set(errp, QERR_INVALID_PARAMETER, "begin");
 | 
			
		||||
        goto cleanup;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* get dump info: endian, class and architecture.
 | 
			
		||||
     * If the target architecture is not supported, cpu_get_dump_info() will
 | 
			
		||||
     * return -1.
 | 
			
		||||
     */
 | 
			
		||||
    ret = cpu_get_dump_info(&s->dump_info, &s->guest_phys_blocks);
 | 
			
		||||
    if (ret < 0) {
 | 
			
		||||
        error_set(errp, QERR_UNSUPPORTED);
 | 
			
		||||
        goto cleanup;
 | 
			
		||||
@@ -754,13 +773,13 @@ static int dump_init(DumpState *s, int fd, bool paging, bool has_filter,
 | 
			
		||||
    /* get memory mapping */
 | 
			
		||||
    memory_mapping_list_init(&s->list);
 | 
			
		||||
    if (paging) {
 | 
			
		||||
        qemu_get_guest_memory_mapping(&s->list, &err);
 | 
			
		||||
        qemu_get_guest_memory_mapping(&s->list, &s->guest_phys_blocks, &err);
 | 
			
		||||
        if (err != NULL) {
 | 
			
		||||
            error_propagate(errp, err);
 | 
			
		||||
            goto cleanup;
 | 
			
		||||
        }
 | 
			
		||||
    } else {
 | 
			
		||||
        qemu_get_guest_simple_memory_mapping(&s->list);
 | 
			
		||||
        qemu_get_guest_simple_memory_mapping(&s->list, &s->guest_phys_blocks);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (s->has_filter) {
 | 
			
		||||
@@ -812,6 +831,8 @@ static int dump_init(DumpState *s, int fd, bool paging, bool has_filter,
 | 
			
		||||
    return 0;
 | 
			
		||||
 | 
			
		||||
cleanup:
 | 
			
		||||
    guest_phys_blocks_free(&s->guest_phys_blocks);
 | 
			
		||||
 | 
			
		||||
    if (s->resume) {
 | 
			
		||||
        vm_start();
 | 
			
		||||
    }
 | 
			
		||||
@@ -859,7 +880,7 @@ void qmp_dump_guest_memory(bool paging, const char *file, bool has_begin,
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    s = g_malloc(sizeof(DumpState));
 | 
			
		||||
    s = g_malloc0(sizeof(DumpState));
 | 
			
		||||
 | 
			
		||||
    ret = dump_init(s, fd, paging, has_begin, begin, length, errp);
 | 
			
		||||
    if (ret < 0) {
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										5
									
								
								exec.c
									
									
									
									
									
								
							
							
						
						
									
										5
									
								
								exec.c
									
									
									
									
									
								
							@@ -402,11 +402,14 @@ void cpu_exec_init(CPUArchState *env)
 | 
			
		||||
#if defined(CONFIG_USER_ONLY)
 | 
			
		||||
    cpu_list_unlock();
 | 
			
		||||
#endif
 | 
			
		||||
    vmstate_register(NULL, cpu_index, &vmstate_cpu_common, cpu);
 | 
			
		||||
    if (qdev_get_vmsd(DEVICE(cpu)) == NULL) {
 | 
			
		||||
        vmstate_register(NULL, cpu_index, &vmstate_cpu_common, cpu);
 | 
			
		||||
    }
 | 
			
		||||
#if defined(CPU_SAVE_VERSION) && !defined(CONFIG_USER_ONLY)
 | 
			
		||||
    register_savevm(NULL, "cpu", cpu_index, CPU_SAVE_VERSION,
 | 
			
		||||
                    cpu_save, cpu_load, env);
 | 
			
		||||
    assert(cc->vmsd == NULL);
 | 
			
		||||
    assert(qdev_get_vmsd(DEVICE(cpu)) == NULL);
 | 
			
		||||
#endif
 | 
			
		||||
    if (cc->vmsd != NULL) {
 | 
			
		||||
        vmstate_register(NULL, cpu_index, cc->vmsd, cpu);
 | 
			
		||||
 
 | 
			
		||||
@@ -621,6 +621,8 @@ void gdb_register_coprocessor(CPUState *cpu,
 | 
			
		||||
        if (g_pos != s->base_reg) {
 | 
			
		||||
            fprintf(stderr, "Error: Bad gdb register numbering for '%s'\n"
 | 
			
		||||
                    "Expected %d got %d\n", xml, g_pos, s->base_reg);
 | 
			
		||||
        } else {
 | 
			
		||||
            cpu->gdb_num_g_regs = cpu->gdb_num_regs;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -902,7 +904,7 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
 | 
			
		||||
    case 'g':
 | 
			
		||||
        cpu_synchronize_state(s->g_cpu);
 | 
			
		||||
        len = 0;
 | 
			
		||||
        for (addr = 0; addr < s->g_cpu->gdb_num_regs; addr++) {
 | 
			
		||||
        for (addr = 0; addr < s->g_cpu->gdb_num_g_regs; addr++) {
 | 
			
		||||
            reg_size = gdb_read_register(s->g_cpu, mem_buf + len, addr);
 | 
			
		||||
            len += reg_size;
 | 
			
		||||
        }
 | 
			
		||||
@@ -914,7 +916,7 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
 | 
			
		||||
        registers = mem_buf;
 | 
			
		||||
        len = strlen(p) / 2;
 | 
			
		||||
        hextomem((uint8_t *)registers, p, len);
 | 
			
		||||
        for (addr = 0; addr < s->g_cpu->gdb_num_regs && len > 0; addr++) {
 | 
			
		||||
        for (addr = 0; addr < s->g_cpu->gdb_num_g_regs && len > 0; addr++) {
 | 
			
		||||
            reg_size = gdb_write_register(s->g_cpu, registers, addr);
 | 
			
		||||
            len -= reg_size;
 | 
			
		||||
            registers += reg_size;
 | 
			
		||||
 
 | 
			
		||||
@@ -173,7 +173,6 @@ static QEMUMachine clipper_machine = {
 | 
			
		||||
    .init = clipper_init,
 | 
			
		||||
    .max_cpus = 4,
 | 
			
		||||
    .is_default = 1,
 | 
			
		||||
    DEFAULT_MACHINE_OPTIONS,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void clipper_machine_init(void)
 | 
			
		||||
 
 | 
			
		||||
@@ -26,9 +26,9 @@ typedef struct TyphoonCchip {
 | 
			
		||||
} TyphoonCchip;
 | 
			
		||||
 | 
			
		||||
typedef struct TyphoonWindow {
 | 
			
		||||
    uint32_t base_addr;
 | 
			
		||||
    uint32_t mask;
 | 
			
		||||
    uint32_t translated_base_pfn;
 | 
			
		||||
    uint64_t wba;
 | 
			
		||||
    uint64_t wsm;
 | 
			
		||||
    uint64_t tba;
 | 
			
		||||
} TyphoonWindow;
 | 
			
		||||
 
 | 
			
		||||
typedef struct TyphoonPchip {
 | 
			
		||||
@@ -37,6 +37,10 @@ typedef struct TyphoonPchip {
 | 
			
		||||
    MemoryRegion reg_mem;
 | 
			
		||||
    MemoryRegion reg_io;
 | 
			
		||||
    MemoryRegion reg_conf;
 | 
			
		||||
 | 
			
		||||
    AddressSpace iommu_as;
 | 
			
		||||
    MemoryRegion iommu;
 | 
			
		||||
 | 
			
		||||
    uint64_t ctl;
 | 
			
		||||
    TyphoonWindow win[4];
 | 
			
		||||
} TyphoonPchip;
 | 
			
		||||
@@ -209,53 +213,53 @@ static uint64_t pchip_read(void *opaque, hwaddr addr, unsigned size)
 | 
			
		||||
    switch (addr) {
 | 
			
		||||
    case 0x0000:
 | 
			
		||||
        /* WSBA0: Window Space Base Address Register.  */
 | 
			
		||||
        ret = s->pchip.win[0].base_addr;
 | 
			
		||||
        ret = s->pchip.win[0].wba;
 | 
			
		||||
        break;
 | 
			
		||||
    case 0x0040:
 | 
			
		||||
        /* WSBA1 */
 | 
			
		||||
        ret = s->pchip.win[1].base_addr;
 | 
			
		||||
        ret = s->pchip.win[1].wba;
 | 
			
		||||
        break;
 | 
			
		||||
    case 0x0080:
 | 
			
		||||
        /* WSBA2 */
 | 
			
		||||
        ret = s->pchip.win[2].base_addr;
 | 
			
		||||
        ret = s->pchip.win[2].wba;
 | 
			
		||||
        break;
 | 
			
		||||
    case 0x00c0:
 | 
			
		||||
        /* WSBA3 */
 | 
			
		||||
        ret = s->pchip.win[3].base_addr;
 | 
			
		||||
        ret = s->pchip.win[3].wba;
 | 
			
		||||
        break;
 | 
			
		||||
 | 
			
		||||
    case 0x0100:
 | 
			
		||||
        /* WSM0: Window Space Mask Register.  */
 | 
			
		||||
        ret = s->pchip.win[0].mask;
 | 
			
		||||
        ret = s->pchip.win[0].wsm;
 | 
			
		||||
        break;
 | 
			
		||||
    case 0x0140:
 | 
			
		||||
        /* WSM1 */
 | 
			
		||||
        ret = s->pchip.win[1].mask;
 | 
			
		||||
        ret = s->pchip.win[1].wsm;
 | 
			
		||||
        break;
 | 
			
		||||
    case 0x0180:
 | 
			
		||||
        /* WSM2 */
 | 
			
		||||
        ret = s->pchip.win[2].mask;
 | 
			
		||||
        ret = s->pchip.win[2].wsm;
 | 
			
		||||
        break;
 | 
			
		||||
    case 0x01c0:
 | 
			
		||||
        /* WSM3 */
 | 
			
		||||
        ret = s->pchip.win[3].mask;
 | 
			
		||||
        ret = s->pchip.win[3].wsm;
 | 
			
		||||
        break;
 | 
			
		||||
 | 
			
		||||
    case 0x0200:
 | 
			
		||||
        /* TBA0: Translated Base Address Register.  */
 | 
			
		||||
        ret = (uint64_t)s->pchip.win[0].translated_base_pfn << 10;
 | 
			
		||||
        ret = s->pchip.win[0].tba;
 | 
			
		||||
        break;
 | 
			
		||||
    case 0x0240:
 | 
			
		||||
        /* TBA1 */
 | 
			
		||||
        ret = (uint64_t)s->pchip.win[1].translated_base_pfn << 10;
 | 
			
		||||
        ret = s->pchip.win[1].tba;
 | 
			
		||||
        break;
 | 
			
		||||
    case 0x0280:
 | 
			
		||||
        /* TBA2 */
 | 
			
		||||
        ret = (uint64_t)s->pchip.win[2].translated_base_pfn << 10;
 | 
			
		||||
        ret = s->pchip.win[2].tba;
 | 
			
		||||
        break;
 | 
			
		||||
    case 0x02c0:
 | 
			
		||||
        /* TBA3 */
 | 
			
		||||
        ret = (uint64_t)s->pchip.win[3].translated_base_pfn << 10;
 | 
			
		||||
        ret = s->pchip.win[3].tba;
 | 
			
		||||
        break;
 | 
			
		||||
 | 
			
		||||
    case 0x0300:
 | 
			
		||||
@@ -458,53 +462,53 @@ static void pchip_write(void *opaque, hwaddr addr,
 | 
			
		||||
    switch (addr) {
 | 
			
		||||
    case 0x0000:
 | 
			
		||||
        /* WSBA0: Window Space Base Address Register.  */
 | 
			
		||||
        s->pchip.win[0].base_addr = val;
 | 
			
		||||
        s->pchip.win[0].wba = val & 0xfff00003u;
 | 
			
		||||
        break;
 | 
			
		||||
    case 0x0040:
 | 
			
		||||
        /* WSBA1 */
 | 
			
		||||
        s->pchip.win[1].base_addr = val;
 | 
			
		||||
        s->pchip.win[1].wba = val & 0xfff00003u;
 | 
			
		||||
        break;
 | 
			
		||||
    case 0x0080:
 | 
			
		||||
        /* WSBA2 */
 | 
			
		||||
        s->pchip.win[2].base_addr = val;
 | 
			
		||||
        s->pchip.win[2].wba = val & 0xfff00003u;
 | 
			
		||||
        break;
 | 
			
		||||
    case 0x00c0:
 | 
			
		||||
        /* WSBA3 */
 | 
			
		||||
        s->pchip.win[3].base_addr = val;
 | 
			
		||||
        s->pchip.win[3].wba = (val & 0x80fff00001ull) | 2;
 | 
			
		||||
        break;
 | 
			
		||||
 | 
			
		||||
    case 0x0100:
 | 
			
		||||
        /* WSM0: Window Space Mask Register.  */
 | 
			
		||||
        s->pchip.win[0].mask = val;
 | 
			
		||||
        s->pchip.win[0].wsm = val & 0xfff00000u;
 | 
			
		||||
        break;
 | 
			
		||||
    case 0x0140:
 | 
			
		||||
        /* WSM1 */
 | 
			
		||||
        s->pchip.win[1].mask = val;
 | 
			
		||||
        s->pchip.win[1].wsm = val & 0xfff00000u;
 | 
			
		||||
        break;
 | 
			
		||||
    case 0x0180:
 | 
			
		||||
        /* WSM2 */
 | 
			
		||||
        s->pchip.win[2].mask = val;
 | 
			
		||||
        s->pchip.win[2].wsm = val & 0xfff00000u;
 | 
			
		||||
        break;
 | 
			
		||||
    case 0x01c0:
 | 
			
		||||
        /* WSM3 */
 | 
			
		||||
        s->pchip.win[3].mask = val;
 | 
			
		||||
        s->pchip.win[3].wsm = val & 0xfff00000u;
 | 
			
		||||
        break;
 | 
			
		||||
 | 
			
		||||
    case 0x0200:
 | 
			
		||||
        /* TBA0: Translated Base Address Register.  */
 | 
			
		||||
        s->pchip.win[0].translated_base_pfn = val >> 10;
 | 
			
		||||
        s->pchip.win[0].tba = val & 0x7fffffc00ull;
 | 
			
		||||
        break;
 | 
			
		||||
    case 0x0240:
 | 
			
		||||
        /* TBA1 */
 | 
			
		||||
        s->pchip.win[1].translated_base_pfn = val >> 10;
 | 
			
		||||
        s->pchip.win[1].tba = val & 0x7fffffc00ull;
 | 
			
		||||
        break;
 | 
			
		||||
    case 0x0280:
 | 
			
		||||
        /* TBA2 */
 | 
			
		||||
        s->pchip.win[2].translated_base_pfn = val >> 10;
 | 
			
		||||
        s->pchip.win[2].tba = val & 0x7fffffc00ull;
 | 
			
		||||
        break;
 | 
			
		||||
    case 0x02c0:
 | 
			
		||||
        /* TBA3 */
 | 
			
		||||
        s->pchip.win[3].translated_base_pfn = val >> 10;
 | 
			
		||||
        s->pchip.win[3].tba = val & 0x7fffffc00ull;
 | 
			
		||||
        break;
 | 
			
		||||
 | 
			
		||||
    case 0x0300:
 | 
			
		||||
@@ -512,7 +516,6 @@ static void pchip_write(void *opaque, hwaddr addr,
 | 
			
		||||
        oldval = s->pchip.ctl;
 | 
			
		||||
        oldval &= ~0x00001cff0fc7ffull;       /* RW fields */
 | 
			
		||||
        oldval |= val & 0x00001cff0fc7ffull;
 | 
			
		||||
 | 
			
		||||
        s->pchip.ctl = oldval;
 | 
			
		||||
        break;
 | 
			
		||||
 | 
			
		||||
@@ -593,6 +596,140 @@ static const MemoryRegionOps pchip_ops = {
 | 
			
		||||
    },
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* A subroutine of typhoon_translate_iommu that builds an IOMMUTLBEntry
 | 
			
		||||
   using the given translated address and mask.  */
 | 
			
		||||
static bool make_iommu_tlbe(hwaddr taddr, hwaddr mask, IOMMUTLBEntry *ret)
 | 
			
		||||
{
 | 
			
		||||
    *ret = (IOMMUTLBEntry) {
 | 
			
		||||
        .target_as = &address_space_memory,
 | 
			
		||||
        .translated_addr = taddr,
 | 
			
		||||
        .addr_mask = mask,
 | 
			
		||||
        .perm = IOMMU_RW,
 | 
			
		||||
    };
 | 
			
		||||
    return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* A subroutine of typhoon_translate_iommu that handles scatter-gather
 | 
			
		||||
   translation, given the address of the PTE.  */
 | 
			
		||||
static bool pte_translate(hwaddr pte_addr, IOMMUTLBEntry *ret)
 | 
			
		||||
{
 | 
			
		||||
    uint64_t pte = ldq_phys(pte_addr);
 | 
			
		||||
 | 
			
		||||
    /* Check valid bit.  */
 | 
			
		||||
    if ((pte & 1) == 0) {
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return make_iommu_tlbe((pte & 0x3ffffe) << 12, 0x1fff, ret);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* A subroutine of typhoon_translate_iommu that handles one of the
 | 
			
		||||
   four single-address-cycle translation windows.  */
 | 
			
		||||
static bool window_translate(TyphoonWindow *win, hwaddr addr,
 | 
			
		||||
                             IOMMUTLBEntry *ret)
 | 
			
		||||
{
 | 
			
		||||
    uint32_t wba = win->wba;
 | 
			
		||||
    uint64_t wsm = win->wsm;
 | 
			
		||||
    uint64_t tba = win->tba;
 | 
			
		||||
    uint64_t wsm_ext = wsm | 0xfffff;
 | 
			
		||||
 | 
			
		||||
    /* Check for window disabled.  */
 | 
			
		||||
    if ((wba & 1) == 0) {
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* Check for window hit.  */
 | 
			
		||||
    if ((addr & ~wsm_ext) != (wba & 0xfff00000u)) {
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (wba & 2) {
 | 
			
		||||
        /* Scatter-gather translation.  */
 | 
			
		||||
        hwaddr pte_addr;
 | 
			
		||||
 | 
			
		||||
        /* See table 10-6, Generating PTE address for PCI DMA Address.  */
 | 
			
		||||
        pte_addr  = tba & ~(wsm >> 10);
 | 
			
		||||
        pte_addr |= (addr & (wsm | 0xfe000)) >> 10;
 | 
			
		||||
        return pte_translate(pte_addr, ret);
 | 
			
		||||
    } else {
 | 
			
		||||
	/* Direct-mapped translation.  */
 | 
			
		||||
	return make_iommu_tlbe(tba & ~wsm_ext, wsm_ext, ret);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Handle PCI-to-system address translation.  */
 | 
			
		||||
/* TODO: A translation failure here ought to set PCI error codes on the
 | 
			
		||||
   Pchip and generate a machine check interrupt.  */
 | 
			
		||||
static IOMMUTLBEntry typhoon_translate_iommu(MemoryRegion *iommu, hwaddr addr)
 | 
			
		||||
{
 | 
			
		||||
    TyphoonPchip *pchip = container_of(iommu, TyphoonPchip, iommu);
 | 
			
		||||
    IOMMUTLBEntry ret;
 | 
			
		||||
    int i;
 | 
			
		||||
 | 
			
		||||
    if (addr <= 0xffffffffu) {
 | 
			
		||||
        /* Single-address cycle.  */
 | 
			
		||||
 | 
			
		||||
        /* Check for the Window Hole, inhibiting matching.  */
 | 
			
		||||
        if ((pchip->ctl & 0x20)
 | 
			
		||||
            && addr >= 0x80000
 | 
			
		||||
            && addr <= 0xfffff) {
 | 
			
		||||
            goto failure;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /* Check the first three windows.  */
 | 
			
		||||
        for (i = 0; i < 3; ++i) {
 | 
			
		||||
            if (window_translate(&pchip->win[i], addr, &ret)) {
 | 
			
		||||
                goto success;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /* Check the fourth window for DAC disable.  */
 | 
			
		||||
        if ((pchip->win[3].wba & 0x80000000000ull) == 0
 | 
			
		||||
	    && window_translate(&pchip->win[3], addr, &ret)) {
 | 
			
		||||
            goto success;
 | 
			
		||||
        }
 | 
			
		||||
    } else {
 | 
			
		||||
        /* Double-address cycle.  */
 | 
			
		||||
 | 
			
		||||
        if (addr >= 0x10000000000ull && addr < 0x20000000000ull) {
 | 
			
		||||
            /* Check for the DMA monster window.  */
 | 
			
		||||
            if (pchip->ctl & 0x40) {
 | 
			
		||||
                /* See 10.1.4.4; in particular <39:35> is ignored.  */
 | 
			
		||||
                make_iommu_tlbe(0, 0x007ffffffffull, &ret);
 | 
			
		||||
		goto success;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (addr >= 0x80000000000 && addr <= 0xfffffffffff) {
 | 
			
		||||
            /* Check the fourth window for DAC enable and window enable.  */
 | 
			
		||||
            if ((pchip->win[3].wba & 0x80000000001ull) == 0x80000000001ull) {
 | 
			
		||||
                uint64_t pte_addr;
 | 
			
		||||
 | 
			
		||||
                pte_addr  = pchip->win[3].tba & 0x7ffc00000ull;
 | 
			
		||||
                pte_addr |= (addr & 0xffffe000u) >> 10;
 | 
			
		||||
                if (pte_translate(pte_addr, &ret)) {
 | 
			
		||||
			goto success;
 | 
			
		||||
		}
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 failure:
 | 
			
		||||
    ret = (IOMMUTLBEntry) { .perm = IOMMU_NONE };
 | 
			
		||||
 success:
 | 
			
		||||
    return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static const MemoryRegionIOMMUOps typhoon_iommu_ops = {
 | 
			
		||||
    .translate = typhoon_translate_iommu,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static AddressSpace *typhoon_pci_dma_iommu(PCIBus *bus, void *opaque, int devfn)
 | 
			
		||||
{
 | 
			
		||||
    TyphoonState *s = opaque;
 | 
			
		||||
    return &s->pchip.iommu_as;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void typhoon_set_irq(void *opaque, int irq, int level)
 | 
			
		||||
{
 | 
			
		||||
    TyphoonState *s = opaque;
 | 
			
		||||
@@ -688,6 +825,9 @@ PCIBus *typhoon_init(ram_addr_t ram_size, ISABus **isa_bus,
 | 
			
		||||
    s = TYPHOON_PCI_HOST_BRIDGE(dev);
 | 
			
		||||
    phb = PCI_HOST_BRIDGE(dev);
 | 
			
		||||
 | 
			
		||||
    s->cchip.misc = 0x800000000ull; /* Revision: Typhoon.  */
 | 
			
		||||
    s->pchip.win[3].wba = 2;        /* Window 3 SG always enabled. */
 | 
			
		||||
 | 
			
		||||
    /* Remember the CPUs so that we can deliver interrupts to them.  */
 | 
			
		||||
    for (i = 0; i < 4; i++) {
 | 
			
		||||
        AlphaCPU *cpu = cpus[i];
 | 
			
		||||
@@ -746,6 +886,12 @@ PCIBus *typhoon_init(ram_addr_t ram_size, ISABus **isa_bus,
 | 
			
		||||
                         0, 64, TYPE_PCI_BUS);
 | 
			
		||||
    phb->bus = b;
 | 
			
		||||
 | 
			
		||||
    /* Host memory as seen from the PCI side, via the IOMMU.  */
 | 
			
		||||
    memory_region_init_iommu(&s->pchip.iommu, OBJECT(s), &typhoon_iommu_ops,
 | 
			
		||||
                             "iommu-typhoon", UINT64_MAX);
 | 
			
		||||
    address_space_init(&s->pchip.iommu_as, &s->pchip.iommu, "pchip0-pci");
 | 
			
		||||
    pci_setup_iommu(b, typhoon_pci_dma_iommu, s);
 | 
			
		||||
 | 
			
		||||
    /* Pchip0 PCI special/interrupt acknowledge, 0x801.F800.0000, 64MB.  */
 | 
			
		||||
    memory_region_init_io(&s->pchip.reg_iack, OBJECT(s), &alpha_pci_iack_ops,
 | 
			
		||||
                          b, "pci0-iack", 64*MB);
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
obj-y += boot.o collie.o exynos4_boards.o gumstix.o highbank.o
 | 
			
		||||
obj-y += integratorcp.o kzm.o mainstone.o musicpal.o nseries.o
 | 
			
		||||
obj-y += omap_sx1.o palm.o pic_cpu.o realview.o spitz.o stellaris.o
 | 
			
		||||
obj-y += omap_sx1.o palm.o realview.o spitz.o stellaris.o
 | 
			
		||||
obj-y += tosa.o versatilepb.o vexpress.o xilinx_zynq.o z2.o
 | 
			
		||||
 | 
			
		||||
obj-y += armv7m.o exynos4210.o pxa2xx.o pxa2xx_gpio.o pxa2xx_pic.o
 | 
			
		||||
 
 | 
			
		||||
@@ -173,7 +173,6 @@ qemu_irq *armv7m_init(MemoryRegion *address_space_mem,
 | 
			
		||||
    DeviceState *nvic;
 | 
			
		||||
    /* FIXME: make this local state.  */
 | 
			
		||||
    static qemu_irq pic[64];
 | 
			
		||||
    qemu_irq *cpu_pic;
 | 
			
		||||
    int image_size;
 | 
			
		||||
    uint64_t entry;
 | 
			
		||||
    uint64_t lowaddr;
 | 
			
		||||
@@ -221,8 +220,8 @@ qemu_irq *armv7m_init(MemoryRegion *address_space_mem,
 | 
			
		||||
    nvic = qdev_create(NULL, "armv7m_nvic");
 | 
			
		||||
    env->nvic = nvic;
 | 
			
		||||
    qdev_init_nofail(nvic);
 | 
			
		||||
    cpu_pic = arm_pic_init_cpu(cpu);
 | 
			
		||||
    sysbus_connect_irq(SYS_BUS_DEVICE(nvic), 0, cpu_pic[ARM_PIC_CPU_IRQ]);
 | 
			
		||||
    sysbus_connect_irq(SYS_BUS_DEVICE(nvic), 0,
 | 
			
		||||
                       qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_IRQ));
 | 
			
		||||
    for (i = 0; i < 64; i++) {
 | 
			
		||||
        pic[i] = qdev_get_gpio_in(nvic, i);
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -62,7 +62,6 @@ static QEMUMachine collie_machine = {
 | 
			
		||||
    .name = "collie",
 | 
			
		||||
    .desc = "Collie PDA (SA-1110)",
 | 
			
		||||
    .init = collie_init,
 | 
			
		||||
    DEFAULT_MACHINE_OPTIONS,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void collie_machine_init(void)
 | 
			
		||||
 
 | 
			
		||||
@@ -137,10 +137,8 @@ void exynos4210_write_secondary(ARMCPU *cpu,
 | 
			
		||||
Exynos4210State *exynos4210_init(MemoryRegion *system_mem,
 | 
			
		||||
        unsigned long ram_size)
 | 
			
		||||
{
 | 
			
		||||
    qemu_irq cpu_irq[EXYNOS4210_NCPUS];
 | 
			
		||||
    int i, n;
 | 
			
		||||
    Exynos4210State *s = g_new(Exynos4210State, 1);
 | 
			
		||||
    qemu_irq *irqp;
 | 
			
		||||
    qemu_irq gate_irq[EXYNOS4210_NCPUS][EXYNOS4210_IRQ_GATE_NINPUTS];
 | 
			
		||||
    unsigned long mem_size;
 | 
			
		||||
    DeviceState *dev;
 | 
			
		||||
@@ -152,15 +150,6 @@ Exynos4210State *exynos4210_init(MemoryRegion *system_mem,
 | 
			
		||||
            fprintf(stderr, "Unable to find CPU %d definition\n", n);
 | 
			
		||||
            exit(1);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /* Create PIC controller for each processor instance */
 | 
			
		||||
        irqp = arm_pic_init_cpu(s->cpu[n]);
 | 
			
		||||
 | 
			
		||||
        /*
 | 
			
		||||
         * Get GICs gpio_in cpu_irq to connect a combiner to them later.
 | 
			
		||||
         * Use only IRQ for a while.
 | 
			
		||||
         */
 | 
			
		||||
        cpu_irq[n] = irqp[ARM_PIC_CPU_IRQ];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /*** IRQs ***/
 | 
			
		||||
@@ -178,8 +167,9 @@ Exynos4210State *exynos4210_init(MemoryRegion *system_mem,
 | 
			
		||||
        }
 | 
			
		||||
        busdev = SYS_BUS_DEVICE(dev);
 | 
			
		||||
 | 
			
		||||
        /* Connect IRQ Gate output to cpu_irq */
 | 
			
		||||
        sysbus_connect_irq(busdev, 0, cpu_irq[i]);
 | 
			
		||||
        /* Connect IRQ Gate output to CPU's IRQ line */
 | 
			
		||||
        sysbus_connect_irq(busdev, 0,
 | 
			
		||||
                           qdev_get_gpio_in(DEVICE(s->cpu[i]), ARM_CPU_IRQ));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* Private memory region and Internal GIC */
 | 
			
		||||
 
 | 
			
		||||
@@ -150,14 +150,12 @@ static QEMUMachine exynos4_machines[EXYNOS4_NUM_OF_BOARDS] = {
 | 
			
		||||
        .desc = "Samsung NURI board (Exynos4210)",
 | 
			
		||||
        .init = nuri_init,
 | 
			
		||||
        .max_cpus = EXYNOS4210_NCPUS,
 | 
			
		||||
        DEFAULT_MACHINE_OPTIONS,
 | 
			
		||||
    },
 | 
			
		||||
    [EXYNOS4_BOARD_SMDKC210] = {
 | 
			
		||||
        .name = "smdkc210",
 | 
			
		||||
        .desc = "Samsung SMDKC210 board (Exynos4210)",
 | 
			
		||||
        .init = smdkc210_init,
 | 
			
		||||
        .max_cpus = EXYNOS4210_NCPUS,
 | 
			
		||||
        DEFAULT_MACHINE_OPTIONS,
 | 
			
		||||
    },
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -122,14 +122,12 @@ static QEMUMachine connex_machine = {
 | 
			
		||||
    .name = "connex",
 | 
			
		||||
    .desc = "Gumstix Connex (PXA255)",
 | 
			
		||||
    .init = connex_init,
 | 
			
		||||
    DEFAULT_MACHINE_OPTIONS,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static QEMUMachine verdex_machine = {
 | 
			
		||||
    .name = "verdex",
 | 
			
		||||
    .desc = "Gumstix Verdex (PXA270)",
 | 
			
		||||
    .init = verdex_init,
 | 
			
		||||
    DEFAULT_MACHINE_OPTIONS,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void gumstix_machine_init(void)
 | 
			
		||||
 
 | 
			
		||||
@@ -209,7 +209,6 @@ static void calxeda_init(QEMUMachineInitArgs *args, enum cxmachines machine)
 | 
			
		||||
    const char *initrd_filename = args->initrd_filename;
 | 
			
		||||
    DeviceState *dev = NULL;
 | 
			
		||||
    SysBusDevice *busdev;
 | 
			
		||||
    qemu_irq *irqp;
 | 
			
		||||
    qemu_irq pic[128];
 | 
			
		||||
    int n;
 | 
			
		||||
    qemu_irq cpu_irq[4];
 | 
			
		||||
@@ -239,8 +238,7 @@ static void calxeda_init(QEMUMachineInitArgs *args, enum cxmachines machine)
 | 
			
		||||
 | 
			
		||||
        /* This will become a QOM property eventually */
 | 
			
		||||
        cpu->reset_cbar = GIC_BASE_ADDR;
 | 
			
		||||
        irqp = arm_pic_init_cpu(cpu);
 | 
			
		||||
        cpu_irq[n] = irqp[ARM_PIC_CPU_IRQ];
 | 
			
		||||
        cpu_irq[n] = qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_IRQ);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    sysmem = get_system_memory();
 | 
			
		||||
@@ -365,7 +363,6 @@ static QEMUMachine highbank_machine = {
 | 
			
		||||
    .init = highbank_init,
 | 
			
		||||
    .block_default_type = IF_SCSI,
 | 
			
		||||
    .max_cpus = 4,
 | 
			
		||||
    DEFAULT_MACHINE_OPTIONS,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static QEMUMachine midway_machine = {
 | 
			
		||||
@@ -374,7 +371,6 @@ static QEMUMachine midway_machine = {
 | 
			
		||||
    .init = midway_init,
 | 
			
		||||
    .block_default_type = IF_SCSI,
 | 
			
		||||
    .max_cpus = 4,
 | 
			
		||||
    DEFAULT_MACHINE_OPTIONS,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void calxeda_machines_init(void)
 | 
			
		||||
 
 | 
			
		||||
@@ -465,7 +465,6 @@ static void integratorcp_init(QEMUMachineInitArgs *args)
 | 
			
		||||
    MemoryRegion *ram = g_new(MemoryRegion, 1);
 | 
			
		||||
    MemoryRegion *ram_alias = g_new(MemoryRegion, 1);
 | 
			
		||||
    qemu_irq pic[32];
 | 
			
		||||
    qemu_irq *cpu_pic;
 | 
			
		||||
    DeviceState *dev;
 | 
			
		||||
    int i;
 | 
			
		||||
 | 
			
		||||
@@ -493,10 +492,10 @@ static void integratorcp_init(QEMUMachineInitArgs *args)
 | 
			
		||||
    qdev_init_nofail(dev);
 | 
			
		||||
    sysbus_mmio_map((SysBusDevice *)dev, 0, 0x10000000);
 | 
			
		||||
 | 
			
		||||
    cpu_pic = arm_pic_init_cpu(cpu);
 | 
			
		||||
    dev = sysbus_create_varargs(TYPE_INTEGRATOR_PIC, 0x14000000,
 | 
			
		||||
                                cpu_pic[ARM_PIC_CPU_IRQ],
 | 
			
		||||
                                cpu_pic[ARM_PIC_CPU_FIQ], NULL);
 | 
			
		||||
                                qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_IRQ),
 | 
			
		||||
                                qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_FIQ),
 | 
			
		||||
                                NULL);
 | 
			
		||||
    for (i = 0; i < 32; i++) {
 | 
			
		||||
        pic[i] = qdev_get_gpio_in(dev, i);
 | 
			
		||||
    }
 | 
			
		||||
@@ -527,7 +526,6 @@ static QEMUMachine integratorcp_machine = {
 | 
			
		||||
    .desc = "ARM Integrator/CP (ARM926EJ-S)",
 | 
			
		||||
    .init = integratorcp_init,
 | 
			
		||||
    .is_default = 1,
 | 
			
		||||
    DEFAULT_MACHINE_OPTIONS,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void integratorcp_machine_init(void)
 | 
			
		||||
 
 | 
			
		||||
@@ -82,7 +82,6 @@ static void kzm_init(QEMUMachineInitArgs *args)
 | 
			
		||||
    MemoryRegion *ram = g_new(MemoryRegion, 1);
 | 
			
		||||
    MemoryRegion *sram = g_new(MemoryRegion, 1);
 | 
			
		||||
    MemoryRegion *ram_alias = g_new(MemoryRegion, 1);
 | 
			
		||||
    qemu_irq *cpu_pic;
 | 
			
		||||
    DeviceState *dev;
 | 
			
		||||
    DeviceState *ccm;
 | 
			
		||||
 | 
			
		||||
@@ -108,11 +107,10 @@ static void kzm_init(QEMUMachineInitArgs *args)
 | 
			
		||||
    memory_region_init_ram(sram, NULL, "kzm.sram", 0x4000);
 | 
			
		||||
    memory_region_add_subregion(address_space_mem, 0x1FFFC000, sram);
 | 
			
		||||
 | 
			
		||||
    cpu_pic = arm_pic_init_cpu(cpu);
 | 
			
		||||
    dev = sysbus_create_varargs("imx_avic", 0x68000000,
 | 
			
		||||
                                cpu_pic[ARM_PIC_CPU_IRQ],
 | 
			
		||||
                                cpu_pic[ARM_PIC_CPU_FIQ], NULL);
 | 
			
		||||
 | 
			
		||||
                                qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_IRQ),
 | 
			
		||||
                                qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_FIQ),
 | 
			
		||||
                                NULL);
 | 
			
		||||
 | 
			
		||||
    imx_serial_create(0, 0x43f90000, qdev_get_gpio_in(dev, 45));
 | 
			
		||||
    imx_serial_create(1, 0x43f94000, qdev_get_gpio_in(dev, 32));
 | 
			
		||||
@@ -146,7 +144,6 @@ static QEMUMachine kzm_machine = {
 | 
			
		||||
    .name = "kzm",
 | 
			
		||||
    .desc = "ARM KZM Emulation Baseboard (ARM1136)",
 | 
			
		||||
    .init = kzm_init,
 | 
			
		||||
    DEFAULT_MACHINE_OPTIONS,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void kzm_machine_init(void)
 | 
			
		||||
 
 | 
			
		||||
@@ -179,7 +179,6 @@ static QEMUMachine mainstone2_machine = {
 | 
			
		||||
    .name = "mainstone",
 | 
			
		||||
    .desc = "Mainstone II (PXA27x)",
 | 
			
		||||
    .init = mainstone_init,
 | 
			
		||||
    DEFAULT_MACHINE_OPTIONS,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void mainstone_machine_init(void)
 | 
			
		||||
 
 | 
			
		||||
@@ -1586,7 +1586,6 @@ static void musicpal_init(QEMUMachineInitArgs *args)
 | 
			
		||||
    const char *kernel_cmdline = args->kernel_cmdline;
 | 
			
		||||
    const char *initrd_filename = args->initrd_filename;
 | 
			
		||||
    ARMCPU *cpu;
 | 
			
		||||
    qemu_irq *cpu_pic;
 | 
			
		||||
    qemu_irq pic[32];
 | 
			
		||||
    DeviceState *dev;
 | 
			
		||||
    DeviceState *i2c_dev;
 | 
			
		||||
@@ -1610,7 +1609,6 @@ static void musicpal_init(QEMUMachineInitArgs *args)
 | 
			
		||||
        fprintf(stderr, "Unable to find CPU definition\n");
 | 
			
		||||
        exit(1);
 | 
			
		||||
    }
 | 
			
		||||
    cpu_pic = arm_pic_init_cpu(cpu);
 | 
			
		||||
 | 
			
		||||
    /* For now we use a fixed - the original - RAM size */
 | 
			
		||||
    memory_region_init_ram(ram, NULL, "musicpal.ram", MP_RAM_DEFAULT_SIZE);
 | 
			
		||||
@@ -1622,7 +1620,7 @@ static void musicpal_init(QEMUMachineInitArgs *args)
 | 
			
		||||
    memory_region_add_subregion(address_space_mem, MP_SRAM_BASE, sram);
 | 
			
		||||
 | 
			
		||||
    dev = sysbus_create_simple(TYPE_MV88W8618_PIC, MP_PIC_BASE,
 | 
			
		||||
                               cpu_pic[ARM_PIC_CPU_IRQ]);
 | 
			
		||||
                               qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_IRQ));
 | 
			
		||||
    for (i = 0; i < 32; i++) {
 | 
			
		||||
        pic[i] = qdev_get_gpio_in(dev, i);
 | 
			
		||||
    }
 | 
			
		||||
@@ -1731,7 +1729,6 @@ static QEMUMachine musicpal_machine = {
 | 
			
		||||
    .name = "musicpal",
 | 
			
		||||
    .desc = "Marvell 88w8618 / MusicPal (ARM926EJ-S)",
 | 
			
		||||
    .init = musicpal_init,
 | 
			
		||||
    DEFAULT_MACHINE_OPTIONS,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void musicpal_machine_init(void)
 | 
			
		||||
 
 | 
			
		||||
@@ -1340,7 +1340,7 @@ static void n8x0_init(QEMUMachineInitArgs *args,
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (option_rom[0].name &&
 | 
			
		||||
        (args->boot_device[0] == 'n' || !args->kernel_filename)) {
 | 
			
		||||
        (args->boot_order[0] == 'n' || !args->kernel_filename)) {
 | 
			
		||||
        uint8_t nolo_tags[0x10000];
 | 
			
		||||
        /* No, wait, better start at the ROM.  */
 | 
			
		||||
        s->mpu->cpu->env.regs[15] = OMAP2_Q2_BASE + 0x400000;
 | 
			
		||||
@@ -1396,14 +1396,14 @@ static QEMUMachine n800_machine = {
 | 
			
		||||
    .name = "n800",
 | 
			
		||||
    .desc = "Nokia N800 tablet aka. RX-34 (OMAP2420)",
 | 
			
		||||
    .init = n800_init,
 | 
			
		||||
    DEFAULT_MACHINE_OPTIONS,
 | 
			
		||||
    .default_boot_order = "",
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static QEMUMachine n810_machine = {
 | 
			
		||||
    .name = "n810",
 | 
			
		||||
    .desc = "Nokia N810 tablet aka. RX-44 (OMAP2420)",
 | 
			
		||||
    .init = n810_init,
 | 
			
		||||
    DEFAULT_MACHINE_OPTIONS,
 | 
			
		||||
    .default_boot_order = "",
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void nseries_machine_init(void)
 | 
			
		||||
 
 | 
			
		||||
@@ -3827,7 +3827,6 @@ struct omap_mpu_state_s *omap310_mpu_init(MemoryRegion *system_memory,
 | 
			
		||||
    int i;
 | 
			
		||||
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *)
 | 
			
		||||
            g_malloc0(sizeof(struct omap_mpu_state_s));
 | 
			
		||||
    qemu_irq *cpu_irq;
 | 
			
		||||
    qemu_irq dma_irqs[6];
 | 
			
		||||
    DriveInfo *dinfo;
 | 
			
		||||
    SysBusDevice *busdev;
 | 
			
		||||
@@ -3860,14 +3859,15 @@ struct omap_mpu_state_s *omap310_mpu_init(MemoryRegion *system_memory,
 | 
			
		||||
 | 
			
		||||
    omap_clkm_init(system_memory, 0xfffece00, 0xe1008000, s);
 | 
			
		||||
 | 
			
		||||
    cpu_irq = arm_pic_init_cpu(s->cpu);
 | 
			
		||||
    s->ih[0] = qdev_create(NULL, "omap-intc");
 | 
			
		||||
    qdev_prop_set_uint32(s->ih[0], "size", 0x100);
 | 
			
		||||
    qdev_prop_set_ptr(s->ih[0], "clk", omap_findclk(s, "arminth_ck"));
 | 
			
		||||
    qdev_init_nofail(s->ih[0]);
 | 
			
		||||
    busdev = SYS_BUS_DEVICE(s->ih[0]);
 | 
			
		||||
    sysbus_connect_irq(busdev, 0, cpu_irq[ARM_PIC_CPU_IRQ]);
 | 
			
		||||
    sysbus_connect_irq(busdev, 1, cpu_irq[ARM_PIC_CPU_FIQ]);
 | 
			
		||||
    sysbus_connect_irq(busdev, 0,
 | 
			
		||||
                       qdev_get_gpio_in(DEVICE(s->cpu), ARM_CPU_IRQ));
 | 
			
		||||
    sysbus_connect_irq(busdev, 1,
 | 
			
		||||
                       qdev_get_gpio_in(DEVICE(s->cpu), ARM_CPU_FIQ));
 | 
			
		||||
    sysbus_mmio_map(busdev, 0, 0xfffecb00);
 | 
			
		||||
    s->ih[1] = qdev_create(NULL, "omap-intc");
 | 
			
		||||
    qdev_prop_set_uint32(s->ih[1], "size", 0x800);
 | 
			
		||||
 
 | 
			
		||||
@@ -2244,7 +2244,6 @@ struct omap_mpu_state_s *omap2420_mpu_init(MemoryRegion *sysmem,
 | 
			
		||||
{
 | 
			
		||||
    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *)
 | 
			
		||||
            g_malloc0(sizeof(struct omap_mpu_state_s));
 | 
			
		||||
    qemu_irq *cpu_irq;
 | 
			
		||||
    qemu_irq dma_irqs[4];
 | 
			
		||||
    DriveInfo *dinfo;
 | 
			
		||||
    int i;
 | 
			
		||||
@@ -2277,15 +2276,16 @@ struct omap_mpu_state_s *omap2420_mpu_init(MemoryRegion *sysmem,
 | 
			
		||||
    s->l4 = omap_l4_init(sysmem, OMAP2_L4_BASE, 54);
 | 
			
		||||
 | 
			
		||||
    /* Actually mapped at any 2K boundary in the ARM11 private-peripheral if */
 | 
			
		||||
    cpu_irq = arm_pic_init_cpu(s->cpu);
 | 
			
		||||
    s->ih[0] = qdev_create(NULL, "omap2-intc");
 | 
			
		||||
    qdev_prop_set_uint8(s->ih[0], "revision", 0x21);
 | 
			
		||||
    qdev_prop_set_ptr(s->ih[0], "fclk", omap_findclk(s, "mpu_intc_fclk"));
 | 
			
		||||
    qdev_prop_set_ptr(s->ih[0], "iclk", omap_findclk(s, "mpu_intc_iclk"));
 | 
			
		||||
    qdev_init_nofail(s->ih[0]);
 | 
			
		||||
    busdev = SYS_BUS_DEVICE(s->ih[0]);
 | 
			
		||||
    sysbus_connect_irq(busdev, 0, cpu_irq[ARM_PIC_CPU_IRQ]);
 | 
			
		||||
    sysbus_connect_irq(busdev, 1, cpu_irq[ARM_PIC_CPU_FIQ]);
 | 
			
		||||
    sysbus_connect_irq(busdev, 0,
 | 
			
		||||
                       qdev_get_gpio_in(DEVICE(s->cpu), ARM_CPU_IRQ));
 | 
			
		||||
    sysbus_connect_irq(busdev, 1,
 | 
			
		||||
                       qdev_get_gpio_in(DEVICE(s->cpu), ARM_CPU_FIQ));
 | 
			
		||||
    sysbus_mmio_map(busdev, 0, 0x480fe000);
 | 
			
		||||
    s->prcm = omap_prcm_init(omap_l4tao(s->l4, 3),
 | 
			
		||||
                             qdev_get_gpio_in(s->ih[0],
 | 
			
		||||
 
 | 
			
		||||
@@ -219,14 +219,12 @@ static QEMUMachine sx1_machine_v2 = {
 | 
			
		||||
    .name = "sx1",
 | 
			
		||||
    .desc = "Siemens SX1 (OMAP310) V2",
 | 
			
		||||
    .init = sx1_init_v2,
 | 
			
		||||
    DEFAULT_MACHINE_OPTIONS,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static QEMUMachine sx1_machine_v1 = {
 | 
			
		||||
    .name = "sx1-v1",
 | 
			
		||||
    .desc = "Siemens SX1 (OMAP310) V1",
 | 
			
		||||
    .init = sx1_init_v1,
 | 
			
		||||
    DEFAULT_MACHINE_OPTIONS,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void sx1_machine_init(void)
 | 
			
		||||
 
 | 
			
		||||
@@ -273,7 +273,6 @@ static QEMUMachine palmte_machine = {
 | 
			
		||||
    .name = "cheetah",
 | 
			
		||||
    .desc = "Palm Tungsten|E aka. Cheetah PDA (OMAP310)",
 | 
			
		||||
    .init = palmte_init,
 | 
			
		||||
    DEFAULT_MACHINE_OPTIONS,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void palmte_machine_init(void)
 | 
			
		||||
 
 | 
			
		||||
@@ -1,68 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Generic ARM Programmable Interrupt Controller support.
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (c) 2006 CodeSourcery.
 | 
			
		||||
 * Written by Paul Brook
 | 
			
		||||
 *
 | 
			
		||||
 * This code is licensed under the LGPL
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "hw/hw.h"
 | 
			
		||||
#include "hw/arm/arm.h"
 | 
			
		||||
#include "sysemu/kvm.h"
 | 
			
		||||
 | 
			
		||||
/* Input 0 is IRQ and input 1 is FIQ.  */
 | 
			
		||||
static void arm_pic_cpu_handler(void *opaque, int irq, int level)
 | 
			
		||||
{
 | 
			
		||||
    ARMCPU *cpu = opaque;
 | 
			
		||||
    CPUState *cs = CPU(cpu);
 | 
			
		||||
 | 
			
		||||
    switch (irq) {
 | 
			
		||||
    case ARM_PIC_CPU_IRQ:
 | 
			
		||||
        if (level) {
 | 
			
		||||
            cpu_interrupt(cs, CPU_INTERRUPT_HARD);
 | 
			
		||||
        } else {
 | 
			
		||||
            cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD);
 | 
			
		||||
        }
 | 
			
		||||
        break;
 | 
			
		||||
    case ARM_PIC_CPU_FIQ:
 | 
			
		||||
        if (level) {
 | 
			
		||||
            cpu_interrupt(cs, CPU_INTERRUPT_FIQ);
 | 
			
		||||
        } else {
 | 
			
		||||
            cpu_reset_interrupt(cs, CPU_INTERRUPT_FIQ);
 | 
			
		||||
        }
 | 
			
		||||
        break;
 | 
			
		||||
    default:
 | 
			
		||||
        hw_error("arm_pic_cpu_handler: Bad interrupt line %d\n", irq);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void kvm_arm_pic_cpu_handler(void *opaque, int irq, int level)
 | 
			
		||||
{
 | 
			
		||||
#ifdef CONFIG_KVM
 | 
			
		||||
    ARMCPU *cpu = opaque;
 | 
			
		||||
    CPUState *cs = CPU(cpu);
 | 
			
		||||
    int kvm_irq = KVM_ARM_IRQ_TYPE_CPU << KVM_ARM_IRQ_TYPE_SHIFT;
 | 
			
		||||
 | 
			
		||||
    switch (irq) {
 | 
			
		||||
    case ARM_PIC_CPU_IRQ:
 | 
			
		||||
        kvm_irq |= KVM_ARM_IRQ_CPU_IRQ;
 | 
			
		||||
        break;
 | 
			
		||||
    case ARM_PIC_CPU_FIQ:
 | 
			
		||||
        kvm_irq |= KVM_ARM_IRQ_CPU_FIQ;
 | 
			
		||||
        break;
 | 
			
		||||
    default:
 | 
			
		||||
        hw_error("kvm_arm_pic_cpu_handler: Bad interrupt line %d\n", irq);
 | 
			
		||||
    }
 | 
			
		||||
    kvm_irq |= cs->cpu_index << KVM_ARM_IRQ_VCPU_SHIFT;
 | 
			
		||||
    kvm_set_irq(kvm_state, kvm_irq, level ? 1 : 0);
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
qemu_irq *arm_pic_init_cpu(ARMCPU *cpu)
 | 
			
		||||
{
 | 
			
		||||
    if (kvm_enabled()) {
 | 
			
		||||
        return qemu_allocate_irqs(kvm_arm_pic_cpu_handler, cpu, 2);
 | 
			
		||||
    }
 | 
			
		||||
    return qemu_allocate_irqs(arm_pic_cpu_handler, cpu, 2);
 | 
			
		||||
}
 | 
			
		||||
@@ -1479,6 +1479,7 @@ PXA2xxI2CState *pxa2xx_i2c_init(hwaddr base,
 | 
			
		||||
    DeviceState *dev;
 | 
			
		||||
    SysBusDevice *i2c_dev;
 | 
			
		||||
    PXA2xxI2CState *s;
 | 
			
		||||
    i2c_bus *i2cbus;
 | 
			
		||||
 | 
			
		||||
    dev = qdev_create(NULL, TYPE_PXA2XX_I2C);
 | 
			
		||||
    qdev_prop_set_uint32(dev, "size", region_size + 1);
 | 
			
		||||
@@ -1491,7 +1492,8 @@ PXA2xxI2CState *pxa2xx_i2c_init(hwaddr base,
 | 
			
		||||
 | 
			
		||||
    s = PXA2XX_I2C(i2c_dev);
 | 
			
		||||
    /* FIXME: Should the slave device really be on a separate bus?  */
 | 
			
		||||
    dev = i2c_create_slave(i2c_init_bus(NULL, "dummy"), "pxa2xx-i2c-slave", 0);
 | 
			
		||||
    i2cbus = i2c_init_bus(dev, "dummy");
 | 
			
		||||
    dev = i2c_create_slave(i2cbus, "pxa2xx-i2c-slave", 0);
 | 
			
		||||
    s->slave = FROM_I2C_SLAVE(PXA2xxI2CSlaveState, I2C_SLAVE(dev));
 | 
			
		||||
    s->slave->host = s;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -56,7 +56,6 @@ static void realview_init(QEMUMachineInitArgs *args,
 | 
			
		||||
    MemoryRegion *ram_hack = g_new(MemoryRegion, 1);
 | 
			
		||||
    DeviceState *dev, *sysctl, *gpio2, *pl041;
 | 
			
		||||
    SysBusDevice *busdev;
 | 
			
		||||
    qemu_irq *irqp;
 | 
			
		||||
    qemu_irq pic[64];
 | 
			
		||||
    qemu_irq mmc_irq[2];
 | 
			
		||||
    PCIBus *pci_bus = NULL;
 | 
			
		||||
@@ -92,8 +91,7 @@ static void realview_init(QEMUMachineInitArgs *args,
 | 
			
		||||
            fprintf(stderr, "Unable to find CPU definition\n");
 | 
			
		||||
            exit(1);
 | 
			
		||||
        }
 | 
			
		||||
        irqp = arm_pic_init_cpu(cpu);
 | 
			
		||||
        cpu_irq[n] = irqp[ARM_PIC_CPU_IRQ];
 | 
			
		||||
        cpu_irq[n] = qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_IRQ);
 | 
			
		||||
    }
 | 
			
		||||
    env = &cpu->env;
 | 
			
		||||
    if (arm_feature(env, ARM_FEATURE_V7)) {
 | 
			
		||||
@@ -371,7 +369,6 @@ static QEMUMachine realview_eb_machine = {
 | 
			
		||||
    .desc = "ARM RealView Emulation Baseboard (ARM926EJ-S)",
 | 
			
		||||
    .init = realview_eb_init,
 | 
			
		||||
    .block_default_type = IF_SCSI,
 | 
			
		||||
    DEFAULT_MACHINE_OPTIONS,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static QEMUMachine realview_eb_mpcore_machine = {
 | 
			
		||||
@@ -380,14 +377,12 @@ static QEMUMachine realview_eb_mpcore_machine = {
 | 
			
		||||
    .init = realview_eb_mpcore_init,
 | 
			
		||||
    .block_default_type = IF_SCSI,
 | 
			
		||||
    .max_cpus = 4,
 | 
			
		||||
    DEFAULT_MACHINE_OPTIONS,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static QEMUMachine realview_pb_a8_machine = {
 | 
			
		||||
    .name = "realview-pb-a8",
 | 
			
		||||
    .desc = "ARM RealView Platform Baseboard for Cortex-A8",
 | 
			
		||||
    .init = realview_pb_a8_init,
 | 
			
		||||
    DEFAULT_MACHINE_OPTIONS,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static QEMUMachine realview_pbx_a9_machine = {
 | 
			
		||||
@@ -396,7 +391,6 @@ static QEMUMachine realview_pbx_a9_machine = {
 | 
			
		||||
    .init = realview_pbx_a9_init,
 | 
			
		||||
    .block_default_type = IF_SCSI,
 | 
			
		||||
    .max_cpus = 4,
 | 
			
		||||
    DEFAULT_MACHINE_OPTIONS,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void realview_machine_init(void)
 | 
			
		||||
 
 | 
			
		||||
@@ -966,28 +966,24 @@ static QEMUMachine akitapda_machine = {
 | 
			
		||||
    .name = "akita",
 | 
			
		||||
    .desc = "Akita PDA (PXA270)",
 | 
			
		||||
    .init = akita_init,
 | 
			
		||||
    DEFAULT_MACHINE_OPTIONS,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static QEMUMachine spitzpda_machine = {
 | 
			
		||||
    .name = "spitz",
 | 
			
		||||
    .desc = "Spitz PDA (PXA270)",
 | 
			
		||||
    .init = spitz_init,
 | 
			
		||||
    DEFAULT_MACHINE_OPTIONS,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static QEMUMachine borzoipda_machine = {
 | 
			
		||||
    .name = "borzoi",
 | 
			
		||||
    .desc = "Borzoi PDA (PXA270)",
 | 
			
		||||
    .init = borzoi_init,
 | 
			
		||||
    DEFAULT_MACHINE_OPTIONS,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static QEMUMachine terrierpda_machine = {
 | 
			
		||||
    .name = "terrier",
 | 
			
		||||
    .desc = "Terrier PDA (PXA270)",
 | 
			
		||||
    .init = terrier_init,
 | 
			
		||||
    DEFAULT_MACHINE_OPTIONS,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void spitz_machine_init(void)
 | 
			
		||||
 
 | 
			
		||||
@@ -1348,14 +1348,12 @@ static QEMUMachine lm3s811evb_machine = {
 | 
			
		||||
    .name = "lm3s811evb",
 | 
			
		||||
    .desc = "Stellaris LM3S811EVB",
 | 
			
		||||
    .init = lm3s811evb_init,
 | 
			
		||||
    DEFAULT_MACHINE_OPTIONS,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static QEMUMachine lm3s6965evb_machine = {
 | 
			
		||||
    .name = "lm3s6965evb",
 | 
			
		||||
    .desc = "Stellaris LM3S6965EVB",
 | 
			
		||||
    .init = lm3s6965evb_init,
 | 
			
		||||
    DEFAULT_MACHINE_OPTIONS,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void stellaris_machine_init(void)
 | 
			
		||||
 
 | 
			
		||||
@@ -1588,7 +1588,6 @@ StrongARMState *sa1110_init(MemoryRegion *sysmem,
 | 
			
		||||
                            unsigned int sdram_size, const char *rev)
 | 
			
		||||
{
 | 
			
		||||
    StrongARMState *s;
 | 
			
		||||
    qemu_irq *pic;
 | 
			
		||||
    int i;
 | 
			
		||||
 | 
			
		||||
    s = g_malloc0(sizeof(StrongARMState));
 | 
			
		||||
@@ -1613,9 +1612,10 @@ StrongARMState *sa1110_init(MemoryRegion *sysmem,
 | 
			
		||||
    vmstate_register_ram_global(&s->sdram);
 | 
			
		||||
    memory_region_add_subregion(sysmem, SA_SDCS0, &s->sdram);
 | 
			
		||||
 | 
			
		||||
    pic = arm_pic_init_cpu(s->cpu);
 | 
			
		||||
    s->pic = sysbus_create_varargs("strongarm_pic", 0x90050000,
 | 
			
		||||
                    pic[ARM_PIC_CPU_IRQ], pic[ARM_PIC_CPU_FIQ], NULL);
 | 
			
		||||
                    qdev_get_gpio_in(DEVICE(s->cpu), ARM_CPU_IRQ),
 | 
			
		||||
                    qdev_get_gpio_in(DEVICE(s->cpu), ARM_CPU_FIQ),
 | 
			
		||||
                    NULL);
 | 
			
		||||
 | 
			
		||||
    sysbus_create_varargs("pxa25x-timer", 0x90000000,
 | 
			
		||||
                    qdev_get_gpio_in(s->pic, SA_PIC_OSTC0),
 | 
			
		||||
 
 | 
			
		||||
@@ -251,7 +251,6 @@ static QEMUMachine tosapda_machine = {
 | 
			
		||||
    .name = "tosa",
 | 
			
		||||
    .desc = "Tosa PDA (PXA255)",
 | 
			
		||||
    .init = tosa_init,
 | 
			
		||||
    DEFAULT_MACHINE_OPTIONS,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void tosapda_machine_init(void)
 | 
			
		||||
 
 | 
			
		||||
@@ -178,7 +178,6 @@ static void versatile_init(QEMUMachineInitArgs *args, int board_id)
 | 
			
		||||
    ARMCPU *cpu;
 | 
			
		||||
    MemoryRegion *sysmem = get_system_memory();
 | 
			
		||||
    MemoryRegion *ram = g_new(MemoryRegion, 1);
 | 
			
		||||
    qemu_irq *cpu_pic;
 | 
			
		||||
    qemu_irq pic[32];
 | 
			
		||||
    qemu_irq sic[32];
 | 
			
		||||
    DeviceState *dev, *sysctl;
 | 
			
		||||
@@ -211,10 +210,10 @@ static void versatile_init(QEMUMachineInitArgs *args, int board_id)
 | 
			
		||||
    qdev_init_nofail(sysctl);
 | 
			
		||||
    sysbus_mmio_map(SYS_BUS_DEVICE(sysctl), 0, 0x10000000);
 | 
			
		||||
 | 
			
		||||
    cpu_pic = arm_pic_init_cpu(cpu);
 | 
			
		||||
    dev = sysbus_create_varargs("pl190", 0x10140000,
 | 
			
		||||
                                cpu_pic[ARM_PIC_CPU_IRQ],
 | 
			
		||||
                                cpu_pic[ARM_PIC_CPU_FIQ], NULL);
 | 
			
		||||
                                qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_IRQ),
 | 
			
		||||
                                qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_FIQ),
 | 
			
		||||
                                NULL);
 | 
			
		||||
    for (n = 0; n < 32; n++) {
 | 
			
		||||
        pic[n] = qdev_get_gpio_in(dev, n);
 | 
			
		||||
    }
 | 
			
		||||
@@ -368,7 +367,6 @@ static QEMUMachine versatilepb_machine = {
 | 
			
		||||
    .desc = "ARM Versatile/PB (ARM926EJ-S)",
 | 
			
		||||
    .init = vpb_init,
 | 
			
		||||
    .block_default_type = IF_SCSI,
 | 
			
		||||
    DEFAULT_MACHINE_OPTIONS,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static QEMUMachine versatileab_machine = {
 | 
			
		||||
@@ -376,7 +374,6 @@ static QEMUMachine versatileab_machine = {
 | 
			
		||||
    .desc = "ARM Versatile/AB (ARM926EJ-S)",
 | 
			
		||||
    .init = vab_init,
 | 
			
		||||
    .block_default_type = IF_SCSI,
 | 
			
		||||
    DEFAULT_MACHINE_OPTIONS,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void versatile_machine_init(void)
 | 
			
		||||
 
 | 
			
		||||
@@ -183,7 +183,6 @@ static void a9_daughterboard_init(const VEDBoardInfo *daughterboard,
 | 
			
		||||
    MemoryRegion *lowram = g_new(MemoryRegion, 1);
 | 
			
		||||
    DeviceState *dev;
 | 
			
		||||
    SysBusDevice *busdev;
 | 
			
		||||
    qemu_irq *irqp;
 | 
			
		||||
    int n;
 | 
			
		||||
    qemu_irq cpu_irq[4];
 | 
			
		||||
    ram_addr_t low_ram_size;
 | 
			
		||||
@@ -198,8 +197,7 @@ static void a9_daughterboard_init(const VEDBoardInfo *daughterboard,
 | 
			
		||||
            fprintf(stderr, "Unable to find CPU definition\n");
 | 
			
		||||
            exit(1);
 | 
			
		||||
        }
 | 
			
		||||
        irqp = arm_pic_init_cpu(cpu);
 | 
			
		||||
        cpu_irq[n] = irqp[ARM_PIC_CPU_IRQ];
 | 
			
		||||
        cpu_irq[n] = qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_IRQ);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (ram_size > 0x40000000) {
 | 
			
		||||
@@ -312,15 +310,13 @@ static void a15_daughterboard_init(const VEDBoardInfo *daughterboard,
 | 
			
		||||
 | 
			
		||||
    for (n = 0; n < smp_cpus; n++) {
 | 
			
		||||
        ARMCPU *cpu;
 | 
			
		||||
        qemu_irq *irqp;
 | 
			
		||||
 | 
			
		||||
        cpu = cpu_arm_init(cpu_model);
 | 
			
		||||
        if (!cpu) {
 | 
			
		||||
            fprintf(stderr, "Unable to find CPU definition\n");
 | 
			
		||||
            exit(1);
 | 
			
		||||
        }
 | 
			
		||||
        irqp = arm_pic_init_cpu(cpu);
 | 
			
		||||
        cpu_irq[n] = irqp[ARM_PIC_CPU_IRQ];
 | 
			
		||||
        cpu_irq[n] = qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_IRQ);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    {
 | 
			
		||||
@@ -651,7 +647,6 @@ static QEMUMachine vexpress_a9_machine = {
 | 
			
		||||
    .init = vexpress_a9_init,
 | 
			
		||||
    .block_default_type = IF_SCSI,
 | 
			
		||||
    .max_cpus = 4,
 | 
			
		||||
    DEFAULT_MACHINE_OPTIONS,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static QEMUMachine vexpress_a15_machine = {
 | 
			
		||||
@@ -660,7 +655,6 @@ static QEMUMachine vexpress_a15_machine = {
 | 
			
		||||
    .init = vexpress_a15_init,
 | 
			
		||||
    .block_default_type = IF_SCSI,
 | 
			
		||||
    .max_cpus = 4,
 | 
			
		||||
    DEFAULT_MACHINE_OPTIONS,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void vexpress_machine_init(void)
 | 
			
		||||
 
 | 
			
		||||
@@ -108,11 +108,9 @@ static void zynq_init(QEMUMachineInitArgs *args)
 | 
			
		||||
    MemoryRegion *ocm_ram = g_new(MemoryRegion, 1);
 | 
			
		||||
    DeviceState *dev;
 | 
			
		||||
    SysBusDevice *busdev;
 | 
			
		||||
    qemu_irq *irqp;
 | 
			
		||||
    qemu_irq pic[64];
 | 
			
		||||
    NICInfo *nd;
 | 
			
		||||
    int n;
 | 
			
		||||
    qemu_irq cpu_irq;
 | 
			
		||||
 | 
			
		||||
    if (!cpu_model) {
 | 
			
		||||
        cpu_model = "cortex-a9";
 | 
			
		||||
@@ -123,8 +121,6 @@ static void zynq_init(QEMUMachineInitArgs *args)
 | 
			
		||||
        fprintf(stderr, "Unable to find CPU definition\n");
 | 
			
		||||
        exit(1);
 | 
			
		||||
    }
 | 
			
		||||
    irqp = arm_pic_init_cpu(cpu);
 | 
			
		||||
    cpu_irq = irqp[ARM_PIC_CPU_IRQ];
 | 
			
		||||
 | 
			
		||||
    /* max 2GB ram */
 | 
			
		||||
    if (ram_size > 0x80000000) {
 | 
			
		||||
@@ -159,7 +155,8 @@ static void zynq_init(QEMUMachineInitArgs *args)
 | 
			
		||||
    qdev_init_nofail(dev);
 | 
			
		||||
    busdev = SYS_BUS_DEVICE(dev);
 | 
			
		||||
    sysbus_mmio_map(busdev, 0, 0xF8F00000);
 | 
			
		||||
    sysbus_connect_irq(busdev, 0, cpu_irq);
 | 
			
		||||
    sysbus_connect_irq(busdev, 0,
 | 
			
		||||
                       qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_IRQ));
 | 
			
		||||
 | 
			
		||||
    for (n = 0; n < 64; n++) {
 | 
			
		||||
        pic[n] = qdev_get_gpio_in(dev, n);
 | 
			
		||||
@@ -236,7 +233,6 @@ static QEMUMachine zynq_machine = {
 | 
			
		||||
    .block_default_type = IF_SCSI,
 | 
			
		||||
    .max_cpus = 1,
 | 
			
		||||
    .no_sdcard = 1,
 | 
			
		||||
    DEFAULT_MACHINE_OPTIONS,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void zynq_machine_init(void)
 | 
			
		||||
 
 | 
			
		||||
@@ -373,7 +373,6 @@ static QEMUMachine z2_machine = {
 | 
			
		||||
    .name = "z2",
 | 
			
		||||
    .desc = "Zipit Z2 (PXA27x)",
 | 
			
		||||
    .init = z2_init,
 | 
			
		||||
    DEFAULT_MACHINE_OPTIONS,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void z2_machine_init(void)
 | 
			
		||||
 
 | 
			
		||||
@@ -7,7 +7,6 @@ common-obj-$(CONFIG_PFLASH_CFI02) += pflash_cfi02.o
 | 
			
		||||
common-obj-$(CONFIG_XEN_BACKEND) += xen_disk.o
 | 
			
		||||
common-obj-$(CONFIG_ECC) += ecc.o
 | 
			
		||||
common-obj-$(CONFIG_ONENAND) += onenand.o
 | 
			
		||||
common-obj-$(CONFIG_PC_SYSFW) += pc_sysfw.o
 | 
			
		||||
common-obj-$(CONFIG_NVME_PCI) += nvme.o
 | 
			
		||||
 | 
			
		||||
obj-$(CONFIG_SH4) += tc58128.o
 | 
			
		||||
 
 | 
			
		||||
@@ -261,11 +261,6 @@ static int process_request(IOQueue *ioq, struct iovec iov[],
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int flush_true(EventNotifier *e)
 | 
			
		||||
{
 | 
			
		||||
    return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void handle_notify(EventNotifier *e)
 | 
			
		||||
{
 | 
			
		||||
    VirtIOBlockDataPlane *s = container_of(e, VirtIOBlockDataPlane,
 | 
			
		||||
@@ -345,14 +340,6 @@ static void handle_notify(EventNotifier *e)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int flush_io(EventNotifier *e)
 | 
			
		||||
{
 | 
			
		||||
    VirtIOBlockDataPlane *s = container_of(e, VirtIOBlockDataPlane,
 | 
			
		||||
                                           io_notifier);
 | 
			
		||||
 | 
			
		||||
    return s->num_reqs > 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void handle_io(EventNotifier *e)
 | 
			
		||||
{
 | 
			
		||||
    VirtIOBlockDataPlane *s = container_of(e, VirtIOBlockDataPlane,
 | 
			
		||||
@@ -376,9 +363,9 @@ static void *data_plane_thread(void *opaque)
 | 
			
		||||
{
 | 
			
		||||
    VirtIOBlockDataPlane *s = opaque;
 | 
			
		||||
 | 
			
		||||
    do {
 | 
			
		||||
    while (!s->stopping || s->num_reqs > 0) {
 | 
			
		||||
        aio_poll(s->ctx, true);
 | 
			
		||||
    } while (!s->stopping || s->num_reqs > 0);
 | 
			
		||||
    }
 | 
			
		||||
    return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -485,7 +472,7 @@ void virtio_blk_data_plane_start(VirtIOBlockDataPlane *s)
 | 
			
		||||
        exit(1);
 | 
			
		||||
    }
 | 
			
		||||
    s->host_notifier = *virtio_queue_get_host_notifier(vq);
 | 
			
		||||
    aio_set_event_notifier(s->ctx, &s->host_notifier, handle_notify, flush_true);
 | 
			
		||||
    aio_set_event_notifier(s->ctx, &s->host_notifier, handle_notify);
 | 
			
		||||
 | 
			
		||||
    /* Set up ioqueue */
 | 
			
		||||
    ioq_init(&s->ioqueue, s->fd, REQ_MAX);
 | 
			
		||||
@@ -493,7 +480,7 @@ void virtio_blk_data_plane_start(VirtIOBlockDataPlane *s)
 | 
			
		||||
        ioq_put_iocb(&s->ioqueue, &s->requests[i].iocb);
 | 
			
		||||
    }
 | 
			
		||||
    s->io_notifier = *ioq_get_notifier(&s->ioqueue);
 | 
			
		||||
    aio_set_event_notifier(s->ctx, &s->io_notifier, handle_io, flush_io);
 | 
			
		||||
    aio_set_event_notifier(s->ctx, &s->io_notifier, handle_io);
 | 
			
		||||
 | 
			
		||||
    s->started = true;
 | 
			
		||||
    trace_virtio_blk_data_plane_start(s);
 | 
			
		||||
@@ -525,10 +512,10 @@ void virtio_blk_data_plane_stop(VirtIOBlockDataPlane *s)
 | 
			
		||||
        qemu_thread_join(&s->thread);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    aio_set_event_notifier(s->ctx, &s->io_notifier, NULL, NULL);
 | 
			
		||||
    aio_set_event_notifier(s->ctx, &s->io_notifier, NULL);
 | 
			
		||||
    ioq_cleanup(&s->ioqueue);
 | 
			
		||||
 | 
			
		||||
    aio_set_event_notifier(s->ctx, &s->host_notifier, NULL, NULL);
 | 
			
		||||
    aio_set_event_notifier(s->ctx, &s->host_notifier, NULL);
 | 
			
		||||
    k->set_host_notifier(qbus->parent, 0, false);
 | 
			
		||||
 | 
			
		||||
    aio_context_unref(s->ctx);
 | 
			
		||||
 
 | 
			
		||||
@@ -54,6 +54,8 @@
 | 
			
		||||
 | 
			
		||||
#include <zlib.h>
 | 
			
		||||
 | 
			
		||||
bool rom_file_in_ram = true;
 | 
			
		||||
 | 
			
		||||
static int roms_loaded;
 | 
			
		||||
 | 
			
		||||
/* return the size or -1 if error */
 | 
			
		||||
@@ -576,6 +578,7 @@ struct Rom {
 | 
			
		||||
    size_t datasize;
 | 
			
		||||
 | 
			
		||||
    uint8_t *data;
 | 
			
		||||
    MemoryRegion *mr;
 | 
			
		||||
    int isrom;
 | 
			
		||||
    char *fw_dir;
 | 
			
		||||
    char *fw_file;
 | 
			
		||||
@@ -605,6 +608,21 @@ static void rom_insert(Rom *rom)
 | 
			
		||||
    QTAILQ_INSERT_TAIL(&roms, rom, next);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void *rom_set_mr(Rom *rom, Object *owner, const char *name)
 | 
			
		||||
{
 | 
			
		||||
    void *data;
 | 
			
		||||
 | 
			
		||||
    rom->mr = g_malloc(sizeof(*rom->mr));
 | 
			
		||||
    memory_region_init_ram(rom->mr, owner, name, rom->datasize);
 | 
			
		||||
    memory_region_set_readonly(rom->mr, true);
 | 
			
		||||
    vmstate_register_ram_global(rom->mr);
 | 
			
		||||
 | 
			
		||||
    data = memory_region_get_ram_ptr(rom->mr);
 | 
			
		||||
    memcpy(data, rom->data, rom->datasize);
 | 
			
		||||
 | 
			
		||||
    return data;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int rom_add_file(const char *file, const char *fw_dir,
 | 
			
		||||
                 hwaddr addr, int32_t bootindex)
 | 
			
		||||
{
 | 
			
		||||
@@ -646,6 +664,7 @@ int rom_add_file(const char *file, const char *fw_dir,
 | 
			
		||||
    if (rom->fw_file && fw_cfg) {
 | 
			
		||||
        const char *basename;
 | 
			
		||||
        char fw_file_name[56];
 | 
			
		||||
        void *data;
 | 
			
		||||
 | 
			
		||||
        basename = strrchr(rom->fw_file, '/');
 | 
			
		||||
        if (basename) {
 | 
			
		||||
@@ -655,8 +674,15 @@ int rom_add_file(const char *file, const char *fw_dir,
 | 
			
		||||
        }
 | 
			
		||||
        snprintf(fw_file_name, sizeof(fw_file_name), "%s/%s", rom->fw_dir,
 | 
			
		||||
                 basename);
 | 
			
		||||
        fw_cfg_add_file(fw_cfg, fw_file_name, rom->data, rom->romsize);
 | 
			
		||||
        snprintf(devpath, sizeof(devpath), "/rom@%s", fw_file_name);
 | 
			
		||||
 | 
			
		||||
        if (rom_file_in_ram) {
 | 
			
		||||
            data = rom_set_mr(rom, OBJECT(fw_cfg), devpath);
 | 
			
		||||
        } else {
 | 
			
		||||
            data = rom->data;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        fw_cfg_add_file(fw_cfg, fw_file_name, data, rom->romsize);
 | 
			
		||||
    } else {
 | 
			
		||||
        snprintf(devpath, sizeof(devpath), "/rom@" TARGET_FMT_plx, addr);
 | 
			
		||||
    }
 | 
			
		||||
@@ -731,7 +757,12 @@ static void rom_reset(void *unused)
 | 
			
		||||
        if (rom->data == NULL) {
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
        cpu_physical_memory_write_rom(rom->addr, rom->data, rom->datasize);
 | 
			
		||||
        if (rom->mr) {
 | 
			
		||||
            void *host = memory_region_get_ram_ptr(rom->mr);
 | 
			
		||||
            memcpy(host, rom->data, rom->datasize);
 | 
			
		||||
        } else {
 | 
			
		||||
            cpu_physical_memory_write_rom(rom->addr, rom->data, rom->datasize);
 | 
			
		||||
        }
 | 
			
		||||
        if (rom->isrom) {
 | 
			
		||||
            /* rom needs to be written only once */
 | 
			
		||||
            g_free(rom->data);
 | 
			
		||||
@@ -781,6 +812,9 @@ static Rom *find_rom(hwaddr addr)
 | 
			
		||||
        if (rom->fw_file) {
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
        if (rom->mr) {
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
        if (rom->addr > addr) {
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
@@ -808,15 +842,15 @@ int rom_copy(uint8_t *dest, hwaddr addr, size_t size)
 | 
			
		||||
        if (rom->fw_file) {
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
        if (rom->mr) {
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
        if (rom->addr + rom->romsize < addr) {
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
        if (rom->addr > end) {
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
        if (!rom->data) {
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        d = dest + (rom->addr - addr);
 | 
			
		||||
        s = rom->data;
 | 
			
		||||
@@ -826,7 +860,9 @@ int rom_copy(uint8_t *dest, hwaddr addr, size_t size)
 | 
			
		||||
            l = dest - d;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        memcpy(d, s, l);
 | 
			
		||||
        if (l > 0) {
 | 
			
		||||
            memcpy(d, s, l);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (rom->romsize > rom->datasize) {
 | 
			
		||||
            /* If datasize is less than romsize, it means that we didn't
 | 
			
		||||
@@ -867,7 +903,13 @@ void do_info_roms(Monitor *mon, const QDict *qdict)
 | 
			
		||||
    Rom *rom;
 | 
			
		||||
 | 
			
		||||
    QTAILQ_FOREACH(rom, &roms, next) {
 | 
			
		||||
        if (!rom->fw_file) {
 | 
			
		||||
        if (rom->mr) {
 | 
			
		||||
            monitor_printf(mon, "%s"
 | 
			
		||||
                           " size=0x%06zx name=\"%s\"\n",
 | 
			
		||||
                           rom->mr->name,
 | 
			
		||||
                           rom->romsize,
 | 
			
		||||
                           rom->name);
 | 
			
		||||
        } else if (!rom->fw_file) {
 | 
			
		||||
            monitor_printf(mon, "addr=" TARGET_FMT_plx
 | 
			
		||||
                           " size=0x%06zx mem=%s name=\"%s\"\n",
 | 
			
		||||
                           rom->addr, rom->romsize,
 | 
			
		||||
 
 | 
			
		||||
@@ -24,7 +24,6 @@ static QEMUMachine machine_none = {
 | 
			
		||||
    .desc = "empty machine",
 | 
			
		||||
    .init = machine_none_init,
 | 
			
		||||
    .max_cpus = 0,
 | 
			
		||||
    DEFAULT_MACHINE_OPTIONS,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void register_machines(void)
 | 
			
		||||
 
 | 
			
		||||
@@ -752,7 +752,6 @@ static void device_initfn(Object *obj)
 | 
			
		||||
        }
 | 
			
		||||
        class = object_class_get_parent(class);
 | 
			
		||||
    } while (class != object_class_by_name(TYPE_DEVICE));
 | 
			
		||||
    qdev_prop_set_globals(dev, &err);
 | 
			
		||||
    if (err != NULL) {
 | 
			
		||||
        qerror_report_err(err);
 | 
			
		||||
        error_free(err);
 | 
			
		||||
@@ -764,6 +763,15 @@ static void device_initfn(Object *obj)
 | 
			
		||||
    assert_no_error(err);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void device_post_init(Object *obj)
 | 
			
		||||
{
 | 
			
		||||
    DeviceState *dev = DEVICE(obj);
 | 
			
		||||
    Error *err = NULL;
 | 
			
		||||
 | 
			
		||||
    qdev_prop_set_globals(dev, &err);
 | 
			
		||||
    assert_no_error(err);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Unlink device from bus and free the structure.  */
 | 
			
		||||
static void device_finalize(Object *obj)
 | 
			
		||||
{
 | 
			
		||||
@@ -853,6 +861,7 @@ static const TypeInfo device_type_info = {
 | 
			
		||||
    .parent = TYPE_OBJECT,
 | 
			
		||||
    .instance_size = sizeof(DeviceState),
 | 
			
		||||
    .instance_init = device_initfn,
 | 
			
		||||
    .instance_post_init = device_post_init,
 | 
			
		||||
    .instance_finalize = device_finalize,
 | 
			
		||||
    .class_base_init = device_class_base_init,
 | 
			
		||||
    .class_init = device_class_init,
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,5 @@
 | 
			
		||||
obj-$(CONFIG_ARM11MPCORE) += arm11mpcore.o
 | 
			
		||||
obj-$(CONFIG_ARM9MPCORE) += a9mpcore.o
 | 
			
		||||
obj-$(CONFIG_ARM15MPCORE) += a15mpcore.o
 | 
			
		||||
obj-$(CONFIG_A9MPCORE) += a9mpcore.o
 | 
			
		||||
obj-$(CONFIG_A15MPCORE) += a15mpcore.o
 | 
			
		||||
obj-$(CONFIG_ICC_BUS) += icc_bus.o
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -49,6 +49,8 @@ static int a15mp_priv_init(SysBusDevice *dev)
 | 
			
		||||
    A15MPPrivState *s = A15MPCORE_PRIV(dev);
 | 
			
		||||
    SysBusDevice *busdev;
 | 
			
		||||
    const char *gictype = "arm_gic";
 | 
			
		||||
    int i;
 | 
			
		||||
    CPUState *cpu;
 | 
			
		||||
 | 
			
		||||
    if (kvm_irqchip_in_kernel()) {
 | 
			
		||||
        gictype = "kvm-arm-gic";
 | 
			
		||||
@@ -67,6 +69,22 @@ static int a15mp_priv_init(SysBusDevice *dev)
 | 
			
		||||
    /* Pass through inbound GPIO lines to the GIC */
 | 
			
		||||
    qdev_init_gpio_in(DEVICE(dev), a15mp_priv_set_irq, s->num_irq - 32);
 | 
			
		||||
 | 
			
		||||
    /* Wire the outputs from each CPU's generic timer to the
 | 
			
		||||
     * appropriate GIC PPI inputs
 | 
			
		||||
     */
 | 
			
		||||
    for (i = 0, cpu = first_cpu; i < s->num_cpu; i++, cpu = cpu->next_cpu) {
 | 
			
		||||
        DeviceState *cpudev = DEVICE(cpu);
 | 
			
		||||
        int ppibase = s->num_irq - 32 + i * 32;
 | 
			
		||||
        /* physical timer; we wire it up to the non-secure timer's ID,
 | 
			
		||||
         * since a real A15 always has TrustZone but QEMU doesn't.
 | 
			
		||||
         */
 | 
			
		||||
        qdev_connect_gpio_out(cpudev, 0,
 | 
			
		||||
                              qdev_get_gpio_in(s->gic, ppibase + 30));
 | 
			
		||||
        /* virtual timer */
 | 
			
		||||
        qdev_connect_gpio_out(cpudev, 1,
 | 
			
		||||
                              qdev_get_gpio_in(s->gic, ppibase + 27));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* Memory map (addresses are offsets from PERIPHBASE):
 | 
			
		||||
     *  0x0000-0x0fff -- reserved
 | 
			
		||||
     *  0x1000-0x1fff -- GIC Distributor
 | 
			
		||||
 
 | 
			
		||||
@@ -355,7 +355,6 @@ static QEMUMachine axisdev88_machine = {
 | 
			
		||||
    .desc = "AXIS devboard 88",
 | 
			
		||||
    .init = axisdev88_init,
 | 
			
		||||
    .is_default = 1,
 | 
			
		||||
    DEFAULT_MACHINE_OPTIONS,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void axisdev88_machine_init(void)
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,7 @@
 | 
			
		||||
obj-$(CONFIG_KVM) += kvm/
 | 
			
		||||
obj-y += multiboot.o smbios.o
 | 
			
		||||
obj-y += pc.o pc_piix.o pc_q35.o
 | 
			
		||||
obj-y += pc_sysfw.o
 | 
			
		||||
obj-$(CONFIG_XEN) += xen_domainbuild.o xen_machine_pv.o
 | 
			
		||||
 | 
			
		||||
obj-y += kvmvapic.o
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										15
									
								
								hw/i386/pc.c
									
									
									
									
									
								
							
							
						
						
									
										15
									
								
								hw/i386/pc.c
									
									
									
									
									
								
							@@ -912,20 +912,19 @@ static X86CPU *pc_new_cpu(const char *cpu_model, int64_t apic_id,
 | 
			
		||||
    X86CPU *cpu;
 | 
			
		||||
    Error *local_err = NULL;
 | 
			
		||||
 | 
			
		||||
    cpu = cpu_x86_create(cpu_model, icc_bridge, errp);
 | 
			
		||||
    if (!cpu) {
 | 
			
		||||
        return cpu;
 | 
			
		||||
    cpu = cpu_x86_create(cpu_model, icc_bridge, &local_err);
 | 
			
		||||
    if (local_err != NULL) {
 | 
			
		||||
        error_propagate(errp, local_err);
 | 
			
		||||
        return NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    object_property_set_int(OBJECT(cpu), apic_id, "apic-id", &local_err);
 | 
			
		||||
    object_property_set_bool(OBJECT(cpu), true, "realized", &local_err);
 | 
			
		||||
 | 
			
		||||
    if (local_err) {
 | 
			
		||||
        if (cpu != NULL) {
 | 
			
		||||
            object_unref(OBJECT(cpu));
 | 
			
		||||
            cpu = NULL;
 | 
			
		||||
        }
 | 
			
		||||
        error_propagate(errp, local_err);
 | 
			
		||||
        object_unref(OBJECT(cpu));
 | 
			
		||||
        cpu = NULL;
 | 
			
		||||
    }
 | 
			
		||||
    return cpu;
 | 
			
		||||
}
 | 
			
		||||
@@ -1146,7 +1145,7 @@ FWCfgState *pc_memory_init(MemoryRegion *system_memory,
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    /* Initialize PC system firmware */
 | 
			
		||||
    pc_system_firmware_init(rom_memory);
 | 
			
		||||
    pc_system_firmware_init(rom_memory, guest_info->isapc_ram_fw);
 | 
			
		||||
 | 
			
		||||
    option_rom_mr = g_malloc(sizeof(*option_rom_mr));
 | 
			
		||||
    memory_region_init_ram(option_rom_mr, NULL, "pc.rom", PC_ROM_SIZE);
 | 
			
		||||
 
 | 
			
		||||
@@ -25,6 +25,7 @@
 | 
			
		||||
#include <glib.h>
 | 
			
		||||
 | 
			
		||||
#include "hw/hw.h"
 | 
			
		||||
#include "hw/loader.h"
 | 
			
		||||
#include "hw/i386/pc.h"
 | 
			
		||||
#include "hw/i386/apic.h"
 | 
			
		||||
#include "hw/pci/pci.h"
 | 
			
		||||
@@ -56,21 +57,16 @@ 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 bool has_pvpanic = true;
 | 
			
		||||
static bool has_pvpanic;
 | 
			
		||||
static bool has_pci_info = true;
 | 
			
		||||
 | 
			
		||||
/* PC hardware initialisation */
 | 
			
		||||
static void pc_init1(MemoryRegion *system_memory,
 | 
			
		||||
                     MemoryRegion *system_io,
 | 
			
		||||
                     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 void pc_init1(QEMUMachineInitArgs *args,
 | 
			
		||||
                     int pci_enabled,
 | 
			
		||||
                     int kvmclock_enabled)
 | 
			
		||||
{
 | 
			
		||||
    MemoryRegion *system_memory = get_system_memory();
 | 
			
		||||
    MemoryRegion *system_io = get_system_io();
 | 
			
		||||
    int i;
 | 
			
		||||
    ram_addr_t below_4g_mem_size, above_4g_mem_size;
 | 
			
		||||
    PCIBus *pci_bus;
 | 
			
		||||
@@ -102,19 +98,18 @@ static void pc_init1(MemoryRegion *system_memory,
 | 
			
		||||
    object_property_add_child(qdev_get_machine(), "icc-bridge",
 | 
			
		||||
                              OBJECT(icc_bridge), NULL);
 | 
			
		||||
 | 
			
		||||
    pc_cpus_init(cpu_model, icc_bridge);
 | 
			
		||||
    pc_acpi_init("acpi-dsdt.aml");
 | 
			
		||||
    pc_cpus_init(args->cpu_model, icc_bridge);
 | 
			
		||||
 | 
			
		||||
    if (kvm_enabled() && kvmclock_enabled) {
 | 
			
		||||
        kvmclock_create();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (ram_size >= 0xe0000000 ) {
 | 
			
		||||
        above_4g_mem_size = ram_size - 0xe0000000;
 | 
			
		||||
    if (args->ram_size >= 0xe0000000) {
 | 
			
		||||
        above_4g_mem_size = args->ram_size - 0xe0000000;
 | 
			
		||||
        below_4g_mem_size = 0xe0000000;
 | 
			
		||||
    } else {
 | 
			
		||||
        above_4g_mem_size = 0;
 | 
			
		||||
        below_4g_mem_size = ram_size;
 | 
			
		||||
        below_4g_mem_size = args->ram_size;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (pci_enabled) {
 | 
			
		||||
@@ -128,11 +123,13 @@ static void pc_init1(MemoryRegion *system_memory,
 | 
			
		||||
 | 
			
		||||
    guest_info = pc_guest_info_init(below_4g_mem_size, above_4g_mem_size);
 | 
			
		||||
    guest_info->has_pci_info = has_pci_info;
 | 
			
		||||
    guest_info->isapc_ram_fw = !pci_enabled;
 | 
			
		||||
 | 
			
		||||
    /* allocate ram and load rom/bios */
 | 
			
		||||
    if (!xen_enabled()) {
 | 
			
		||||
        fw_cfg = pc_memory_init(system_memory,
 | 
			
		||||
                       kernel_filename, kernel_cmdline, initrd_filename,
 | 
			
		||||
                       args->kernel_filename, args->kernel_cmdline,
 | 
			
		||||
                       args->initrd_filename,
 | 
			
		||||
                       below_4g_mem_size, above_4g_mem_size,
 | 
			
		||||
                       rom_memory, &ram_memory, guest_info);
 | 
			
		||||
    }
 | 
			
		||||
@@ -148,7 +145,7 @@ static void pc_init1(MemoryRegion *system_memory,
 | 
			
		||||
 | 
			
		||||
    if (pci_enabled) {
 | 
			
		||||
        pci_bus = i440fx_init(&i440fx_state, &piix3_devfn, &isa_bus, gsi,
 | 
			
		||||
                              system_memory, system_io, ram_size,
 | 
			
		||||
                              system_memory, system_io, args->ram_size,
 | 
			
		||||
                              below_4g_mem_size,
 | 
			
		||||
                              0x100000000ULL - below_4g_mem_size,
 | 
			
		||||
                              above_4g_mem_size,
 | 
			
		||||
@@ -207,7 +204,7 @@ static void pc_init1(MemoryRegion *system_memory,
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pc_cmos_init(below_4g_mem_size, above_4g_mem_size, boot_device,
 | 
			
		||||
    pc_cmos_init(below_4g_mem_size, above_4g_mem_size, args->boot_order,
 | 
			
		||||
                 floppy, idebus[0], idebus[1], rtc_state);
 | 
			
		||||
 | 
			
		||||
    if (pci_enabled && usb_enabled(false)) {
 | 
			
		||||
@@ -236,90 +233,91 @@ static void pc_init1(MemoryRegion *system_memory,
 | 
			
		||||
 | 
			
		||||
static void pc_init_pci(QEMUMachineInitArgs *args)
 | 
			
		||||
{
 | 
			
		||||
    ram_addr_t ram_size = args->ram_size;
 | 
			
		||||
    const char *cpu_model = args->cpu_model;
 | 
			
		||||
    const char *kernel_filename = args->kernel_filename;
 | 
			
		||||
    const char *kernel_cmdline = args->kernel_cmdline;
 | 
			
		||||
    const char *initrd_filename = args->initrd_filename;
 | 
			
		||||
    const char *boot_device = args->boot_device;
 | 
			
		||||
    pc_init1(get_system_memory(),
 | 
			
		||||
             get_system_io(),
 | 
			
		||||
             ram_size, boot_device,
 | 
			
		||||
             kernel_filename, kernel_cmdline,
 | 
			
		||||
             initrd_filename, cpu_model, 1, 1);
 | 
			
		||||
    pc_init1(args, 1, 1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void pc_compat_1_6(QEMUMachineInitArgs *args)
 | 
			
		||||
{
 | 
			
		||||
    has_pci_info = false;
 | 
			
		||||
    rom_file_in_ram = false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void pc_compat_1_5(QEMUMachineInitArgs *args)
 | 
			
		||||
{
 | 
			
		||||
    pc_compat_1_6(args);
 | 
			
		||||
    has_pvpanic = true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void pc_compat_1_4(QEMUMachineInitArgs *args)
 | 
			
		||||
{
 | 
			
		||||
    pc_compat_1_5(args);
 | 
			
		||||
    has_pvpanic = false;
 | 
			
		||||
    x86_cpu_compat_set_features("n270", FEAT_1_ECX, 0, CPUID_EXT_MOVBE);
 | 
			
		||||
    x86_cpu_compat_set_features("Westmere", FEAT_1_ECX, 0, CPUID_EXT_PCLMULQDQ);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void pc_compat_1_3(QEMUMachineInitArgs *args)
 | 
			
		||||
{
 | 
			
		||||
    pc_compat_1_4(args);
 | 
			
		||||
    enable_compat_apic_id_mode();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* PC compat function for pc-0.14 to pc-1.2 */
 | 
			
		||||
static void pc_compat_1_2(QEMUMachineInitArgs *args)
 | 
			
		||||
{
 | 
			
		||||
    pc_compat_1_3(args);
 | 
			
		||||
    disable_kvm_pv_eoi();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void pc_init_pci_1_6(QEMUMachineInitArgs *args)
 | 
			
		||||
{
 | 
			
		||||
    pc_compat_1_6(args);
 | 
			
		||||
    pc_init_pci(args);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void pc_init_pci_1_5(QEMUMachineInitArgs *args)
 | 
			
		||||
{
 | 
			
		||||
    has_pci_info = false;
 | 
			
		||||
    pc_compat_1_5(args);
 | 
			
		||||
    pc_init_pci(args);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void pc_init_pci_1_4(QEMUMachineInitArgs *args)
 | 
			
		||||
{
 | 
			
		||||
    has_pvpanic = false;
 | 
			
		||||
    x86_cpu_compat_set_features("n270", FEAT_1_ECX, 0, CPUID_EXT_MOVBE);
 | 
			
		||||
    pc_init_pci_1_5(args);
 | 
			
		||||
    pc_compat_1_4(args);
 | 
			
		||||
    pc_init_pci(args);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void pc_init_pci_1_3(QEMUMachineInitArgs *args)
 | 
			
		||||
{
 | 
			
		||||
    enable_compat_apic_id_mode();
 | 
			
		||||
    pc_init_pci_1_4(args);
 | 
			
		||||
    pc_compat_1_3(args);
 | 
			
		||||
    pc_init_pci(args);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* PC machine init function for pc-1.1 to pc-1.2 */
 | 
			
		||||
/* PC machine init function for pc-0.14 to pc-1.2 */
 | 
			
		||||
static void pc_init_pci_1_2(QEMUMachineInitArgs *args)
 | 
			
		||||
{
 | 
			
		||||
    disable_kvm_pv_eoi();
 | 
			
		||||
    pc_init_pci_1_3(args);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* PC machine init function for pc-0.14 to pc-1.0 */
 | 
			
		||||
static void pc_init_pci_1_0(QEMUMachineInitArgs *args)
 | 
			
		||||
{
 | 
			
		||||
    pc_init_pci_1_2(args);
 | 
			
		||||
    pc_compat_1_2(args);
 | 
			
		||||
    pc_init_pci(args);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* PC init function for pc-0.10 to pc-0.13, and reused by xenfv */
 | 
			
		||||
static void pc_init_pci_no_kvmclock(QEMUMachineInitArgs *args)
 | 
			
		||||
{
 | 
			
		||||
    ram_addr_t ram_size = args->ram_size;
 | 
			
		||||
    const char *cpu_model = args->cpu_model;
 | 
			
		||||
    const char *kernel_filename = args->kernel_filename;
 | 
			
		||||
    const char *kernel_cmdline = args->kernel_cmdline;
 | 
			
		||||
    const char *initrd_filename = args->initrd_filename;
 | 
			
		||||
    const char *boot_device = args->boot_device;
 | 
			
		||||
    has_pvpanic = false;
 | 
			
		||||
    has_pci_info = false;
 | 
			
		||||
    disable_kvm_pv_eoi();
 | 
			
		||||
    enable_compat_apic_id_mode();
 | 
			
		||||
    pc_init1(get_system_memory(),
 | 
			
		||||
             get_system_io(),
 | 
			
		||||
             ram_size, boot_device,
 | 
			
		||||
             kernel_filename, kernel_cmdline,
 | 
			
		||||
             initrd_filename, cpu_model, 1, 0);
 | 
			
		||||
    pc_init1(args, 1, 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void pc_init_isa(QEMUMachineInitArgs *args)
 | 
			
		||||
{
 | 
			
		||||
    ram_addr_t ram_size = args->ram_size;
 | 
			
		||||
    const char *cpu_model = args->cpu_model;
 | 
			
		||||
    const char *kernel_filename = args->kernel_filename;
 | 
			
		||||
    const char *kernel_cmdline = args->kernel_cmdline;
 | 
			
		||||
    const char *initrd_filename = args->initrd_filename;
 | 
			
		||||
    const char *boot_device = args->boot_device;
 | 
			
		||||
    has_pvpanic = false;
 | 
			
		||||
    has_pci_info = false;
 | 
			
		||||
    if (cpu_model == NULL)
 | 
			
		||||
        cpu_model = "486";
 | 
			
		||||
    if (!args->cpu_model) {
 | 
			
		||||
        args->cpu_model = "486";
 | 
			
		||||
    }
 | 
			
		||||
    disable_kvm_pv_eoi();
 | 
			
		||||
    enable_compat_apic_id_mode();
 | 
			
		||||
    pc_init1(get_system_memory(),
 | 
			
		||||
             get_system_io(),
 | 
			
		||||
             ram_size, boot_device,
 | 
			
		||||
             kernel_filename, kernel_cmdline,
 | 
			
		||||
             initrd_filename, cpu_model, 0, 1);
 | 
			
		||||
    pc_init1(args, 0, 1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#ifdef CONFIG_XEN
 | 
			
		||||
@@ -336,40 +334,43 @@ static void pc_xen_hvm_init(QEMUMachineInitArgs *args)
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define PC_I440FX_MACHINE_OPTIONS \
 | 
			
		||||
    PC_DEFAULT_MACHINE_OPTIONS, \
 | 
			
		||||
    .desc = "Standard PC (i440FX + PIIX, 1996)", \
 | 
			
		||||
    .hot_add_cpu = pc_hot_add_cpu
 | 
			
		||||
 | 
			
		||||
#define PC_I440FX_1_6_MACHINE_OPTIONS PC_I440FX_MACHINE_OPTIONS
 | 
			
		||||
 | 
			
		||||
static QEMUMachine pc_i440fx_machine_v1_6 = {
 | 
			
		||||
    PC_I440FX_1_6_MACHINE_OPTIONS,
 | 
			
		||||
    .name = "pc-i440fx-1.6",
 | 
			
		||||
    .alias = "pc",
 | 
			
		||||
    .desc = "Standard PC (i440FX + PIIX, 1996)",
 | 
			
		||||
    .init = pc_init_pci,
 | 
			
		||||
    .hot_add_cpu = pc_hot_add_cpu,
 | 
			
		||||
    .max_cpus = 255,
 | 
			
		||||
    .init = pc_init_pci_1_6,
 | 
			
		||||
    .is_default = 1,
 | 
			
		||||
    DEFAULT_MACHINE_OPTIONS,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static QEMUMachine pc_i440fx_machine_v1_5 = {
 | 
			
		||||
    PC_I440FX_1_6_MACHINE_OPTIONS,
 | 
			
		||||
    .name = "pc-i440fx-1.5",
 | 
			
		||||
    .desc = "Standard PC (i440FX + PIIX, 1996)",
 | 
			
		||||
    .init = pc_init_pci_1_5,
 | 
			
		||||
    .hot_add_cpu = pc_hot_add_cpu,
 | 
			
		||||
    .max_cpus = 255,
 | 
			
		||||
    .compat_props = (GlobalProperty[]) {
 | 
			
		||||
        PC_COMPAT_1_5,
 | 
			
		||||
        { /* end of list */ }
 | 
			
		||||
    },
 | 
			
		||||
    DEFAULT_MACHINE_OPTIONS,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#define PC_I440FX_1_4_MACHINE_OPTIONS \
 | 
			
		||||
    PC_I440FX_1_6_MACHINE_OPTIONS, \
 | 
			
		||||
    .hot_add_cpu = NULL
 | 
			
		||||
 | 
			
		||||
static QEMUMachine pc_i440fx_machine_v1_4 = {
 | 
			
		||||
    PC_I440FX_1_4_MACHINE_OPTIONS,
 | 
			
		||||
    .name = "pc-i440fx-1.4",
 | 
			
		||||
    .desc = "Standard PC (i440FX + PIIX, 1996)",
 | 
			
		||||
    .init = pc_init_pci_1_4,
 | 
			
		||||
    .max_cpus = 255,
 | 
			
		||||
    .compat_props = (GlobalProperty[]) {
 | 
			
		||||
        PC_COMPAT_1_4,
 | 
			
		||||
        { /* end of list */ }
 | 
			
		||||
    },
 | 
			
		||||
    DEFAULT_MACHINE_OPTIONS,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#define PC_COMPAT_1_3 \
 | 
			
		||||
@@ -393,15 +394,13 @@ static QEMUMachine pc_i440fx_machine_v1_4 = {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
static QEMUMachine pc_machine_v1_3 = {
 | 
			
		||||
    PC_I440FX_1_4_MACHINE_OPTIONS,
 | 
			
		||||
    .name = "pc-1.3",
 | 
			
		||||
    .desc = "Standard PC",
 | 
			
		||||
    .init = pc_init_pci_1_3,
 | 
			
		||||
    .max_cpus = 255,
 | 
			
		||||
    .compat_props = (GlobalProperty[]) {
 | 
			
		||||
        PC_COMPAT_1_3,
 | 
			
		||||
        { /* end of list */ }
 | 
			
		||||
    },
 | 
			
		||||
    DEFAULT_MACHINE_OPTIONS,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#define PC_COMPAT_1_2 \
 | 
			
		||||
@@ -432,16 +431,17 @@ static QEMUMachine pc_machine_v1_3 = {
 | 
			
		||||
            .value    = "off",\
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
#define PC_I440FX_1_2_MACHINE_OPTIONS \
 | 
			
		||||
    PC_I440FX_1_4_MACHINE_OPTIONS, \
 | 
			
		||||
    .init = pc_init_pci_1_2
 | 
			
		||||
 | 
			
		||||
static QEMUMachine pc_machine_v1_2 = {
 | 
			
		||||
    PC_I440FX_1_2_MACHINE_OPTIONS,
 | 
			
		||||
    .name = "pc-1.2",
 | 
			
		||||
    .desc = "Standard PC",
 | 
			
		||||
    .init = pc_init_pci_1_2,
 | 
			
		||||
    .max_cpus = 255,
 | 
			
		||||
    .compat_props = (GlobalProperty[]) {
 | 
			
		||||
        PC_COMPAT_1_2,
 | 
			
		||||
        { /* end of list */ }
 | 
			
		||||
    },
 | 
			
		||||
    DEFAULT_MACHINE_OPTIONS,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#define PC_COMPAT_1_1 \
 | 
			
		||||
@@ -477,24 +477,17 @@ static QEMUMachine pc_machine_v1_2 = {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
static QEMUMachine pc_machine_v1_1 = {
 | 
			
		||||
    PC_I440FX_1_2_MACHINE_OPTIONS,
 | 
			
		||||
    .name = "pc-1.1",
 | 
			
		||||
    .desc = "Standard PC",
 | 
			
		||||
    .init = pc_init_pci_1_2,
 | 
			
		||||
    .max_cpus = 255,
 | 
			
		||||
    .compat_props = (GlobalProperty[]) {
 | 
			
		||||
        PC_COMPAT_1_1,
 | 
			
		||||
        { /* end of list */ }
 | 
			
		||||
    },
 | 
			
		||||
    DEFAULT_MACHINE_OPTIONS,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#define PC_COMPAT_1_0 \
 | 
			
		||||
        PC_COMPAT_1_1,\
 | 
			
		||||
        {\
 | 
			
		||||
            .driver   = "pc-sysfw",\
 | 
			
		||||
            .property = "rom_only",\
 | 
			
		||||
            .value    = stringify(1),\
 | 
			
		||||
        }, {\
 | 
			
		||||
            .driver   = TYPE_ISA_FDC,\
 | 
			
		||||
            .property = "check_media_rate",\
 | 
			
		||||
            .value    = "off",\
 | 
			
		||||
@@ -513,32 +506,26 @@ static QEMUMachine pc_machine_v1_1 = {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
static QEMUMachine pc_machine_v1_0 = {
 | 
			
		||||
    PC_I440FX_1_2_MACHINE_OPTIONS,
 | 
			
		||||
    .name = "pc-1.0",
 | 
			
		||||
    .desc = "Standard PC",
 | 
			
		||||
    .init = pc_init_pci_1_0,
 | 
			
		||||
    .max_cpus = 255,
 | 
			
		||||
    .compat_props = (GlobalProperty[]) {
 | 
			
		||||
        PC_COMPAT_1_0,
 | 
			
		||||
        { /* end of list */ }
 | 
			
		||||
    },
 | 
			
		||||
    .hw_version = "1.0",
 | 
			
		||||
    DEFAULT_MACHINE_OPTIONS,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#define PC_COMPAT_0_15 \
 | 
			
		||||
        PC_COMPAT_1_0
 | 
			
		||||
 | 
			
		||||
static QEMUMachine pc_machine_v0_15 = {
 | 
			
		||||
    PC_I440FX_1_2_MACHINE_OPTIONS,
 | 
			
		||||
    .name = "pc-0.15",
 | 
			
		||||
    .desc = "Standard PC",
 | 
			
		||||
    .init = pc_init_pci_1_0,
 | 
			
		||||
    .max_cpus = 255,
 | 
			
		||||
    .compat_props = (GlobalProperty[]) {
 | 
			
		||||
        PC_COMPAT_0_15,
 | 
			
		||||
        { /* end of list */ }
 | 
			
		||||
    },
 | 
			
		||||
    .hw_version = "0.15",
 | 
			
		||||
    DEFAULT_MACHINE_OPTIONS,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#define PC_COMPAT_0_14 \
 | 
			
		||||
@@ -562,10 +549,8 @@ static QEMUMachine pc_machine_v0_15 = {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
static QEMUMachine pc_machine_v0_14 = {
 | 
			
		||||
    PC_I440FX_1_2_MACHINE_OPTIONS,
 | 
			
		||||
    .name = "pc-0.14",
 | 
			
		||||
    .desc = "Standard PC",
 | 
			
		||||
    .init = pc_init_pci_1_0,
 | 
			
		||||
    .max_cpus = 255,
 | 
			
		||||
    .compat_props = (GlobalProperty[]) {
 | 
			
		||||
        PC_COMPAT_0_14, 
 | 
			
		||||
        {
 | 
			
		||||
@@ -580,7 +565,6 @@ static QEMUMachine pc_machine_v0_14 = {
 | 
			
		||||
        { /* end of list */ }
 | 
			
		||||
    },
 | 
			
		||||
    .hw_version = "0.14",
 | 
			
		||||
    DEFAULT_MACHINE_OPTIONS,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#define PC_COMPAT_0_13 \
 | 
			
		||||
@@ -595,11 +579,13 @@ static QEMUMachine pc_machine_v0_14 = {
 | 
			
		||||
            .value    = stringify(1),\
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
#define PC_I440FX_0_13_MACHINE_OPTIONS \
 | 
			
		||||
    PC_I440FX_1_2_MACHINE_OPTIONS, \
 | 
			
		||||
    .init = pc_init_pci_no_kvmclock
 | 
			
		||||
 | 
			
		||||
static QEMUMachine pc_machine_v0_13 = {
 | 
			
		||||
    PC_I440FX_0_13_MACHINE_OPTIONS,
 | 
			
		||||
    .name = "pc-0.13",
 | 
			
		||||
    .desc = "Standard PC",
 | 
			
		||||
    .init = pc_init_pci_no_kvmclock,
 | 
			
		||||
    .max_cpus = 255,
 | 
			
		||||
    .compat_props = (GlobalProperty[]) {
 | 
			
		||||
        PC_COMPAT_0_13,
 | 
			
		||||
        {
 | 
			
		||||
@@ -618,7 +604,6 @@ static QEMUMachine pc_machine_v0_13 = {
 | 
			
		||||
        { /* end of list */ }
 | 
			
		||||
    },
 | 
			
		||||
    .hw_version = "0.13",
 | 
			
		||||
    DEFAULT_MACHINE_OPTIONS,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#define PC_COMPAT_0_12 \
 | 
			
		||||
@@ -646,10 +631,8 @@ static QEMUMachine pc_machine_v0_13 = {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
static QEMUMachine pc_machine_v0_12 = {
 | 
			
		||||
    PC_I440FX_0_13_MACHINE_OPTIONS,
 | 
			
		||||
    .name = "pc-0.12",
 | 
			
		||||
    .desc = "Standard PC",
 | 
			
		||||
    .init = pc_init_pci_no_kvmclock,
 | 
			
		||||
    .max_cpus = 255,
 | 
			
		||||
    .compat_props = (GlobalProperty[]) {
 | 
			
		||||
        PC_COMPAT_0_12,
 | 
			
		||||
        {
 | 
			
		||||
@@ -664,7 +647,6 @@ static QEMUMachine pc_machine_v0_12 = {
 | 
			
		||||
        { /* end of list */ }
 | 
			
		||||
    },
 | 
			
		||||
    .hw_version = "0.12",
 | 
			
		||||
    DEFAULT_MACHINE_OPTIONS,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#define PC_COMPAT_0_11 \
 | 
			
		||||
@@ -680,10 +662,8 @@ static QEMUMachine pc_machine_v0_12 = {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
static QEMUMachine pc_machine_v0_11 = {
 | 
			
		||||
    PC_I440FX_0_13_MACHINE_OPTIONS,
 | 
			
		||||
    .name = "pc-0.11",
 | 
			
		||||
    .desc = "Standard PC, qemu 0.11",
 | 
			
		||||
    .init = pc_init_pci_no_kvmclock,
 | 
			
		||||
    .max_cpus = 255,
 | 
			
		||||
    .compat_props = (GlobalProperty[]) {
 | 
			
		||||
        PC_COMPAT_0_11,
 | 
			
		||||
        {
 | 
			
		||||
@@ -698,14 +678,11 @@ static QEMUMachine pc_machine_v0_11 = {
 | 
			
		||||
        { /* end of list */ }
 | 
			
		||||
    },
 | 
			
		||||
    .hw_version = "0.11",
 | 
			
		||||
    DEFAULT_MACHINE_OPTIONS,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static QEMUMachine pc_machine_v0_10 = {
 | 
			
		||||
    PC_I440FX_0_13_MACHINE_OPTIONS,
 | 
			
		||||
    .name = "pc-0.10",
 | 
			
		||||
    .desc = "Standard PC, qemu 0.10",
 | 
			
		||||
    .init = pc_init_pci_no_kvmclock,
 | 
			
		||||
    .max_cpus = 255,
 | 
			
		||||
    .compat_props = (GlobalProperty[]) {
 | 
			
		||||
        PC_COMPAT_0_11,
 | 
			
		||||
        {
 | 
			
		||||
@@ -732,38 +709,27 @@ static QEMUMachine pc_machine_v0_10 = {
 | 
			
		||||
        { /* end of list */ }
 | 
			
		||||
    },
 | 
			
		||||
    .hw_version = "0.10",
 | 
			
		||||
    DEFAULT_MACHINE_OPTIONS,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static QEMUMachine isapc_machine = {
 | 
			
		||||
    PC_COMMON_MACHINE_OPTIONS,
 | 
			
		||||
    .name = "isapc",
 | 
			
		||||
    .desc = "ISA-only PC",
 | 
			
		||||
    .init = pc_init_isa,
 | 
			
		||||
    .max_cpus = 1,
 | 
			
		||||
    .compat_props = (GlobalProperty[]) {
 | 
			
		||||
        {
 | 
			
		||||
            .driver   = "pc-sysfw",
 | 
			
		||||
            .property = "rom_only",
 | 
			
		||||
            .value    = stringify(1),
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
            .driver   = "pc-sysfw",
 | 
			
		||||
            .property = "isapc_ram_fw",
 | 
			
		||||
            .value    = stringify(1),
 | 
			
		||||
        },
 | 
			
		||||
        { /* end of list */ }
 | 
			
		||||
    },
 | 
			
		||||
    DEFAULT_MACHINE_OPTIONS,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#ifdef CONFIG_XEN
 | 
			
		||||
static QEMUMachine xenfv_machine = {
 | 
			
		||||
    PC_COMMON_MACHINE_OPTIONS,
 | 
			
		||||
    .name = "xenfv",
 | 
			
		||||
    .desc = "Xen Fully-virtualized PC",
 | 
			
		||||
    .init = pc_xen_hvm_init,
 | 
			
		||||
    .max_cpus = HVM_MAX_VCPUS,
 | 
			
		||||
    .default_machine_opts = "accel=xen",
 | 
			
		||||
    DEFAULT_MACHINE_OPTIONS,
 | 
			
		||||
};
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -28,6 +28,7 @@
 | 
			
		||||
 * THE SOFTWARE.
 | 
			
		||||
 */
 | 
			
		||||
#include "hw/hw.h"
 | 
			
		||||
#include "hw/loader.h"
 | 
			
		||||
#include "sysemu/arch_init.h"
 | 
			
		||||
#include "hw/i2c/smbus.h"
 | 
			
		||||
#include "hw/boards.h"
 | 
			
		||||
@@ -46,18 +47,12 @@
 | 
			
		||||
/* ICH9 AHCI has 6 ports */
 | 
			
		||||
#define MAX_SATA_PORTS     6
 | 
			
		||||
 | 
			
		||||
static bool has_pvpanic = true;
 | 
			
		||||
static bool has_pvpanic;
 | 
			
		||||
static bool has_pci_info = true;
 | 
			
		||||
 | 
			
		||||
/* PC hardware initialisation */
 | 
			
		||||
static void pc_q35_init(QEMUMachineInitArgs *args)
 | 
			
		||||
{
 | 
			
		||||
    ram_addr_t ram_size = args->ram_size;
 | 
			
		||||
    const char *cpu_model = args->cpu_model;
 | 
			
		||||
    const char *kernel_filename = args->kernel_filename;
 | 
			
		||||
    const char *kernel_cmdline = args->kernel_cmdline;
 | 
			
		||||
    const char *initrd_filename = args->initrd_filename;
 | 
			
		||||
    const char *boot_device = args->boot_device;
 | 
			
		||||
    ram_addr_t below_4g_mem_size, above_4g_mem_size;
 | 
			
		||||
    Q35PCIHost *q35_host;
 | 
			
		||||
    PCIHostState *phb;
 | 
			
		||||
@@ -85,17 +80,17 @@ static void pc_q35_init(QEMUMachineInitArgs *args)
 | 
			
		||||
    object_property_add_child(qdev_get_machine(), "icc-bridge",
 | 
			
		||||
                              OBJECT(icc_bridge), NULL);
 | 
			
		||||
 | 
			
		||||
    pc_cpus_init(cpu_model, icc_bridge);
 | 
			
		||||
    pc_cpus_init(args->cpu_model, icc_bridge);
 | 
			
		||||
    pc_acpi_init("q35-acpi-dsdt.aml");
 | 
			
		||||
 | 
			
		||||
    kvmclock_create();
 | 
			
		||||
 | 
			
		||||
    if (ram_size >= 0xb0000000) {
 | 
			
		||||
        above_4g_mem_size = ram_size - 0xb0000000;
 | 
			
		||||
    if (args->ram_size >= 0xb0000000) {
 | 
			
		||||
        above_4g_mem_size = args->ram_size - 0xb0000000;
 | 
			
		||||
        below_4g_mem_size = 0xb0000000;
 | 
			
		||||
    } else {
 | 
			
		||||
        above_4g_mem_size = 0;
 | 
			
		||||
        below_4g_mem_size = ram_size;
 | 
			
		||||
        below_4g_mem_size = args->ram_size;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* pci enabled */
 | 
			
		||||
@@ -110,11 +105,14 @@ static void pc_q35_init(QEMUMachineInitArgs *args)
 | 
			
		||||
 | 
			
		||||
    guest_info = pc_guest_info_init(below_4g_mem_size, above_4g_mem_size);
 | 
			
		||||
    guest_info->has_pci_info = has_pci_info;
 | 
			
		||||
    guest_info->isapc_ram_fw = false;
 | 
			
		||||
 | 
			
		||||
    /* allocate ram and load rom/bios */
 | 
			
		||||
    if (!xen_enabled()) {
 | 
			
		||||
        pc_memory_init(get_system_memory(), kernel_filename, kernel_cmdline,
 | 
			
		||||
                       initrd_filename, below_4g_mem_size, above_4g_mem_size,
 | 
			
		||||
        pc_memory_init(get_system_memory(),
 | 
			
		||||
                       args->kernel_filename, args->kernel_cmdline,
 | 
			
		||||
                       args->initrd_filename,
 | 
			
		||||
                       below_4g_mem_size, above_4g_mem_size,
 | 
			
		||||
                       rom_memory, &ram_memory, guest_info);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -202,7 +200,7 @@ static void pc_q35_init(QEMUMachineInitArgs *args)
 | 
			
		||||
                                    0xb100),
 | 
			
		||||
                      8, NULL, 0);
 | 
			
		||||
 | 
			
		||||
    pc_cmos_init(below_4g_mem_size, above_4g_mem_size, boot_device,
 | 
			
		||||
    pc_cmos_init(below_4g_mem_size, above_4g_mem_size, args->boot_order,
 | 
			
		||||
                 floppy, idebus[0], idebus[1], rtc_state);
 | 
			
		||||
 | 
			
		||||
    /* the rest devices to which pci devfn is automatically assigned */
 | 
			
		||||
@@ -217,52 +215,80 @@ static void pc_q35_init(QEMUMachineInitArgs *args)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void pc_q35_init_1_5(QEMUMachineInitArgs *args)
 | 
			
		||||
static void pc_compat_1_6(QEMUMachineInitArgs *args)
 | 
			
		||||
{
 | 
			
		||||
    has_pci_info = false;
 | 
			
		||||
    rom_file_in_ram = false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void pc_compat_1_5(QEMUMachineInitArgs *args)
 | 
			
		||||
{
 | 
			
		||||
    pc_compat_1_6(args);
 | 
			
		||||
    has_pvpanic = true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void pc_compat_1_4(QEMUMachineInitArgs *args)
 | 
			
		||||
{
 | 
			
		||||
    pc_compat_1_5(args);
 | 
			
		||||
    has_pvpanic = false;
 | 
			
		||||
    x86_cpu_compat_set_features("n270", FEAT_1_ECX, 0, CPUID_EXT_MOVBE);
 | 
			
		||||
    x86_cpu_compat_set_features("Westmere", FEAT_1_ECX, 0, CPUID_EXT_PCLMULQDQ);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void pc_q35_init_1_6(QEMUMachineInitArgs *args)
 | 
			
		||||
{
 | 
			
		||||
    pc_compat_1_6(args);
 | 
			
		||||
    pc_q35_init(args);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void pc_q35_init_1_5(QEMUMachineInitArgs *args)
 | 
			
		||||
{
 | 
			
		||||
    pc_compat_1_5(args);
 | 
			
		||||
    pc_q35_init(args);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void pc_q35_init_1_4(QEMUMachineInitArgs *args)
 | 
			
		||||
{
 | 
			
		||||
    has_pvpanic = false;
 | 
			
		||||
    x86_cpu_compat_set_features("n270", FEAT_1_ECX, 0, CPUID_EXT_MOVBE);
 | 
			
		||||
    pc_q35_init_1_5(args);
 | 
			
		||||
    pc_compat_1_4(args);
 | 
			
		||||
    pc_q35_init(args);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#define PC_Q35_MACHINE_OPTIONS \
 | 
			
		||||
    PC_DEFAULT_MACHINE_OPTIONS, \
 | 
			
		||||
    .desc = "Standard PC (Q35 + ICH9, 2009)", \
 | 
			
		||||
    .hot_add_cpu = pc_hot_add_cpu
 | 
			
		||||
 | 
			
		||||
#define PC_Q35_1_6_MACHINE_OPTIONS PC_Q35_MACHINE_OPTIONS
 | 
			
		||||
 | 
			
		||||
static QEMUMachine pc_q35_machine_v1_6 = {
 | 
			
		||||
    PC_Q35_1_6_MACHINE_OPTIONS,
 | 
			
		||||
    .name = "pc-q35-1.6",
 | 
			
		||||
    .alias = "q35",
 | 
			
		||||
    .desc = "Standard PC (Q35 + ICH9, 2009)",
 | 
			
		||||
    .init = pc_q35_init,
 | 
			
		||||
    .hot_add_cpu = pc_hot_add_cpu,
 | 
			
		||||
    .max_cpus = 255,
 | 
			
		||||
    DEFAULT_MACHINE_OPTIONS,
 | 
			
		||||
    .init = pc_q35_init_1_6,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static QEMUMachine pc_q35_machine_v1_5 = {
 | 
			
		||||
    PC_Q35_1_6_MACHINE_OPTIONS,
 | 
			
		||||
    .name = "pc-q35-1.5",
 | 
			
		||||
    .desc = "Standard PC (Q35 + ICH9, 2009)",
 | 
			
		||||
    .init = pc_q35_init_1_5,
 | 
			
		||||
    .hot_add_cpu = pc_hot_add_cpu,
 | 
			
		||||
    .max_cpus = 255,
 | 
			
		||||
    .compat_props = (GlobalProperty[]) {
 | 
			
		||||
        PC_COMPAT_1_5,
 | 
			
		||||
        { /* end of list */ }
 | 
			
		||||
    },
 | 
			
		||||
    DEFAULT_MACHINE_OPTIONS,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#define PC_Q35_1_4_MACHINE_OPTIONS \
 | 
			
		||||
    PC_Q35_1_6_MACHINE_OPTIONS, \
 | 
			
		||||
    .hot_add_cpu = NULL
 | 
			
		||||
 | 
			
		||||
static QEMUMachine pc_q35_machine_v1_4 = {
 | 
			
		||||
    PC_Q35_1_4_MACHINE_OPTIONS,
 | 
			
		||||
    .name = "pc-q35-1.4",
 | 
			
		||||
    .desc = "Standard PC (Q35 + ICH9, 2009)",
 | 
			
		||||
    .init = pc_q35_init_1_4,
 | 
			
		||||
    .max_cpus = 255,
 | 
			
		||||
    .compat_props = (GlobalProperty[]) {
 | 
			
		||||
        PC_COMPAT_1_4,
 | 
			
		||||
        { /* end of list */ }
 | 
			
		||||
    },
 | 
			
		||||
    DEFAULT_MACHINE_OPTIONS,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void pc_q35_machine_init(void)
 | 
			
		||||
 
 | 
			
		||||
@@ -38,7 +38,6 @@
 | 
			
		||||
 | 
			
		||||
typedef struct PcSysFwDevice {
 | 
			
		||||
    SysBusDevice busdev;
 | 
			
		||||
    uint8_t rom_only;
 | 
			
		||||
    uint8_t isapc_ram_fw;
 | 
			
		||||
} PcSysFwDevice;
 | 
			
		||||
 | 
			
		||||
@@ -76,39 +75,6 @@ static void pc_isa_bios_init(MemoryRegion *rom_memory,
 | 
			
		||||
    memory_region_set_readonly(isa_bios, true);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void pc_fw_add_pflash_drv(void)
 | 
			
		||||
{
 | 
			
		||||
    QemuOpts *opts;
 | 
			
		||||
    QEMUMachine *machine;
 | 
			
		||||
    char *filename;
 | 
			
		||||
 | 
			
		||||
    if (bios_name == NULL) {
 | 
			
		||||
        bios_name = BIOS_FILENAME;
 | 
			
		||||
    }
 | 
			
		||||
    filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
 | 
			
		||||
    if (!filename) {
 | 
			
		||||
        error_report("Can't open BIOS image %s", bios_name);
 | 
			
		||||
        exit(1);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    opts = drive_add(IF_PFLASH, -1, filename, "readonly=on");
 | 
			
		||||
 | 
			
		||||
    g_free(filename);
 | 
			
		||||
 | 
			
		||||
    if (opts == NULL) {
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    machine = find_default_machine();
 | 
			
		||||
    if (machine == NULL) {
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (!drive_init(opts, machine->block_default_type)) {
 | 
			
		||||
        qemu_opts_del(opts);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void pc_system_flash_init(MemoryRegion *rom_memory,
 | 
			
		||||
                                 DriveInfo *pflash_drv)
 | 
			
		||||
{
 | 
			
		||||
@@ -199,110 +165,24 @@ static void old_pc_system_rom_init(MemoryRegion *rom_memory, bool isapc_ram_fw)
 | 
			
		||||
                                bios);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Bug-compatible flash vs. ROM selection enabled?
 | 
			
		||||
 * A few older machines enable this.
 | 
			
		||||
 */
 | 
			
		||||
bool pc_sysfw_flash_vs_rom_bug_compatible;
 | 
			
		||||
 | 
			
		||||
void pc_system_firmware_init(MemoryRegion *rom_memory)
 | 
			
		||||
void pc_system_firmware_init(MemoryRegion *rom_memory, bool isapc_ram_fw)
 | 
			
		||||
{
 | 
			
		||||
    DriveInfo *pflash_drv;
 | 
			
		||||
    PcSysFwDevice *sysfw_dev;
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
     * TODO This device exists only so that users can switch between
 | 
			
		||||
     * use of flash and ROM for the BIOS.  The ability to switch was
 | 
			
		||||
     * created because flash doesn't work with KVM.  Once it does, we
 | 
			
		||||
     * should drop this device.
 | 
			
		||||
     */
 | 
			
		||||
    sysfw_dev = (PcSysFwDevice*) qdev_create(NULL, "pc-sysfw");
 | 
			
		||||
 | 
			
		||||
    qdev_init_nofail(DEVICE(sysfw_dev));
 | 
			
		||||
 | 
			
		||||
    pflash_drv = drive_get(IF_PFLASH, 0, 0);
 | 
			
		||||
 | 
			
		||||
    if (pc_sysfw_flash_vs_rom_bug_compatible) {
 | 
			
		||||
        /*
 | 
			
		||||
         * This is a Bad Idea, because it makes enabling/disabling KVM
 | 
			
		||||
         * guest-visible.  Do it only in bug-compatibility mode.
 | 
			
		||||
         */
 | 
			
		||||
        if (kvm_enabled()) {
 | 
			
		||||
            if (pflash_drv != NULL) {
 | 
			
		||||
                fprintf(stderr, "qemu: pflash cannot be used with kvm enabled\n");
 | 
			
		||||
                exit(1);
 | 
			
		||||
            } else {
 | 
			
		||||
                /* In old pc_sysfw_flash_vs_rom_bug_compatible mode, we assume
 | 
			
		||||
                 * that KVM cannot execute from device memory. In this case, we
 | 
			
		||||
                 * use old rom based firmware initialization for KVM. But, since
 | 
			
		||||
                 * this is different from non-kvm mode, this behavior is
 | 
			
		||||
                 * undesirable */
 | 
			
		||||
                sysfw_dev->rom_only = 1;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    } else if (pflash_drv == NULL) {
 | 
			
		||||
    if (isapc_ram_fw || pflash_drv == NULL) {
 | 
			
		||||
        /* When a pflash drive is not found, use rom-mode */
 | 
			
		||||
        sysfw_dev->rom_only = 1;
 | 
			
		||||
    } else if (kvm_enabled() && !kvm_readonly_mem_enabled()) {
 | 
			
		||||
        old_pc_system_rom_init(rom_memory, isapc_ram_fw);
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (kvm_enabled() && !kvm_readonly_mem_enabled()) {
 | 
			
		||||
        /* Older KVM cannot execute from device memory. So, flash memory
 | 
			
		||||
         * cannot be used unless the readonly memory kvm capability is present. */
 | 
			
		||||
        fprintf(stderr, "qemu: pflash with kvm requires KVM readonly memory support\n");
 | 
			
		||||
        exit(1);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* If rom-mode is active, use the old pc system rom initialization. */
 | 
			
		||||
    if (sysfw_dev->rom_only) {
 | 
			
		||||
        old_pc_system_rom_init(rom_memory, sysfw_dev->isapc_ram_fw);
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* If a pflash drive is not found, then create one using
 | 
			
		||||
       the bios filename. */
 | 
			
		||||
    if (pflash_drv == NULL) {
 | 
			
		||||
        pc_fw_add_pflash_drv();
 | 
			
		||||
        pflash_drv = drive_get(IF_PFLASH, 0, 0);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (pflash_drv != NULL) {
 | 
			
		||||
        pc_system_flash_init(rom_memory, pflash_drv);
 | 
			
		||||
    } else {
 | 
			
		||||
        fprintf(stderr, "qemu: PC system firmware (pflash) not available\n");
 | 
			
		||||
        exit(1);
 | 
			
		||||
    }
 | 
			
		||||
    pc_system_flash_init(rom_memory, pflash_drv);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static Property pcsysfw_properties[] = {
 | 
			
		||||
    DEFINE_PROP_UINT8("isapc_ram_fw", PcSysFwDevice, isapc_ram_fw, 0),
 | 
			
		||||
    DEFINE_PROP_UINT8("rom_only", PcSysFwDevice, rom_only, 0),
 | 
			
		||||
    DEFINE_PROP_END_OF_LIST(),
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static int pcsysfw_init(DeviceState *dev)
 | 
			
		||||
{
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void pcsysfw_class_init (ObjectClass *klass, void *data)
 | 
			
		||||
{
 | 
			
		||||
    DeviceClass *dc = DEVICE_CLASS (klass);
 | 
			
		||||
 | 
			
		||||
    set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
 | 
			
		||||
    dc->desc = "PC System Firmware";
 | 
			
		||||
    dc->init = pcsysfw_init;
 | 
			
		||||
    dc->props = pcsysfw_properties;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static const TypeInfo pcsysfw_info = {
 | 
			
		||||
    .name          = "pc-sysfw",
 | 
			
		||||
    .parent        = TYPE_SYS_BUS_DEVICE,
 | 
			
		||||
    .instance_size = sizeof (PcSysFwDevice),
 | 
			
		||||
    .class_init    = pcsysfw_class_init,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void pcsysfw_register (void)
 | 
			
		||||
{
 | 
			
		||||
    type_register_static (&pcsysfw_info);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type_init (pcsysfw_register);
 | 
			
		||||
 | 
			
		||||
@@ -99,7 +99,6 @@ static QEMUMachine xenpv_machine = {
 | 
			
		||||
    .init = xen_init_pv,
 | 
			
		||||
    .max_cpus = 1,
 | 
			
		||||
    .default_machine_opts = "accel=xen",
 | 
			
		||||
    DEFAULT_MACHINE_OPTIONS,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void xenpv_machine_init(void)
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										217
									
								
								hw/isa/i82378.c
									
									
									
									
									
								
							
							
						
						
									
										217
									
								
								hw/isa/i82378.c
									
									
									
									
									
								
							@@ -22,135 +22,28 @@
 | 
			
		||||
#include "hw/timer/i8254.h"
 | 
			
		||||
#include "hw/audio/pcspk.h"
 | 
			
		||||
 | 
			
		||||
//#define DEBUG_I82378
 | 
			
		||||
 | 
			
		||||
#ifdef DEBUG_I82378
 | 
			
		||||
#define DPRINTF(fmt, ...) \
 | 
			
		||||
do { fprintf(stderr, "i82378: " fmt , ## __VA_ARGS__); } while (0)
 | 
			
		||||
#else
 | 
			
		||||
#define DPRINTF(fmt, ...) \
 | 
			
		||||
do {} while (0)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define BADF(fmt, ...) \
 | 
			
		||||
do { fprintf(stderr, "i82378 ERROR: " fmt , ## __VA_ARGS__); } while (0)
 | 
			
		||||
#define TYPE_I82378 "i82378"
 | 
			
		||||
#define I82378(obj) \
 | 
			
		||||
    OBJECT_CHECK(I82378State, (obj), TYPE_I82378)
 | 
			
		||||
 | 
			
		||||
typedef struct I82378State {
 | 
			
		||||
    PCIDevice parent_obj;
 | 
			
		||||
 | 
			
		||||
    qemu_irq out[2];
 | 
			
		||||
    qemu_irq *i8259;
 | 
			
		||||
    MemoryRegion io;
 | 
			
		||||
    MemoryRegion mem;
 | 
			
		||||
} I82378State;
 | 
			
		||||
 | 
			
		||||
typedef struct PCIi82378State {
 | 
			
		||||
    PCIDevice pci_dev;
 | 
			
		||||
    uint32_t isa_io_base;
 | 
			
		||||
    uint32_t isa_mem_base;
 | 
			
		||||
    I82378State state;
 | 
			
		||||
} PCIi82378State;
 | 
			
		||||
 | 
			
		||||
static const VMStateDescription vmstate_pci_i82378 = {
 | 
			
		||||
static const VMStateDescription vmstate_i82378 = {
 | 
			
		||||
    .name = "pci-i82378",
 | 
			
		||||
    .version_id = 0,
 | 
			
		||||
    .minimum_version_id = 0,
 | 
			
		||||
    .fields = (VMStateField[]) {
 | 
			
		||||
        VMSTATE_PCI_DEVICE(pci_dev, PCIi82378State),
 | 
			
		||||
        VMSTATE_PCI_DEVICE(parent_obj, I82378State),
 | 
			
		||||
        VMSTATE_END_OF_LIST()
 | 
			
		||||
    },
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void i82378_io_write(void *opaque, hwaddr addr,
 | 
			
		||||
                            uint64_t value, unsigned int size)
 | 
			
		||||
{
 | 
			
		||||
    switch (size) {
 | 
			
		||||
    case 1:
 | 
			
		||||
        DPRINTF("%s: " TARGET_FMT_plx "=%02" PRIx64 "\n", __func__,
 | 
			
		||||
                addr, value);
 | 
			
		||||
        cpu_outb(addr, value);
 | 
			
		||||
        break;
 | 
			
		||||
    case 2:
 | 
			
		||||
        DPRINTF("%s: " TARGET_FMT_plx "=%04" PRIx64 "\n", __func__,
 | 
			
		||||
                addr, value);
 | 
			
		||||
        cpu_outw(addr, value);
 | 
			
		||||
        break;
 | 
			
		||||
    case 4:
 | 
			
		||||
        DPRINTF("%s: " TARGET_FMT_plx "=%08" PRIx64 "\n", __func__,
 | 
			
		||||
                addr, value);
 | 
			
		||||
        cpu_outl(addr, value);
 | 
			
		||||
        break;
 | 
			
		||||
    default:
 | 
			
		||||
        abort();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static uint64_t i82378_io_read(void *opaque, hwaddr addr,
 | 
			
		||||
                               unsigned int size)
 | 
			
		||||
{
 | 
			
		||||
    DPRINTF("%s: " TARGET_FMT_plx "\n", __func__, addr);
 | 
			
		||||
    switch (size) {
 | 
			
		||||
    case 1:
 | 
			
		||||
        return cpu_inb(addr);
 | 
			
		||||
    case 2:
 | 
			
		||||
        return cpu_inw(addr);
 | 
			
		||||
    case 4:
 | 
			
		||||
        return cpu_inl(addr);
 | 
			
		||||
    default:
 | 
			
		||||
        abort();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static const MemoryRegionOps i82378_io_ops = {
 | 
			
		||||
    .read = i82378_io_read,
 | 
			
		||||
    .write = i82378_io_write,
 | 
			
		||||
    .endianness = DEVICE_LITTLE_ENDIAN,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void i82378_mem_write(void *opaque, hwaddr addr,
 | 
			
		||||
                             uint64_t value, unsigned int size)
 | 
			
		||||
{
 | 
			
		||||
    switch (size) {
 | 
			
		||||
    case 1:
 | 
			
		||||
        DPRINTF("%s: " TARGET_FMT_plx "=%02" PRIx64 "\n", __func__,
 | 
			
		||||
                addr, value);
 | 
			
		||||
        cpu_outb(addr, value);
 | 
			
		||||
        break;
 | 
			
		||||
    case 2:
 | 
			
		||||
        DPRINTF("%s: " TARGET_FMT_plx "=%04" PRIx64 "\n", __func__,
 | 
			
		||||
                addr, value);
 | 
			
		||||
        cpu_outw(addr, value);
 | 
			
		||||
        break;
 | 
			
		||||
    case 4:
 | 
			
		||||
        DPRINTF("%s: " TARGET_FMT_plx "=%08" PRIx64 "\n", __func__,
 | 
			
		||||
                addr, value);
 | 
			
		||||
        cpu_outl(addr, value);
 | 
			
		||||
        break;
 | 
			
		||||
    default:
 | 
			
		||||
        abort();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static uint64_t i82378_mem_read(void *opaque, hwaddr addr,
 | 
			
		||||
                                unsigned int size)
 | 
			
		||||
{
 | 
			
		||||
    DPRINTF("%s: " TARGET_FMT_plx "\n", __func__, addr);
 | 
			
		||||
    switch (size) {
 | 
			
		||||
    case 1:
 | 
			
		||||
        return cpu_inb(addr);
 | 
			
		||||
    case 2:
 | 
			
		||||
        return cpu_inw(addr);
 | 
			
		||||
    case 4:
 | 
			
		||||
        return cpu_inl(addr);
 | 
			
		||||
    default:
 | 
			
		||||
        abort();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static const MemoryRegionOps i82378_mem_ops = {
 | 
			
		||||
    .read = i82378_mem_read,
 | 
			
		||||
    .write = i82378_mem_write,
 | 
			
		||||
    .endianness = DEVICE_LITTLE_ENDIAN,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void i82378_request_out0_irq(void *opaque, int irq, int level)
 | 
			
		||||
{
 | 
			
		||||
    I82378State *s = opaque;
 | 
			
		||||
@@ -160,19 +53,30 @@ static void i82378_request_out0_irq(void *opaque, int irq, int level)
 | 
			
		||||
static void i82378_request_pic_irq(void *opaque, int irq, int level)
 | 
			
		||||
{
 | 
			
		||||
    DeviceState *dev = opaque;
 | 
			
		||||
    PCIDevice *pci = DO_UPCAST(PCIDevice, qdev, dev);
 | 
			
		||||
    PCIi82378State *s = DO_UPCAST(PCIi82378State, pci_dev, pci);
 | 
			
		||||
    I82378State *s = I82378(dev);
 | 
			
		||||
 | 
			
		||||
    qemu_set_irq(s->state.i8259[irq], level);
 | 
			
		||||
    qemu_set_irq(s->i8259[irq], level);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void i82378_init(DeviceState *dev, I82378State *s)
 | 
			
		||||
static int i82378_initfn(PCIDevice *pci)
 | 
			
		||||
{
 | 
			
		||||
    ISABus *isabus = ISA_BUS(qdev_get_child_bus(dev, "isa.0"));
 | 
			
		||||
    ISADevice *pit;
 | 
			
		||||
    DeviceState *dev = DEVICE(pci);
 | 
			
		||||
    I82378State *s = I82378(dev);
 | 
			
		||||
    uint8_t *pci_conf;
 | 
			
		||||
    ISABus *isabus;
 | 
			
		||||
    ISADevice *isa;
 | 
			
		||||
    qemu_irq *out0_irq;
 | 
			
		||||
 | 
			
		||||
    pci_conf = pci->config;
 | 
			
		||||
    pci_set_word(pci_conf + PCI_COMMAND,
 | 
			
		||||
                 PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
 | 
			
		||||
    pci_set_word(pci_conf + PCI_STATUS,
 | 
			
		||||
                 PCI_STATUS_DEVSEL_MEDIUM);
 | 
			
		||||
 | 
			
		||||
    pci_config_set_interrupt_pin(pci_conf, 1); /* interrupt pin 0 */
 | 
			
		||||
 | 
			
		||||
    isabus = isa_bus_new(dev, pci_address_space_io(pci));
 | 
			
		||||
 | 
			
		||||
    /* This device has:
 | 
			
		||||
       2 82C59 (irq)
 | 
			
		||||
       1 82C54 (pit)
 | 
			
		||||
@@ -183,9 +87,6 @@ static void i82378_init(DeviceState *dev, I82378State *s)
 | 
			
		||||
       All devices accept byte access only, except timer
 | 
			
		||||
     */
 | 
			
		||||
 | 
			
		||||
    qdev_init_gpio_out(dev, s->out, 2);
 | 
			
		||||
    qdev_init_gpio_in(dev, i82378_request_pic_irq, 16);
 | 
			
		||||
 | 
			
		||||
    /* Workaround the fact that i8259 is not qdev'ified... */
 | 
			
		||||
    out0_irq = qemu_allocate_irqs(i82378_request_out0_irq, s, 1);
 | 
			
		||||
 | 
			
		||||
@@ -194,10 +95,10 @@ static void i82378_init(DeviceState *dev, I82378State *s)
 | 
			
		||||
    isa_bus_irqs(isabus, s->i8259);
 | 
			
		||||
 | 
			
		||||
    /* 1 82C54 (pit) */
 | 
			
		||||
    pit = pit_init(isabus, 0x40, 0, NULL);
 | 
			
		||||
    isa = pit_init(isabus, 0x40, 0, NULL);
 | 
			
		||||
 | 
			
		||||
    /* speaker */
 | 
			
		||||
    pcspk_init(isabus, pit);
 | 
			
		||||
    pcspk_init(isabus, isa);
 | 
			
		||||
 | 
			
		||||
    /* 2 82C37 (dma) */
 | 
			
		||||
    isa = isa_create_simple(isabus, "i82374");
 | 
			
		||||
@@ -205,76 +106,44 @@ static void i82378_init(DeviceState *dev, I82378State *s)
 | 
			
		||||
 | 
			
		||||
    /* timer */
 | 
			
		||||
    isa_create_simple(isabus, "mc146818rtc");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int pci_i82378_init(PCIDevice *dev)
 | 
			
		||||
{
 | 
			
		||||
    PCIi82378State *pci = DO_UPCAST(PCIi82378State, pci_dev, dev);
 | 
			
		||||
    I82378State *s = &pci->state;
 | 
			
		||||
    uint8_t *pci_conf;
 | 
			
		||||
 | 
			
		||||
    pci_conf = dev->config;
 | 
			
		||||
    pci_set_word(pci_conf + PCI_COMMAND,
 | 
			
		||||
                 PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
 | 
			
		||||
    pci_set_word(pci_conf + PCI_STATUS,
 | 
			
		||||
                 PCI_STATUS_DEVSEL_MEDIUM);
 | 
			
		||||
 | 
			
		||||
    pci_conf[PCI_INTERRUPT_PIN] = 1; /* interrupt pin 0 */
 | 
			
		||||
 | 
			
		||||
    memory_region_init_io(&s->io, OBJECT(pci), &i82378_io_ops, s,
 | 
			
		||||
                          "i82378-io", 0x00010000);
 | 
			
		||||
    pci_register_bar(dev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->io);
 | 
			
		||||
 | 
			
		||||
    memory_region_init_io(&s->mem, OBJECT(pci), &i82378_mem_ops, s,
 | 
			
		||||
                          "i82378-mem", 0x01000000);
 | 
			
		||||
    pci_register_bar(dev, 1, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->mem);
 | 
			
		||||
 | 
			
		||||
    /* Make I/O address read only */
 | 
			
		||||
    pci_set_word(dev->wmask + PCI_COMMAND, PCI_COMMAND_SPECIAL);
 | 
			
		||||
    pci_set_long(dev->wmask + PCI_BASE_ADDRESS_0, 0);
 | 
			
		||||
    pci_set_long(pci_conf + PCI_BASE_ADDRESS_0, pci->isa_io_base);
 | 
			
		||||
 | 
			
		||||
    isa_mem_base = pci->isa_mem_base;
 | 
			
		||||
    isa_bus_new(&dev->qdev, pci_address_space_io(dev));
 | 
			
		||||
 | 
			
		||||
    i82378_init(&dev->qdev, s);
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static Property i82378_properties[] = {
 | 
			
		||||
    DEFINE_PROP_HEX32("iobase", PCIi82378State, isa_io_base, 0x80000000),
 | 
			
		||||
    DEFINE_PROP_HEX32("membase", PCIi82378State, isa_mem_base, 0xc0000000),
 | 
			
		||||
    DEFINE_PROP_END_OF_LIST()
 | 
			
		||||
};
 | 
			
		||||
static void i82378_init(Object *obj)
 | 
			
		||||
{
 | 
			
		||||
    DeviceState *dev = DEVICE(obj);
 | 
			
		||||
    I82378State *s = I82378(obj);
 | 
			
		||||
 | 
			
		||||
static void pci_i82378_class_init(ObjectClass *klass, void *data)
 | 
			
		||||
    qdev_init_gpio_out(dev, s->out, 2);
 | 
			
		||||
    qdev_init_gpio_in(dev, i82378_request_pic_irq, 16);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void i82378_class_init(ObjectClass *klass, void *data)
 | 
			
		||||
{
 | 
			
		||||
    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
 | 
			
		||||
    DeviceClass *dc = DEVICE_CLASS(klass);
 | 
			
		||||
 | 
			
		||||
    k->init = pci_i82378_init;
 | 
			
		||||
    k->init = i82378_initfn;
 | 
			
		||||
    k->vendor_id = PCI_VENDOR_ID_INTEL;
 | 
			
		||||
    k->device_id = PCI_DEVICE_ID_INTEL_82378;
 | 
			
		||||
    k->revision = 0x03;
 | 
			
		||||
    k->class_id = PCI_CLASS_BRIDGE_ISA;
 | 
			
		||||
    k->subsystem_vendor_id = 0x0;
 | 
			
		||||
    k->subsystem_id = 0x0;
 | 
			
		||||
    dc->vmsd = &vmstate_pci_i82378;
 | 
			
		||||
    dc->vmsd = &vmstate_i82378;
 | 
			
		||||
    set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
 | 
			
		||||
    dc->props = i82378_properties;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static const TypeInfo pci_i82378_info = {
 | 
			
		||||
    .name = "i82378",
 | 
			
		||||
static const TypeInfo i82378_type_info = {
 | 
			
		||||
    .name = TYPE_I82378,
 | 
			
		||||
    .parent = TYPE_PCI_DEVICE,
 | 
			
		||||
    .instance_size = sizeof(PCIi82378State),
 | 
			
		||||
    .class_init = pci_i82378_class_init,
 | 
			
		||||
    .instance_size = sizeof(I82378State),
 | 
			
		||||
    .instance_init = i82378_init,
 | 
			
		||||
    .class_init = i82378_class_init,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void i82378_register_types(void)
 | 
			
		||||
{
 | 
			
		||||
    type_register_static(&pci_i82378_info);
 | 
			
		||||
    type_register_static(&i82378_type_info);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type_init(i82378_register_types)
 | 
			
		||||
 
 | 
			
		||||
@@ -289,7 +289,6 @@ static QEMUMachine lm32_evr_machine = {
 | 
			
		||||
    .desc = "LatticeMico32 EVR32 eval system",
 | 
			
		||||
    .init = lm32_evr_init,
 | 
			
		||||
    .is_default = 1,
 | 
			
		||||
    DEFAULT_MACHINE_OPTIONS,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static QEMUMachine lm32_uclinux_machine = {
 | 
			
		||||
@@ -297,7 +296,6 @@ static QEMUMachine lm32_uclinux_machine = {
 | 
			
		||||
    .desc = "lm32 platform for uClinux and u-boot by Theobroma Systems",
 | 
			
		||||
    .init = lm32_uclinux_init,
 | 
			
		||||
    .is_default = 0,
 | 
			
		||||
    DEFAULT_MACHINE_OPTIONS,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void lm32_machine_init(void)
 | 
			
		||||
 
 | 
			
		||||
@@ -208,7 +208,6 @@ static QEMUMachine milkymist_machine = {
 | 
			
		||||
    .desc = "Milkymist One",
 | 
			
		||||
    .init = milkymist_init,
 | 
			
		||||
    .is_default = 0,
 | 
			
		||||
    DEFAULT_MACHINE_OPTIONS,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void milkymist_machine_init(void)
 | 
			
		||||
 
 | 
			
		||||
@@ -89,7 +89,6 @@ static QEMUMachine an5206_machine = {
 | 
			
		||||
    .name = "an5206",
 | 
			
		||||
    .desc = "Arnewsh 5206",
 | 
			
		||||
    .init = an5206_init,
 | 
			
		||||
    DEFAULT_MACHINE_OPTIONS,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void an5206_machine_init(void)
 | 
			
		||||
 
 | 
			
		||||
@@ -73,7 +73,6 @@ static QEMUMachine dummy_m68k_machine = {
 | 
			
		||||
    .name = "dummy",
 | 
			
		||||
    .desc = "Dummy board",
 | 
			
		||||
    .init = dummy_m68k_init,
 | 
			
		||||
    DEFAULT_MACHINE_OPTIONS,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void dummy_m68k_machine_init(void)
 | 
			
		||||
 
 | 
			
		||||
@@ -295,7 +295,6 @@ static QEMUMachine mcf5208evb_machine = {
 | 
			
		||||
    .desc = "MCF5206EVB",
 | 
			
		||||
    .init = mcf5208evb_init,
 | 
			
		||||
    .is_default = 1,
 | 
			
		||||
    DEFAULT_MACHINE_OPTIONS,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void mcf5208evb_machine_init(void)
 | 
			
		||||
 
 | 
			
		||||
@@ -186,7 +186,6 @@ static QEMUMachine petalogix_ml605_machine = {
 | 
			
		||||
    .desc = "PetaLogix linux refdesign for xilinx ml605 little endian",
 | 
			
		||||
    .init = petalogix_ml605_init,
 | 
			
		||||
    .is_default = 0,
 | 
			
		||||
    DEFAULT_MACHINE_OPTIONS,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void petalogix_ml605_machine_init(void)
 | 
			
		||||
 
 | 
			
		||||
@@ -116,7 +116,6 @@ static QEMUMachine petalogix_s3adsp1800_machine = {
 | 
			
		||||
    .desc = "PetaLogix linux refdesign for xilinx Spartan 3ADSP1800",
 | 
			
		||||
    .init = petalogix_s3adsp1800_init,
 | 
			
		||||
    .is_default = 1,
 | 
			
		||||
    DEFAULT_MACHINE_OPTIONS,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void petalogix_s3adsp1800_machine_init(void)
 | 
			
		||||
 
 | 
			
		||||
@@ -44,6 +44,7 @@
 | 
			
		||||
#include "sysemu/blockdev.h"
 | 
			
		||||
#include "exec/address-spaces.h"
 | 
			
		||||
#include "sysemu/qtest.h"
 | 
			
		||||
#include "qemu/error-report.h"
 | 
			
		||||
 | 
			
		||||
#define DEBUG_FULONG2E_INIT
 | 
			
		||||
 | 
			
		||||
@@ -335,7 +336,8 @@ static void mips_fulong2e_init(QEMUMachineInitArgs *args)
 | 
			
		||||
 | 
			
		||||
        if ((bios_size < 0 || bios_size > BIOS_SIZE) &&
 | 
			
		||||
            !kernel_filename && !qtest_enabled()) {
 | 
			
		||||
            fprintf(stderr, "qemu: Warning, could not load MIPS bios '%s'\n", bios_name);
 | 
			
		||||
            error_report("Could not load MIPS bios '%s'", bios_name);
 | 
			
		||||
            exit(1);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -401,7 +403,6 @@ static QEMUMachine mips_fulong2e_machine = {
 | 
			
		||||
    .name = "fulong2e",
 | 
			
		||||
    .desc = "Fulong 2e mini pc",
 | 
			
		||||
    .init = mips_fulong2e_init,
 | 
			
		||||
    DEFAULT_MACHINE_OPTIONS,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void mips_fulong2e_machine_init(void)
 | 
			
		||||
 
 | 
			
		||||
@@ -43,6 +43,7 @@
 | 
			
		||||
#include "hw/sysbus.h"
 | 
			
		||||
#include "exec/address-spaces.h"
 | 
			
		||||
#include "sysemu/qtest.h"
 | 
			
		||||
#include "qemu/error-report.h"
 | 
			
		||||
 | 
			
		||||
enum jazz_model_e
 | 
			
		||||
{
 | 
			
		||||
@@ -178,8 +179,8 @@ static void mips_jazz_init(MemoryRegion *address_space,
 | 
			
		||||
        bios_size = -1;
 | 
			
		||||
    }
 | 
			
		||||
    if ((bios_size < 0 || bios_size > MAGNUM_BIOS_SIZE) && !qtest_enabled()) {
 | 
			
		||||
        fprintf(stderr, "qemu: Warning, could not load MIPS bios '%s'\n",
 | 
			
		||||
                bios_name);
 | 
			
		||||
        error_report("Could not load MIPS bios '%s'", bios_name);
 | 
			
		||||
        exit(1);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* Init CPU internal devices */
 | 
			
		||||
@@ -326,7 +327,6 @@ static QEMUMachine mips_magnum_machine = {
 | 
			
		||||
    .desc = "MIPS Magnum",
 | 
			
		||||
    .init = mips_magnum_init,
 | 
			
		||||
    .block_default_type = IF_SCSI,
 | 
			
		||||
    DEFAULT_MACHINE_OPTIONS,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static QEMUMachine mips_pica61_machine = {
 | 
			
		||||
@@ -334,7 +334,6 @@ static QEMUMachine mips_pica61_machine = {
 | 
			
		||||
    .desc = "Acer Pica 61",
 | 
			
		||||
    .init = mips_pica61_init,
 | 
			
		||||
    .block_default_type = IF_SCSI,
 | 
			
		||||
    DEFAULT_MACHINE_OPTIONS,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void mips_jazz_machine_init(void)
 | 
			
		||||
 
 | 
			
		||||
@@ -49,6 +49,8 @@
 | 
			
		||||
#include "hw/sysbus.h"             /* SysBusDevice */
 | 
			
		||||
#include "qemu/host-utils.h"
 | 
			
		||||
#include "sysemu/qtest.h"
 | 
			
		||||
#include "qemu/error-report.h"
 | 
			
		||||
#include "hw/empty_slot.h"
 | 
			
		||||
 | 
			
		||||
//#define DEBUG_BOARD_INIT
 | 
			
		||||
 | 
			
		||||
@@ -907,6 +909,11 @@ void mips_malta_init(QEMUMachineInitArgs *args)
 | 
			
		||||
    DeviceState *dev = qdev_create(NULL, TYPE_MIPS_MALTA);
 | 
			
		||||
    MaltaState *s = MIPS_MALTA(dev);
 | 
			
		||||
 | 
			
		||||
    /* The whole address space decoded by the GT-64120A doesn't generate
 | 
			
		||||
       exception when accessing invalid memory. Create an empty slot to
 | 
			
		||||
       emulate this feature. */
 | 
			
		||||
    empty_slot_init(0, 0x20000000);
 | 
			
		||||
 | 
			
		||||
    qdev_init_nofail(dev);
 | 
			
		||||
 | 
			
		||||
    /* Make sure the first 3 serial ports are associated with a device. */
 | 
			
		||||
@@ -1008,9 +1015,9 @@ void mips_malta_init(QEMUMachineInitArgs *args)
 | 
			
		||||
            }
 | 
			
		||||
            if ((bios_size < 0 || bios_size > BIOS_SIZE) &&
 | 
			
		||||
                !kernel_filename && !qtest_enabled()) {
 | 
			
		||||
                fprintf(stderr,
 | 
			
		||||
                        "qemu: Warning, could not load MIPS bios '%s', and no -kernel argument was specified\n",
 | 
			
		||||
                        bios_name);
 | 
			
		||||
                error_report("Could not load MIPS bios '%s', and no "
 | 
			
		||||
                             "-kernel argument was specified", bios_name);
 | 
			
		||||
                exit(1);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        /* In little endian mode the 32bit words in the bios are swapped,
 | 
			
		||||
@@ -1129,7 +1136,6 @@ static QEMUMachine mips_malta_machine = {
 | 
			
		||||
    .init = mips_malta_init,
 | 
			
		||||
    .max_cpus = 16,
 | 
			
		||||
    .is_default = 1,
 | 
			
		||||
    DEFAULT_MACHINE_OPTIONS,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void mips_malta_register_types(void)
 | 
			
		||||
 
 | 
			
		||||
@@ -37,6 +37,7 @@
 | 
			
		||||
#include "elf.h"
 | 
			
		||||
#include "hw/sysbus.h"
 | 
			
		||||
#include "exec/address-spaces.h"
 | 
			
		||||
#include "qemu/error-report.h"
 | 
			
		||||
 | 
			
		||||
static struct _loaderparams {
 | 
			
		||||
    int ram_size;
 | 
			
		||||
@@ -191,9 +192,9 @@ mips_mipssim_init(QEMUMachineInitArgs *args)
 | 
			
		||||
    }
 | 
			
		||||
    if ((bios_size < 0 || bios_size > BIOS_SIZE) && !kernel_filename) {
 | 
			
		||||
        /* Bail out if we have neither a kernel image nor boot vector code. */
 | 
			
		||||
        fprintf(stderr,
 | 
			
		||||
                "qemu: Warning, could not load MIPS bios '%s', and no -kernel argument was specified\n",
 | 
			
		||||
                filename);
 | 
			
		||||
        error_report("Could not load MIPS bios '%s', and no "
 | 
			
		||||
                     "-kernel argument was specified", filename);
 | 
			
		||||
        exit(1);
 | 
			
		||||
    } else {
 | 
			
		||||
        /* We have a boot vector start address. */
 | 
			
		||||
        env->active_tc.PC = (target_long)(int32_t)0xbfc00000;
 | 
			
		||||
@@ -231,7 +232,6 @@ static QEMUMachine mips_mipssim_machine = {
 | 
			
		||||
    .name = "mipssim",
 | 
			
		||||
    .desc = "MIPS MIPSsim platform",
 | 
			
		||||
    .init = mips_mipssim_init,
 | 
			
		||||
    DEFAULT_MACHINE_OPTIONS,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void mips_mipssim_machine_init(void)
 | 
			
		||||
 
 | 
			
		||||
@@ -306,7 +306,6 @@ static QEMUMachine mips_machine = {
 | 
			
		||||
    .name = "mips",
 | 
			
		||||
    .desc = "mips r4k platform",
 | 
			
		||||
    .init = mips_r4k_init,
 | 
			
		||||
    DEFAULT_MACHINE_OPTIONS,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void mips_machine_init(void)
 | 
			
		||||
 
 | 
			
		||||
@@ -97,29 +97,24 @@ static void pvpanic_isa_realizefn(DeviceState *dev, Error **errp)
 | 
			
		||||
{
 | 
			
		||||
    ISADevice *d = ISA_DEVICE(dev);
 | 
			
		||||
    PVPanicState *s = ISA_PVPANIC_DEVICE(dev);
 | 
			
		||||
    FWCfgState *fw_cfg = fw_cfg_find();
 | 
			
		||||
    uint16_t *pvpanic_port;
 | 
			
		||||
 | 
			
		||||
    if (!fw_cfg) {
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pvpanic_port = g_malloc(sizeof(*pvpanic_port));
 | 
			
		||||
    *pvpanic_port = cpu_to_le16(s->ioport);
 | 
			
		||||
    fw_cfg_add_file(fw_cfg, "etc/pvpanic-port", pvpanic_port,
 | 
			
		||||
                    sizeof(*pvpanic_port));
 | 
			
		||||
 | 
			
		||||
    isa_register_ioport(d, &s->io, s->ioport);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void pvpanic_fw_cfg(ISADevice *dev, FWCfgState *fw_cfg)
 | 
			
		||||
{
 | 
			
		||||
    PVPanicState *s = ISA_PVPANIC_DEVICE(dev);
 | 
			
		||||
    uint16_t *pvpanic_port = g_malloc(sizeof(*pvpanic_port));
 | 
			
		||||
    *pvpanic_port = cpu_to_le16(s->ioport);
 | 
			
		||||
 | 
			
		||||
    fw_cfg_add_file(fw_cfg, "etc/pvpanic-port", pvpanic_port,
 | 
			
		||||
                    sizeof(*pvpanic_port));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void pvpanic_init(ISABus *bus)
 | 
			
		||||
{
 | 
			
		||||
    ISADevice *dev;
 | 
			
		||||
    FWCfgState *fw_cfg = fw_cfg_find();
 | 
			
		||||
    if (!fw_cfg) {
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    dev = isa_create_simple (bus, TYPE_ISA_PVPANIC_DEVICE);
 | 
			
		||||
    pvpanic_fw_cfg(dev, fw_cfg);
 | 
			
		||||
    isa_create_simple(bus, TYPE_ISA_PVPANIC_DEVICE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static Property pvpanic_isa_properties[] = {
 | 
			
		||||
@@ -132,8 +127,8 @@ static void pvpanic_isa_class_init(ObjectClass *klass, void *data)
 | 
			
		||||
    DeviceClass *dc = DEVICE_CLASS(klass);
 | 
			
		||||
 | 
			
		||||
    dc->realize = pvpanic_isa_realizefn;
 | 
			
		||||
    dc->no_user = 1;
 | 
			
		||||
    dc->props = pvpanic_isa_properties;
 | 
			
		||||
    set_bit(DEVICE_CATEGORY_MISC, dc->categories);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static TypeInfo pvpanic_isa_info = {
 | 
			
		||||
 
 | 
			
		||||
@@ -861,6 +861,8 @@ static void pcnet_init(PCNetState *s)
 | 
			
		||||
 | 
			
		||||
    s->csr[0] |= 0x0101;
 | 
			
		||||
    s->csr[0] &= ~0x0004;       /* clear STOP bit */
 | 
			
		||||
 | 
			
		||||
    qemu_flush_queued_packets(qemu_get_queue(s->nic));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void pcnet_start(PCNetState *s)
 | 
			
		||||
@@ -878,6 +880,8 @@ static void pcnet_start(PCNetState *s)
 | 
			
		||||
    s->csr[0] &= ~0x0004;       /* clear STOP bit */
 | 
			
		||||
    s->csr[0] |= 0x0002;
 | 
			
		||||
    pcnet_poll_timer(s);
 | 
			
		||||
 | 
			
		||||
    qemu_flush_queued_packets(qemu_get_queue(s->nic));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void pcnet_stop(PCNetState *s)
 | 
			
		||||
 
 | 
			
		||||
@@ -324,7 +324,7 @@ static const MemoryRegionOps fw_cfg_data_mem_ops = {
 | 
			
		||||
static const MemoryRegionOps fw_cfg_comb_mem_ops = {
 | 
			
		||||
    .read = fw_cfg_comb_read,
 | 
			
		||||
    .write = fw_cfg_comb_write,
 | 
			
		||||
    .endianness = DEVICE_NATIVE_ENDIAN,
 | 
			
		||||
    .endianness = DEVICE_LITTLE_ENDIAN,
 | 
			
		||||
    .valid.accepts = fw_cfg_comb_valid,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -139,7 +139,6 @@ static QEMUMachine openrisc_sim_machine = {
 | 
			
		||||
    .init = openrisc_sim_init,
 | 
			
		||||
    .max_cpus = 1,
 | 
			
		||||
    .is_default = 1,
 | 
			
		||||
    DEFAULT_MACHINE_OPTIONS,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void openrisc_sim_machine_init(void)
 | 
			
		||||
 
 | 
			
		||||
@@ -90,6 +90,7 @@ static void i82801b11_bridge_class_init(ObjectClass *klass, void *data)
 | 
			
		||||
    k->device_id = PCI_DEVICE_ID_INTEL_82801BA_11;
 | 
			
		||||
    k->revision = ICH9_D2P_A2_REVISION;
 | 
			
		||||
    k->init = i82801b11_bridge_initfn;
 | 
			
		||||
    k->config_write = pci_bridge_write_config;
 | 
			
		||||
    set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -320,6 +320,7 @@ PCIBus *i440fx_init(PCII440FXState **pi440fx_state,
 | 
			
		||||
    PCII440FXState *f;
 | 
			
		||||
    unsigned i;
 | 
			
		||||
    I440FXState *i440fx;
 | 
			
		||||
    uint64_t pci_hole64_size;
 | 
			
		||||
 | 
			
		||||
    dev = qdev_create(NULL, TYPE_I440FX_PCI_HOST_BRIDGE);
 | 
			
		||||
    s = PCI_HOST_BRIDGE(dev);
 | 
			
		||||
@@ -351,13 +352,15 @@ PCIBus *i440fx_init(PCII440FXState **pi440fx_state,
 | 
			
		||||
                             pci_hole_start, pci_hole_size);
 | 
			
		||||
    memory_region_add_subregion(f->system_memory, pci_hole_start, &f->pci_hole);
 | 
			
		||||
 | 
			
		||||
    pci_hole64_size = pci_host_get_hole64_size(i440fx->pci_hole64_size);
 | 
			
		||||
 | 
			
		||||
    pc_init_pci64_hole(&i440fx->pci_info, 0x100000000ULL + above_4g_mem_size,
 | 
			
		||||
                       i440fx->pci_hole64_size);
 | 
			
		||||
                       pci_hole64_size);
 | 
			
		||||
    memory_region_init_alias(&f->pci_hole_64bit, OBJECT(d), "pci-hole64",
 | 
			
		||||
                             f->pci_address_space,
 | 
			
		||||
                             i440fx->pci_info.w64.begin,
 | 
			
		||||
                             i440fx->pci_hole64_size);
 | 
			
		||||
    if (i440fx->pci_hole64_size) {
 | 
			
		||||
                             pci_hole64_size);
 | 
			
		||||
    if (pci_hole64_size) {
 | 
			
		||||
        memory_region_add_subregion(f->system_memory,
 | 
			
		||||
                                    i440fx->pci_info.w64.begin,
 | 
			
		||||
                                    &f->pci_hole_64bit);
 | 
			
		||||
 
 | 
			
		||||
@@ -119,6 +119,8 @@ static void raven_pcihost_realizefn(DeviceState *d, Error **errp)
 | 
			
		||||
    MemoryRegion *address_space_mem = get_system_memory();
 | 
			
		||||
    int i;
 | 
			
		||||
 | 
			
		||||
    isa_mem_base = 0xc0000000;
 | 
			
		||||
 | 
			
		||||
    for (i = 0; i < 4; i++) {
 | 
			
		||||
        sysbus_init_irq(dev, &s->irq[i]);
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -320,6 +320,7 @@ static int mch_init(PCIDevice *d)
 | 
			
		||||
{
 | 
			
		||||
    int i;
 | 
			
		||||
    MCHPCIState *mch = MCH_PCI_DEVICE(d);
 | 
			
		||||
    uint64_t pci_hole64_size;
 | 
			
		||||
 | 
			
		||||
    /* setup pci memory regions */
 | 
			
		||||
    memory_region_init_alias(&mch->pci_hole, OBJECT(mch), "pci-hole",
 | 
			
		||||
@@ -329,13 +330,14 @@ static int mch_init(PCIDevice *d)
 | 
			
		||||
    memory_region_add_subregion(mch->system_memory, mch->below_4g_mem_size,
 | 
			
		||||
                                &mch->pci_hole);
 | 
			
		||||
 | 
			
		||||
    pci_hole64_size = pci_host_get_hole64_size(mch->pci_hole64_size);
 | 
			
		||||
    pc_init_pci64_hole(&mch->pci_info, 0x100000000ULL + mch->above_4g_mem_size,
 | 
			
		||||
                       mch->pci_hole64_size);
 | 
			
		||||
                       pci_hole64_size);
 | 
			
		||||
    memory_region_init_alias(&mch->pci_hole_64bit, OBJECT(mch), "pci-hole64",
 | 
			
		||||
                             mch->pci_address_space,
 | 
			
		||||
                             mch->pci_info.w64.begin,
 | 
			
		||||
                             mch->pci_hole64_size);
 | 
			
		||||
    if (mch->pci_hole64_size) {
 | 
			
		||||
                             pci_hole64_size);
 | 
			
		||||
    if (pci_hole64_size) {
 | 
			
		||||
        memory_region_add_subregion(mch->system_memory,
 | 
			
		||||
                                    mch->pci_info.w64.begin,
 | 
			
		||||
                                    &mch->pci_hole_64bit);
 | 
			
		||||
 
 | 
			
		||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user