Compare commits
215 Commits
v1.6.0-rc0
...
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 | ||
|
|
e501425bbe | ||
|
|
203439ce0a | ||
|
|
27915efb97 | ||
|
|
d5a2bcf70e | ||
|
|
8c0426aed1 | ||
|
|
00c14997cb | ||
|
|
a14ff8a650 | ||
|
|
75cc1c1fcb | ||
|
|
5c9736789b | ||
|
|
768d7e2c7f | ||
|
|
e0d4794458 | ||
|
|
f44c5c6794 | ||
|
|
1197cbb9ed | ||
|
|
e76c756fd3 | ||
|
|
75e2a4baf1 | ||
|
|
c095e10847 | ||
|
|
dbef7b17ad | ||
|
|
c9dd6a9fa0 | ||
|
|
38c8894fe7 | ||
|
|
2c57bd9b06 | ||
|
|
4a7ed999a7 | ||
|
|
96b3bfa083 | ||
|
|
7b7ab18d0b | ||
|
|
5fe0d351b3 | ||
|
|
9a949b94f6 | ||
|
|
beb3faaa00 | ||
|
|
9b4f38e182 | ||
|
|
d2ee774616 | ||
|
|
c1e8dfb5e8 | ||
|
|
71ed827abd | ||
|
|
7ae5a7c0f6 | ||
|
|
0056fc9e44 | ||
|
|
61bf0dcb2e | ||
|
|
2e14211476 | ||
|
|
cf66ee8e20 | ||
|
|
9f0f1a0c09 | ||
|
|
ed60ff024f | ||
|
|
58ae52a8dc | ||
|
|
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.
|
# 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>
|
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>
|
Aurelien Jarno <aurelien@aurel32.net> aurel32 <aurel32@c046a42c-6fe2-441c-8c8c-71466251a162>
|
||||||
Blue Swirl <blauwirbel@gmail.com> blueswir1 <blueswir1@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>
|
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:
|
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
|
2) Parts of QEMU have specific licenses which are compatible with the
|
||||||
GNU General Public License. Hence each source file contains its own
|
GNU General Public License, version 2. Hence each source file contains
|
||||||
licensing information.
|
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
|
3) The Tiny Code Generator (TCG) is released under the BSD license
|
||||||
(see license headers in files).
|
(see license headers in files).
|
||||||
|
|
||||||
4) QEMU is a trademark of Fabrice Bellard.
|
4) QEMU is a trademark of Fabrice Bellard.
|
||||||
|
|
||||||
Fabrice Bellard.
|
Fabrice Bellard and the QEMU team
|
||||||
|
|||||||
16
MAINTAINERS
16
MAINTAINERS
@@ -50,7 +50,7 @@ Descriptions of section entries:
|
|||||||
|
|
||||||
General Project Administration
|
General Project Administration
|
||||||
------------------------------
|
------------------------------
|
||||||
M: Anthony Liguori <aliguori@us.ibm.com>
|
M: Anthony Liguori <anthony@codemonkey.ws>
|
||||||
M: Paul Brook <paul@codesourcery.com>
|
M: Paul Brook <paul@codesourcery.com>
|
||||||
|
|
||||||
Guest CPU cores (TCG):
|
Guest CPU cores (TCG):
|
||||||
@@ -225,7 +225,7 @@ ARM Machines
|
|||||||
Exynos
|
Exynos
|
||||||
M: Evgeny Voevodin <e.voevodin@samsung.com>
|
M: Evgeny Voevodin <e.voevodin@samsung.com>
|
||||||
M: Maksim Kozlov <m.kozlov@samsung.com>
|
M: Maksim Kozlov <m.kozlov@samsung.com>
|
||||||
M: Igor Mitsyanko <i.mitsyanko@samsung.com>
|
M: Igor Mitsyanko <i.mitsyanko@gmail.com>
|
||||||
M: Dmitry Solodkiy <d.solodkiy@samsung.com>
|
M: Dmitry Solodkiy <d.solodkiy@samsung.com>
|
||||||
S: Maintained
|
S: Maintained
|
||||||
F: hw/*/exynos*
|
F: hw/*/exynos*
|
||||||
@@ -509,7 +509,7 @@ F: hw/unicore32/
|
|||||||
X86 Machines
|
X86 Machines
|
||||||
------------
|
------------
|
||||||
PC
|
PC
|
||||||
M: Anthony Liguori <aliguori@us.ibm.com>
|
M: Anthony Liguori <anthony@codemonkey.ws>
|
||||||
S: Supported
|
S: Supported
|
||||||
F: hw/i386/pc.[ch]
|
F: hw/i386/pc.[ch]
|
||||||
F: hw/i386/pc_piix.c
|
F: hw/i386/pc_piix.c
|
||||||
@@ -593,7 +593,7 @@ S: Supported
|
|||||||
F: hw/*/*vhost*
|
F: hw/*/*vhost*
|
||||||
|
|
||||||
virtio
|
virtio
|
||||||
M: Anthony Liguori <aliguori@us.ibm.com>
|
M: Anthony Liguori <anthony@codemonkey.ws>
|
||||||
S: Supported
|
S: Supported
|
||||||
F: hw/*/virtio*
|
F: hw/*/virtio*
|
||||||
|
|
||||||
@@ -651,7 +651,7 @@ F: block/
|
|||||||
F: hw/block/
|
F: hw/block/
|
||||||
|
|
||||||
Character Devices
|
Character Devices
|
||||||
M: Anthony Liguori <aliguori@us.ibm.com>
|
M: Anthony Liguori <anthony@codemonkey.ws>
|
||||||
S: Maintained
|
S: Maintained
|
||||||
F: qemu-char.c
|
F: qemu-char.c
|
||||||
|
|
||||||
@@ -689,7 +689,7 @@ F: audio/spiceaudio.c
|
|||||||
F: hw/display/qxl*
|
F: hw/display/qxl*
|
||||||
|
|
||||||
Graphics
|
Graphics
|
||||||
M: Anthony Liguori <aliguori@us.ibm.com>
|
M: Anthony Liguori <anthony@codemonkey.ws>
|
||||||
S: Maintained
|
S: Maintained
|
||||||
F: ui/
|
F: ui/
|
||||||
|
|
||||||
@@ -699,7 +699,7 @@ S: Odd Fixes
|
|||||||
F: ui/cocoa.m
|
F: ui/cocoa.m
|
||||||
|
|
||||||
Main loop
|
Main loop
|
||||||
M: Anthony Liguori <aliguori@us.ibm.com>
|
M: Anthony Liguori <anthony@codemonkey.ws>
|
||||||
S: Supported
|
S: Supported
|
||||||
F: vl.c
|
F: vl.c
|
||||||
|
|
||||||
@@ -711,7 +711,7 @@ F: hmp.c
|
|||||||
F: hmp-commands.hx
|
F: hmp-commands.hx
|
||||||
|
|
||||||
Network device layer
|
Network device layer
|
||||||
M: Anthony Liguori <aliguori@us.ibm.com>
|
M: Anthony Liguori <anthony@codemonkey.ws>
|
||||||
M: Stefan Hajnoczi <stefanha@redhat.com>
|
M: Stefan Hajnoczi <stefanha@redhat.com>
|
||||||
S: Maintained
|
S: Maintained
|
||||||
F: net/
|
F: net/
|
||||||
|
|||||||
7
Makefile
7
Makefile
@@ -167,11 +167,8 @@ recurse-all: $(SUBDIR_RULES) $(ROMSUBDIR_RULES)
|
|||||||
|
|
||||||
bt-host.o: QEMU_CFLAGS += $(BLUEZ_CFLAGS)
|
bt-host.o: QEMU_CFLAGS += $(BLUEZ_CFLAGS)
|
||||||
|
|
||||||
version.o: $(SRC_PATH)/version.rc config-host.h | version.lo
|
$(BUILD_DIR)/version.o: $(SRC_PATH)/version.rc $(BUILD_DIR)/config-host.h | $(BUILD_DIR)/version.lo
|
||||||
version.lo: $(SRC_PATH)/version.rc config-host.h
|
$(BUILD_DIR)/version.lo: $(SRC_PATH)/version.rc $(BUILD_DIR)/config-host.h
|
||||||
|
|
||||||
version-obj-$(CONFIG_WIN32) += version.o
|
|
||||||
version-lobj-$(CONFIG_WIN32) += version.lo
|
|
||||||
|
|
||||||
Makefile: $(version-obj-y) $(version-lobj-y)
|
Makefile: $(version-obj-y) $(version-lobj-y)
|
||||||
|
|
||||||
|
|||||||
@@ -98,6 +98,11 @@ common-obj-y += hw/
|
|||||||
common-obj-y += qom/
|
common-obj-y += qom/
|
||||||
common-obj-y += disas/
|
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
|
# guest agent
|
||||||
|
|
||||||
|
|||||||
34
aio-posix.c
34
aio-posix.c
@@ -23,7 +23,6 @@ struct AioHandler
|
|||||||
GPollFD pfd;
|
GPollFD pfd;
|
||||||
IOHandler *io_read;
|
IOHandler *io_read;
|
||||||
IOHandler *io_write;
|
IOHandler *io_write;
|
||||||
AioFlushHandler *io_flush;
|
|
||||||
int deleted;
|
int deleted;
|
||||||
int pollfds_idx;
|
int pollfds_idx;
|
||||||
void *opaque;
|
void *opaque;
|
||||||
@@ -47,7 +46,6 @@ void aio_set_fd_handler(AioContext *ctx,
|
|||||||
int fd,
|
int fd,
|
||||||
IOHandler *io_read,
|
IOHandler *io_read,
|
||||||
IOHandler *io_write,
|
IOHandler *io_write,
|
||||||
AioFlushHandler *io_flush,
|
|
||||||
void *opaque)
|
void *opaque)
|
||||||
{
|
{
|
||||||
AioHandler *node;
|
AioHandler *node;
|
||||||
@@ -84,7 +82,6 @@ void aio_set_fd_handler(AioContext *ctx,
|
|||||||
/* Update handler with latest information */
|
/* Update handler with latest information */
|
||||||
node->io_read = io_read;
|
node->io_read = io_read;
|
||||||
node->io_write = io_write;
|
node->io_write = io_write;
|
||||||
node->io_flush = io_flush;
|
|
||||||
node->opaque = opaque;
|
node->opaque = opaque;
|
||||||
node->pollfds_idx = -1;
|
node->pollfds_idx = -1;
|
||||||
|
|
||||||
@@ -97,12 +94,10 @@ void aio_set_fd_handler(AioContext *ctx,
|
|||||||
|
|
||||||
void aio_set_event_notifier(AioContext *ctx,
|
void aio_set_event_notifier(AioContext *ctx,
|
||||||
EventNotifier *notifier,
|
EventNotifier *notifier,
|
||||||
EventNotifierHandler *io_read,
|
EventNotifierHandler *io_read)
|
||||||
AioFlushEventNotifierHandler *io_flush)
|
|
||||||
{
|
{
|
||||||
aio_set_fd_handler(ctx, event_notifier_get_fd(notifier),
|
aio_set_fd_handler(ctx, event_notifier_get_fd(notifier),
|
||||||
(IOHandler *)io_read, NULL,
|
(IOHandler *)io_read, NULL, notifier);
|
||||||
(AioFlushHandler *)io_flush, notifier);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool aio_pending(AioContext *ctx)
|
bool aio_pending(AioContext *ctx)
|
||||||
@@ -147,8 +142,12 @@ static bool aio_dispatch(AioContext *ctx)
|
|||||||
(revents & (G_IO_IN | G_IO_HUP | G_IO_ERR)) &&
|
(revents & (G_IO_IN | G_IO_HUP | G_IO_ERR)) &&
|
||||||
node->io_read) {
|
node->io_read) {
|
||||||
node->io_read(node->opaque);
|
node->io_read(node->opaque);
|
||||||
|
|
||||||
|
/* aio_notify() does not count as progress */
|
||||||
|
if (node->opaque != &ctx->notifier) {
|
||||||
progress = true;
|
progress = true;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (!node->deleted &&
|
if (!node->deleted &&
|
||||||
(revents & (G_IO_OUT | G_IO_ERR)) &&
|
(revents & (G_IO_OUT | G_IO_ERR)) &&
|
||||||
node->io_write) {
|
node->io_write) {
|
||||||
@@ -173,7 +172,7 @@ bool aio_poll(AioContext *ctx, bool blocking)
|
|||||||
{
|
{
|
||||||
AioHandler *node;
|
AioHandler *node;
|
||||||
int ret;
|
int ret;
|
||||||
bool busy, progress;
|
bool progress;
|
||||||
|
|
||||||
progress = false;
|
progress = false;
|
||||||
|
|
||||||
@@ -200,20 +199,8 @@ bool aio_poll(AioContext *ctx, bool blocking)
|
|||||||
g_array_set_size(ctx->pollfds, 0);
|
g_array_set_size(ctx->pollfds, 0);
|
||||||
|
|
||||||
/* fill pollfds */
|
/* fill pollfds */
|
||||||
busy = false;
|
|
||||||
QLIST_FOREACH(node, &ctx->aio_handlers, node) {
|
QLIST_FOREACH(node, &ctx->aio_handlers, node) {
|
||||||
node->pollfds_idx = -1;
|
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) {
|
if (!node->deleted && node->pfd.events) {
|
||||||
GPollFD pfd = {
|
GPollFD pfd = {
|
||||||
.fd = node->pfd.fd,
|
.fd = node->pfd.fd,
|
||||||
@@ -226,8 +213,8 @@ bool aio_poll(AioContext *ctx, bool blocking)
|
|||||||
|
|
||||||
ctx->walking_handlers--;
|
ctx->walking_handlers--;
|
||||||
|
|
||||||
/* No AIO operations? Get us out of here */
|
/* early return if we only have the aio_notify() fd */
|
||||||
if (!busy) {
|
if (ctx->pollfds->len == 1) {
|
||||||
return progress;
|
return progress;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -250,6 +237,5 @@ bool aio_poll(AioContext *ctx, bool blocking)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(progress || busy);
|
return progress;
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|||||||
33
aio-win32.c
33
aio-win32.c
@@ -23,7 +23,6 @@
|
|||||||
struct AioHandler {
|
struct AioHandler {
|
||||||
EventNotifier *e;
|
EventNotifier *e;
|
||||||
EventNotifierHandler *io_notify;
|
EventNotifierHandler *io_notify;
|
||||||
AioFlushEventNotifierHandler *io_flush;
|
|
||||||
GPollFD pfd;
|
GPollFD pfd;
|
||||||
int deleted;
|
int deleted;
|
||||||
QLIST_ENTRY(AioHandler) node;
|
QLIST_ENTRY(AioHandler) node;
|
||||||
@@ -31,8 +30,7 @@ struct AioHandler {
|
|||||||
|
|
||||||
void aio_set_event_notifier(AioContext *ctx,
|
void aio_set_event_notifier(AioContext *ctx,
|
||||||
EventNotifier *e,
|
EventNotifier *e,
|
||||||
EventNotifierHandler *io_notify,
|
EventNotifierHandler *io_notify)
|
||||||
AioFlushEventNotifierHandler *io_flush)
|
|
||||||
{
|
{
|
||||||
AioHandler *node;
|
AioHandler *node;
|
||||||
|
|
||||||
@@ -73,7 +71,6 @@ void aio_set_event_notifier(AioContext *ctx,
|
|||||||
}
|
}
|
||||||
/* Update handler with latest information */
|
/* Update handler with latest information */
|
||||||
node->io_notify = io_notify;
|
node->io_notify = io_notify;
|
||||||
node->io_flush = io_flush;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
aio_notify(ctx);
|
aio_notify(ctx);
|
||||||
@@ -96,7 +93,7 @@ bool aio_poll(AioContext *ctx, bool blocking)
|
|||||||
{
|
{
|
||||||
AioHandler *node;
|
AioHandler *node;
|
||||||
HANDLE events[MAXIMUM_WAIT_OBJECTS + 1];
|
HANDLE events[MAXIMUM_WAIT_OBJECTS + 1];
|
||||||
bool busy, progress;
|
bool progress;
|
||||||
int count;
|
int count;
|
||||||
|
|
||||||
progress = false;
|
progress = false;
|
||||||
@@ -126,8 +123,12 @@ bool aio_poll(AioContext *ctx, bool blocking)
|
|||||||
if (node->pfd.revents && node->io_notify) {
|
if (node->pfd.revents && node->io_notify) {
|
||||||
node->pfd.revents = 0;
|
node->pfd.revents = 0;
|
||||||
node->io_notify(node->e);
|
node->io_notify(node->e);
|
||||||
|
|
||||||
|
/* aio_notify() does not count as progress */
|
||||||
|
if (node->opaque != &ctx->notifier) {
|
||||||
progress = true;
|
progress = true;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
tmp = node;
|
tmp = node;
|
||||||
node = QLIST_NEXT(node, node);
|
node = QLIST_NEXT(node, node);
|
||||||
@@ -147,19 +148,8 @@ bool aio_poll(AioContext *ctx, bool blocking)
|
|||||||
ctx->walking_handlers++;
|
ctx->walking_handlers++;
|
||||||
|
|
||||||
/* fill fd sets */
|
/* fill fd sets */
|
||||||
busy = false;
|
|
||||||
count = 0;
|
count = 0;
|
||||||
QLIST_FOREACH(node, &ctx->aio_handlers, node) {
|
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) {
|
if (!node->deleted && node->io_notify) {
|
||||||
events[count++] = event_notifier_get_handle(node->e);
|
events[count++] = event_notifier_get_handle(node->e);
|
||||||
}
|
}
|
||||||
@@ -167,8 +157,8 @@ bool aio_poll(AioContext *ctx, bool blocking)
|
|||||||
|
|
||||||
ctx->walking_handlers--;
|
ctx->walking_handlers--;
|
||||||
|
|
||||||
/* No AIO operations? Get us out of here */
|
/* early return if we only have the aio_notify() fd */
|
||||||
if (!busy) {
|
if (count == 1) {
|
||||||
return progress;
|
return progress;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -196,8 +186,12 @@ bool aio_poll(AioContext *ctx, bool blocking)
|
|||||||
event_notifier_get_handle(node->e) == events[ret - WAIT_OBJECT_0] &&
|
event_notifier_get_handle(node->e) == events[ret - WAIT_OBJECT_0] &&
|
||||||
node->io_notify) {
|
node->io_notify) {
|
||||||
node->io_notify(node->e);
|
node->io_notify(node->e);
|
||||||
|
|
||||||
|
/* aio_notify() does not count as progress */
|
||||||
|
if (node->opaque != &ctx->notifier) {
|
||||||
progress = true;
|
progress = true;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
tmp = node;
|
tmp = node;
|
||||||
node = QLIST_NEXT(node, node);
|
node = QLIST_NEXT(node, node);
|
||||||
@@ -214,6 +208,5 @@ bool aio_poll(AioContext *ctx, bool blocking)
|
|||||||
events[ret - WAIT_OBJECT_0] = events[--count];
|
events[ret - WAIT_OBJECT_0] = events[--count];
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(progress || busy);
|
return progress;
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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 base = mr->ram_addr >> TARGET_PAGE_BITS;
|
||||||
unsigned long nr = base + (start >> 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;
|
unsigned long next;
|
||||||
|
|
||||||
|
|||||||
4
async.c
4
async.c
@@ -201,7 +201,7 @@ aio_ctx_finalize(GSource *source)
|
|||||||
AioContext *ctx = (AioContext *) source;
|
AioContext *ctx = (AioContext *) source;
|
||||||
|
|
||||||
thread_pool_free(ctx->thread_pool);
|
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);
|
event_notifier_cleanup(&ctx->notifier);
|
||||||
qemu_mutex_destroy(&ctx->bh_lock);
|
qemu_mutex_destroy(&ctx->bh_lock);
|
||||||
g_array_free(ctx->pollfds, TRUE);
|
g_array_free(ctx->pollfds, TRUE);
|
||||||
@@ -243,7 +243,7 @@ AioContext *aio_context_new(void)
|
|||||||
event_notifier_init(&ctx->notifier, false);
|
event_notifier_init(&ctx->notifier, false);
|
||||||
aio_set_event_notifier(ctx, &ctx->notifier,
|
aio_set_event_notifier(ctx, &ctx->notifier,
|
||||||
(EventNotifierHandler *)
|
(EventNotifierHandler *)
|
||||||
event_notifier_test_and_clear, NULL);
|
event_notifier_test_and_clear);
|
||||||
|
|
||||||
return ctx;
|
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)
|
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->block_timer = qemu_new_timer_ns(vm_clock, bdrv_block_timer, bs);
|
||||||
bs->io_limits_enabled = true;
|
bs->io_limits_enabled = true;
|
||||||
}
|
}
|
||||||
@@ -306,6 +305,7 @@ BlockDriverState *bdrv_new(const char *device_name)
|
|||||||
bdrv_iostatus_disable(bs);
|
bdrv_iostatus_disable(bs);
|
||||||
notifier_list_init(&bs->close_notifiers);
|
notifier_list_init(&bs->close_notifiers);
|
||||||
notifier_with_return_list_init(&bs->before_write_notifiers);
|
notifier_with_return_list_init(&bs->before_write_notifiers);
|
||||||
|
qemu_co_queue_init(&bs->throttled_reqs);
|
||||||
|
|
||||||
return bs;
|
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
|
* Wait for pending requests to complete across all BlockDriverStates
|
||||||
*
|
*
|
||||||
@@ -1442,12 +1471,11 @@ void bdrv_close_all(void)
|
|||||||
*/
|
*/
|
||||||
void bdrv_drain_all(void)
|
void bdrv_drain_all(void)
|
||||||
{
|
{
|
||||||
|
/* Always run first iteration so any pending completion BHs run */
|
||||||
|
bool busy = true;
|
||||||
BlockDriverState *bs;
|
BlockDriverState *bs;
|
||||||
bool busy;
|
|
||||||
|
|
||||||
do {
|
|
||||||
busy = qemu_aio_wait();
|
|
||||||
|
|
||||||
|
while (busy) {
|
||||||
/* FIXME: We do not have timer support here, so this is effectively
|
/* FIXME: We do not have timer support here, so this is effectively
|
||||||
* a busy wait.
|
* a busy wait.
|
||||||
*/
|
*/
|
||||||
@@ -1456,12 +1484,9 @@ void bdrv_drain_all(void)
|
|||||||
busy = true;
|
busy = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} while (busy);
|
|
||||||
|
|
||||||
/* If requests are still pending there is a bug somewhere */
|
busy = bdrv_requests_pending_all();
|
||||||
QTAILQ_FOREACH(bs, &bdrv_states, list) {
|
busy |= aio_poll(qemu_get_aio_context(), busy);
|
||||||
assert(QLIST_EMPTY(&bs->tracked_requests));
|
|
||||||
assert(qemu_co_queue_empty(&bs->throttled_reqs));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1606,11 +1631,11 @@ void bdrv_delete(BlockDriverState *bs)
|
|||||||
assert(!bs->job);
|
assert(!bs->job);
|
||||||
assert(!bs->in_use);
|
assert(!bs->in_use);
|
||||||
|
|
||||||
|
bdrv_close(bs);
|
||||||
|
|
||||||
/* remove from list, if necessary */
|
/* remove from list, if necessary */
|
||||||
bdrv_make_anon(bs);
|
bdrv_make_anon(bs);
|
||||||
|
|
||||||
bdrv_close(bs);
|
|
||||||
|
|
||||||
g_free(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_clean_state(CURLState *s);
|
||||||
static void curl_multi_do(void *arg);
|
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,
|
static int curl_sock_cb(CURL *curl, curl_socket_t fd, int action,
|
||||||
void *s, void *sp)
|
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);
|
DPRINTF("CURL (AIO): Sock action %d on fd %d\n", action, fd);
|
||||||
switch (action) {
|
switch (action) {
|
||||||
case CURL_POLL_IN:
|
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;
|
break;
|
||||||
case CURL_POLL_OUT:
|
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;
|
break;
|
||||||
case CURL_POLL_INOUT:
|
case CURL_POLL_INOUT:
|
||||||
qemu_aio_set_fd_handler(fd, curl_multi_do, curl_multi_do,
|
qemu_aio_set_fd_handler(fd, curl_multi_do, curl_multi_do, s);
|
||||||
curl_aio_flush, s);
|
|
||||||
break;
|
break;
|
||||||
case CURL_POLL_REMOVE:
|
case CURL_POLL_REMOVE:
|
||||||
qemu_aio_set_fd_handler(fd, NULL, NULL, NULL, NULL);
|
qemu_aio_set_fd_handler(fd, NULL, NULL, NULL);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -495,21 +493,6 @@ out_noclean:
|
|||||||
return -EINVAL;
|
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)
|
static void curl_aio_cancel(BlockDriverAIOCB *blockacb)
|
||||||
{
|
{
|
||||||
// Do we have to implement canceling? Seems to work without...
|
// Do we have to implement canceling? Seems to work without...
|
||||||
|
|||||||
@@ -32,7 +32,6 @@ typedef struct BDRVGlusterState {
|
|||||||
struct glfs *glfs;
|
struct glfs *glfs;
|
||||||
int fds[2];
|
int fds[2];
|
||||||
struct glfs_fd *fd;
|
struct glfs_fd *fd;
|
||||||
int qemu_aio_count;
|
|
||||||
int event_reader_pos;
|
int event_reader_pos;
|
||||||
GlusterAIOCB *event_acb;
|
GlusterAIOCB *event_acb;
|
||||||
} BDRVGlusterState;
|
} BDRVGlusterState;
|
||||||
@@ -247,7 +246,6 @@ static void qemu_gluster_complete_aio(GlusterAIOCB *acb, BDRVGlusterState *s)
|
|||||||
ret = -EIO; /* Partial read/write - fail it */
|
ret = -EIO; /* Partial read/write - fail it */
|
||||||
}
|
}
|
||||||
|
|
||||||
s->qemu_aio_count--;
|
|
||||||
qemu_aio_release(acb);
|
qemu_aio_release(acb);
|
||||||
cb(opaque, ret);
|
cb(opaque, ret);
|
||||||
if (finished) {
|
if (finished) {
|
||||||
@@ -275,13 +273,6 @@ static void qemu_gluster_aio_event_reader(void *opaque)
|
|||||||
} while (ret < 0 && errno == EINTR);
|
} 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 */
|
/* TODO Convert to fine grained options */
|
||||||
static QemuOptsList runtime_opts = {
|
static QemuOptsList runtime_opts = {
|
||||||
.name = "gluster",
|
.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);
|
fcntl(s->fds[GLUSTER_FD_READ], F_SETFL, O_NONBLOCK);
|
||||||
qemu_aio_set_fd_handler(s->fds[GLUSTER_FD_READ],
|
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:
|
out:
|
||||||
qemu_opts_del(opts);
|
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 */
|
qemu_mutex_lock_iothread(); /* We are in gluster thread context */
|
||||||
acb->common.cb(acb->common.opaque, -EIO);
|
acb->common.cb(acb->common.opaque, -EIO);
|
||||||
qemu_aio_release(acb);
|
qemu_aio_release(acb);
|
||||||
s->qemu_aio_count--;
|
|
||||||
close(s->fds[GLUSTER_FD_READ]);
|
close(s->fds[GLUSTER_FD_READ]);
|
||||||
close(s->fds[GLUSTER_FD_WRITE]);
|
close(s->fds[GLUSTER_FD_WRITE]);
|
||||||
qemu_aio_set_fd_handler(s->fds[GLUSTER_FD_READ], NULL, NULL, NULL,
|
qemu_aio_set_fd_handler(s->fds[GLUSTER_FD_READ], NULL, NULL, NULL);
|
||||||
NULL);
|
|
||||||
bs->drv = NULL; /* Make the disk inaccessible */
|
bs->drv = NULL; /* Make the disk inaccessible */
|
||||||
qemu_mutex_unlock_iothread();
|
qemu_mutex_unlock_iothread();
|
||||||
}
|
}
|
||||||
@@ -467,7 +456,6 @@ static BlockDriverAIOCB *qemu_gluster_aio_rw(BlockDriverState *bs,
|
|||||||
|
|
||||||
offset = sector_num * BDRV_SECTOR_SIZE;
|
offset = sector_num * BDRV_SECTOR_SIZE;
|
||||||
size = nb_sectors * BDRV_SECTOR_SIZE;
|
size = nb_sectors * BDRV_SECTOR_SIZE;
|
||||||
s->qemu_aio_count++;
|
|
||||||
|
|
||||||
acb = qemu_aio_get(&gluster_aiocb_info, bs, cb, opaque);
|
acb = qemu_aio_get(&gluster_aiocb_info, bs, cb, opaque);
|
||||||
acb->size = size;
|
acb->size = size;
|
||||||
@@ -488,7 +476,6 @@ static BlockDriverAIOCB *qemu_gluster_aio_rw(BlockDriverState *bs,
|
|||||||
return &acb->common;
|
return &acb->common;
|
||||||
|
|
||||||
out:
|
out:
|
||||||
s->qemu_aio_count--;
|
|
||||||
qemu_aio_release(acb);
|
qemu_aio_release(acb);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@@ -531,7 +518,6 @@ static BlockDriverAIOCB *qemu_gluster_aio_flush(BlockDriverState *bs,
|
|||||||
acb->size = 0;
|
acb->size = 0;
|
||||||
acb->ret = 0;
|
acb->ret = 0;
|
||||||
acb->finished = NULL;
|
acb->finished = NULL;
|
||||||
s->qemu_aio_count++;
|
|
||||||
|
|
||||||
ret = glfs_fsync_async(s->fd, &gluster_finish_aiocb, acb);
|
ret = glfs_fsync_async(s->fd, &gluster_finish_aiocb, acb);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
@@ -540,7 +526,6 @@ static BlockDriverAIOCB *qemu_gluster_aio_flush(BlockDriverState *bs,
|
|||||||
return &acb->common;
|
return &acb->common;
|
||||||
|
|
||||||
out:
|
out:
|
||||||
s->qemu_aio_count--;
|
|
||||||
qemu_aio_release(acb);
|
qemu_aio_release(acb);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@@ -563,7 +548,6 @@ static BlockDriverAIOCB *qemu_gluster_aio_discard(BlockDriverState *bs,
|
|||||||
acb->size = 0;
|
acb->size = 0;
|
||||||
acb->ret = 0;
|
acb->ret = 0;
|
||||||
acb->finished = NULL;
|
acb->finished = NULL;
|
||||||
s->qemu_aio_count++;
|
|
||||||
|
|
||||||
ret = glfs_discard_async(s->fd, offset, size, &gluster_finish_aiocb, acb);
|
ret = glfs_discard_async(s->fd, offset, size, &gluster_finish_aiocb, acb);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
@@ -572,7 +556,6 @@ static BlockDriverAIOCB *qemu_gluster_aio_discard(BlockDriverState *bs,
|
|||||||
return &acb->common;
|
return &acb->common;
|
||||||
|
|
||||||
out:
|
out:
|
||||||
s->qemu_aio_count--;
|
|
||||||
qemu_aio_release(acb);
|
qemu_aio_release(acb);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@@ -611,7 +594,7 @@ static void qemu_gluster_close(BlockDriverState *bs)
|
|||||||
|
|
||||||
close(s->fds[GLUSTER_FD_READ]);
|
close(s->fds[GLUSTER_FD_READ]);
|
||||||
close(s->fds[GLUSTER_FD_WRITE]);
|
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) {
|
if (s->fd) {
|
||||||
glfs_close(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_read(void *arg);
|
||||||
static void iscsi_process_write(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
|
static void
|
||||||
iscsi_set_events(IscsiLun *iscsilun)
|
iscsi_set_events(IscsiLun *iscsilun)
|
||||||
{
|
{
|
||||||
@@ -166,7 +159,6 @@ iscsi_set_events(IscsiLun *iscsilun)
|
|||||||
qemu_aio_set_fd_handler(iscsi_get_fd(iscsi),
|
qemu_aio_set_fd_handler(iscsi_get_fd(iscsi),
|
||||||
iscsi_process_read,
|
iscsi_process_read,
|
||||||
(ev & POLLOUT) ? iscsi_process_write : NULL,
|
(ev & POLLOUT) ? iscsi_process_write : NULL,
|
||||||
iscsi_process_flush,
|
|
||||||
iscsilun);
|
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 ||
|
if ((sector_num * BDRV_SECTOR_SIZE) % iscsilun->block_size ||
|
||||||
(nb_sectors * 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);
|
iscsilun->block_size, sector_num, nb_sectors);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -1213,7 +1207,7 @@ static void iscsi_close(BlockDriverState *bs)
|
|||||||
qemu_del_timer(iscsilun->nop_timer);
|
qemu_del_timer(iscsilun->nop_timer);
|
||||||
qemu_free_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);
|
iscsi_destroy_context(iscsi);
|
||||||
memset(iscsilun, 0, sizeof(IscsiLun));
|
memset(iscsilun, 0, sizeof(IscsiLun));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,7 +39,6 @@ struct qemu_laiocb {
|
|||||||
struct qemu_laio_state {
|
struct qemu_laio_state {
|
||||||
io_context_t ctx;
|
io_context_t ctx;
|
||||||
EventNotifier e;
|
EventNotifier e;
|
||||||
int count;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline ssize_t io_event_ret(struct io_event *ev)
|
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;
|
int ret;
|
||||||
|
|
||||||
s->count--;
|
|
||||||
|
|
||||||
ret = laiocb->ret;
|
ret = laiocb->ret;
|
||||||
if (ret != -ECANCELED) {
|
if (ret != -ECANCELED) {
|
||||||
if (ret == laiocb->nbytes) {
|
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)
|
static void laio_cancel(BlockDriverAIOCB *blockacb)
|
||||||
{
|
{
|
||||||
struct qemu_laiocb *laiocb = (struct qemu_laiocb *)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;
|
goto out_free_aiocb;
|
||||||
}
|
}
|
||||||
io_set_eventfd(&laiocb->iocb, event_notifier_get_fd(&s->e));
|
io_set_eventfd(&laiocb->iocb, event_notifier_get_fd(&s->e));
|
||||||
s->count++;
|
|
||||||
|
|
||||||
if (io_submit(s->ctx, 1, &iocbs) < 0)
|
if (io_submit(s->ctx, 1, &iocbs) < 0)
|
||||||
goto out_dec_count;
|
goto out_free_aiocb;
|
||||||
return &laiocb->common;
|
return &laiocb->common;
|
||||||
|
|
||||||
out_dec_count:
|
|
||||||
s->count--;
|
|
||||||
out_free_aiocb:
|
out_free_aiocb:
|
||||||
qemu_aio_release(laiocb);
|
qemu_aio_release(laiocb);
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -203,8 +190,7 @@ void *laio_init(void)
|
|||||||
goto out_close_efd;
|
goto out_close_efd;
|
||||||
}
|
}
|
||||||
|
|
||||||
qemu_aio_set_event_notifier(&s->e, qemu_laio_completion_cb,
|
qemu_aio_set_event_notifier(&s->e, qemu_laio_completion_cb);
|
||||||
qemu_laio_flush_cb);
|
|
||||||
|
|
||||||
return s;
|
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);
|
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)
|
static void nbd_reply_ready(void *opaque)
|
||||||
{
|
{
|
||||||
BDRVNBDState *s = 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);
|
qemu_co_mutex_lock(&s->send_mutex);
|
||||||
s->send_coroutine = qemu_coroutine_self();
|
s->send_coroutine = qemu_coroutine_self();
|
||||||
qemu_aio_set_fd_handler(s->sock, nbd_reply_ready, nbd_restart_write,
|
qemu_aio_set_fd_handler(s->sock, nbd_reply_ready, nbd_restart_write, s);
|
||||||
nbd_have_request, s);
|
|
||||||
if (qiov) {
|
if (qiov) {
|
||||||
if (!s->is_unix) {
|
if (!s->is_unix) {
|
||||||
socket_set_cork(s->sock, 1);
|
socket_set_cork(s->sock, 1);
|
||||||
@@ -361,8 +353,7 @@ static int nbd_co_send_request(BDRVNBDState *s, struct nbd_request *request,
|
|||||||
} else {
|
} else {
|
||||||
rc = nbd_send_request(s->sock, request);
|
rc = nbd_send_request(s->sock, request);
|
||||||
}
|
}
|
||||||
qemu_aio_set_fd_handler(s->sock, nbd_reply_ready, NULL,
|
qemu_aio_set_fd_handler(s->sock, nbd_reply_ready, NULL, s);
|
||||||
nbd_have_request, s);
|
|
||||||
s->send_coroutine = NULL;
|
s->send_coroutine = NULL;
|
||||||
qemu_co_mutex_unlock(&s->send_mutex);
|
qemu_co_mutex_unlock(&s->send_mutex);
|
||||||
return rc;
|
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
|
/* Now that we're connected, set the socket to be non-blocking and
|
||||||
* kick the reply mechanism. */
|
* kick the reply mechanism. */
|
||||||
qemu_set_nonblock(sock);
|
qemu_set_nonblock(sock);
|
||||||
qemu_aio_set_fd_handler(sock, nbd_reply_ready, NULL,
|
qemu_aio_set_fd_handler(sock, nbd_reply_ready, NULL, s);
|
||||||
nbd_have_request, s);
|
|
||||||
|
|
||||||
s->sock = sock;
|
s->sock = sock;
|
||||||
s->size = size;
|
s->size = size;
|
||||||
@@ -459,7 +449,7 @@ static void nbd_teardown_connection(BlockDriverState *bs)
|
|||||||
request.len = 0;
|
request.len = 0;
|
||||||
nbd_send_request(s->sock, &request);
|
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);
|
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 "qemu-common.h"
|
||||||
#include "block/block_int.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;
|
rados_ioctx_t io_ctx;
|
||||||
rbd_image_t image;
|
rbd_image_t image;
|
||||||
char name[RBD_MAX_IMAGE_NAME_SIZE];
|
char name[RBD_MAX_IMAGE_NAME_SIZE];
|
||||||
int qemu_aio_count;
|
|
||||||
char *snap;
|
char *snap;
|
||||||
int event_reader_pos;
|
int event_reader_pos;
|
||||||
RADOSCB *event_rcb;
|
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)) {
|
if (s->event_reader_pos == sizeof(s->event_rcb)) {
|
||||||
s->event_reader_pos = 0;
|
s->event_reader_pos = 0;
|
||||||
qemu_rbd_complete_aio(s->event_rcb);
|
qemu_rbd_complete_aio(s->event_rcb);
|
||||||
s->qemu_aio_count--;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} while (ret < 0 && errno == EINTR);
|
} 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 */
|
/* TODO Convert to fine grained options */
|
||||||
static QemuOptsList runtime_opts = {
|
static QemuOptsList runtime_opts = {
|
||||||
.name = "rbd",
|
.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[0], F_SETFL, O_NONBLOCK);
|
||||||
fcntl(s->fds[1], 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,
|
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);
|
qemu_opts_del(opts);
|
||||||
@@ -578,7 +569,7 @@ static void qemu_rbd_close(BlockDriverState *bs)
|
|||||||
|
|
||||||
close(s->fds[0]);
|
close(s->fds[0]);
|
||||||
close(s->fds[1]);
|
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);
|
rbd_close(s->image);
|
||||||
rados_ioctx_destroy(s->io_ctx);
|
rados_ioctx_destroy(s->io_ctx);
|
||||||
@@ -741,8 +732,6 @@ static BlockDriverAIOCB *rbd_start_aio(BlockDriverState *bs,
|
|||||||
off = sector_num * BDRV_SECTOR_SIZE;
|
off = sector_num * BDRV_SECTOR_SIZE;
|
||||||
size = nb_sectors * BDRV_SECTOR_SIZE;
|
size = nb_sectors * BDRV_SECTOR_SIZE;
|
||||||
|
|
||||||
s->qemu_aio_count++; /* All the RADOSCB */
|
|
||||||
|
|
||||||
rcb = g_malloc(sizeof(RADOSCB));
|
rcb = g_malloc(sizeof(RADOSCB));
|
||||||
rcb->done = 0;
|
rcb->done = 0;
|
||||||
rcb->acb = acb;
|
rcb->acb = acb;
|
||||||
@@ -779,7 +768,6 @@ static BlockDriverAIOCB *rbd_start_aio(BlockDriverState *bs,
|
|||||||
|
|
||||||
failed:
|
failed:
|
||||||
g_free(rcb);
|
g_free(rcb);
|
||||||
s->qemu_aio_count--;
|
|
||||||
qemu_aio_release(acb);
|
qemu_aio_release(acb);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -509,13 +509,6 @@ static void restart_co_req(void *opaque)
|
|||||||
qemu_coroutine_enter(co, NULL);
|
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 {
|
typedef struct SheepdogReqCo {
|
||||||
int sockfd;
|
int sockfd;
|
||||||
SheepdogReq *hdr;
|
SheepdogReq *hdr;
|
||||||
@@ -538,14 +531,14 @@ static coroutine_fn void do_co_req(void *opaque)
|
|||||||
unsigned int *rlen = srco->rlen;
|
unsigned int *rlen = srco->rlen;
|
||||||
|
|
||||||
co = qemu_coroutine_self();
|
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);
|
ret = send_co_req(sockfd, hdr, data, wlen);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
goto out;
|
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));
|
ret = qemu_co_recv(sockfd, hdr, sizeof(*hdr));
|
||||||
if (ret < sizeof(*hdr)) {
|
if (ret < sizeof(*hdr)) {
|
||||||
@@ -570,7 +563,7 @@ static coroutine_fn void do_co_req(void *opaque)
|
|||||||
out:
|
out:
|
||||||
/* there is at most one request for this sockfd, so it is safe to
|
/* there is at most one request for this sockfd, so it is safe to
|
||||||
* set each handler to NULL. */
|
* 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->ret = ret;
|
||||||
srco->finished = true;
|
srco->finished = true;
|
||||||
@@ -796,14 +789,6 @@ static void co_write_request(void *opaque)
|
|||||||
qemu_coroutine_enter(s->co_send, NULL);
|
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.
|
* Return a socket discriptor to read/write objects.
|
||||||
*
|
*
|
||||||
@@ -819,7 +804,7 @@ static int get_sheep_fd(BDRVSheepdogState *s)
|
|||||||
return fd;
|
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;
|
return fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1069,8 +1054,7 @@ static int coroutine_fn add_aio_request(BDRVSheepdogState *s, AIOReq *aio_req,
|
|||||||
|
|
||||||
qemu_co_mutex_lock(&s->lock);
|
qemu_co_mutex_lock(&s->lock);
|
||||||
s->co_send = qemu_coroutine_self();
|
s->co_send = qemu_coroutine_self();
|
||||||
qemu_aio_set_fd_handler(s->fd, co_read_response, co_write_request,
|
qemu_aio_set_fd_handler(s->fd, co_read_response, co_write_request, s);
|
||||||
aio_flush_request, s);
|
|
||||||
socket_set_cork(s->fd, 1);
|
socket_set_cork(s->fd, 1);
|
||||||
|
|
||||||
/* send a header */
|
/* 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);
|
socket_set_cork(s->fd, 0);
|
||||||
qemu_aio_set_fd_handler(s->fd, co_read_response, NULL,
|
qemu_aio_set_fd_handler(s->fd, co_read_response, NULL, s);
|
||||||
aio_flush_request, s);
|
|
||||||
qemu_co_mutex_unlock(&s->lock);
|
qemu_co_mutex_unlock(&s->lock);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@@ -1350,7 +1333,7 @@ static int sd_open(BlockDriverState *bs, QDict *options, int flags)
|
|||||||
g_free(buf);
|
g_free(buf);
|
||||||
return 0;
|
return 0;
|
||||||
out:
|
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) {
|
if (s->fd >= 0) {
|
||||||
closesocket(s->fd);
|
closesocket(s->fd);
|
||||||
}
|
}
|
||||||
@@ -1578,7 +1561,7 @@ static void sd_close(BlockDriverState *bs)
|
|||||||
error_report("%s, %s", sd_strerror(rsp->result), s->name);
|
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);
|
closesocket(s->fd);
|
||||||
g_free(s->host_spec);
|
g_free(s->host_spec);
|
||||||
}
|
}
|
||||||
@@ -2347,6 +2330,7 @@ static BlockDriver bdrv_sheepdog = {
|
|||||||
.bdrv_file_open = sd_open,
|
.bdrv_file_open = sd_open,
|
||||||
.bdrv_close = sd_close,
|
.bdrv_close = sd_close,
|
||||||
.bdrv_create = sd_create,
|
.bdrv_create = sd_create,
|
||||||
|
.bdrv_has_zero_init = bdrv_has_zero_init_1,
|
||||||
.bdrv_getlength = sd_getlength,
|
.bdrv_getlength = sd_getlength,
|
||||||
.bdrv_truncate = sd_truncate,
|
.bdrv_truncate = sd_truncate,
|
||||||
|
|
||||||
@@ -2374,6 +2358,7 @@ static BlockDriver bdrv_sheepdog_tcp = {
|
|||||||
.bdrv_file_open = sd_open,
|
.bdrv_file_open = sd_open,
|
||||||
.bdrv_close = sd_close,
|
.bdrv_close = sd_close,
|
||||||
.bdrv_create = sd_create,
|
.bdrv_create = sd_create,
|
||||||
|
.bdrv_has_zero_init = bdrv_has_zero_init_1,
|
||||||
.bdrv_getlength = sd_getlength,
|
.bdrv_getlength = sd_getlength,
|
||||||
.bdrv_truncate = sd_truncate,
|
.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);
|
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)
|
static coroutine_fn void set_fd_handler(BDRVSSHState *s)
|
||||||
{
|
{
|
||||||
int r;
|
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,
|
DPRINTF("s->sock=%d rd_handler=%p wr_handler=%p", s->sock,
|
||||||
rd_handler, wr_handler);
|
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)
|
static coroutine_fn void clear_fd_handler(BDRVSSHState *s)
|
||||||
{
|
{
|
||||||
DPRINTF("s->sock=%d", s->sock);
|
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
|
/* 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;
|
BlockDriverState *intermediate;
|
||||||
intermediate = top->backing_hd;
|
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) {
|
while (intermediate) {
|
||||||
BlockDriverState *unused;
|
BlockDriverState *unused;
|
||||||
|
|
||||||
@@ -70,7 +75,6 @@ static void close_unused_images(BlockDriverState *top, BlockDriverState *base,
|
|||||||
unused->backing_hd = NULL;
|
unused->backing_hd = NULL;
|
||||||
bdrv_delete(unused);
|
bdrv_delete(unused);
|
||||||
}
|
}
|
||||||
top->backing_hd = base;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void coroutine_fn stream_run(void *opaque)
|
static void coroutine_fn stream_run(void *opaque)
|
||||||
|
|||||||
121
block/vmdk.c
121
block/vmdk.c
@@ -62,19 +62,20 @@ typedef struct {
|
|||||||
uint32_t cylinders;
|
uint32_t cylinders;
|
||||||
uint32_t heads;
|
uint32_t heads;
|
||||||
uint32_t sectors_per_track;
|
uint32_t sectors_per_track;
|
||||||
} VMDK3Header;
|
} QEMU_PACKED VMDK3Header;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint32_t version;
|
uint32_t version;
|
||||||
uint32_t flags;
|
uint32_t flags;
|
||||||
int64_t capacity;
|
uint64_t capacity;
|
||||||
int64_t granularity;
|
uint64_t granularity;
|
||||||
int64_t desc_offset;
|
uint64_t desc_offset;
|
||||||
int64_t desc_size;
|
uint64_t desc_size;
|
||||||
int32_t num_gtes_per_gte;
|
/* Number of GrainTableEntries per GrainTable */
|
||||||
int64_t rgd_offset;
|
uint32_t num_gtes_per_gt;
|
||||||
int64_t gd_offset;
|
uint64_t rgd_offset;
|
||||||
int64_t grain_offset;
|
uint64_t gd_offset;
|
||||||
|
uint64_t grain_offset;
|
||||||
char filler[1];
|
char filler[1];
|
||||||
char check_bytes[4];
|
char check_bytes[4];
|
||||||
uint16_t compressAlgorithm;
|
uint16_t compressAlgorithm;
|
||||||
@@ -109,7 +110,7 @@ typedef struct VmdkExtent {
|
|||||||
|
|
||||||
typedef struct BDRVVmdkState {
|
typedef struct BDRVVmdkState {
|
||||||
CoMutex lock;
|
CoMutex lock;
|
||||||
int desc_offset;
|
uint64_t desc_offset;
|
||||||
bool cid_updated;
|
bool cid_updated;
|
||||||
uint32_t parent_cid;
|
uint32_t parent_cid;
|
||||||
int num_extents;
|
int num_extents;
|
||||||
@@ -131,7 +132,7 @@ typedef struct VmdkGrainMarker {
|
|||||||
uint64_t lba;
|
uint64_t lba;
|
||||||
uint32_t size;
|
uint32_t size;
|
||||||
uint8_t data[0];
|
uint8_t data[0];
|
||||||
} VmdkGrainMarker;
|
} QEMU_PACKED VmdkGrainMarker;
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
MARKER_END_OF_STREAM = 0,
|
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
|
/* Create and append extent to the extent array. Return the added VmdkExtent
|
||||||
* address. return NULL if allocation failed. */
|
* 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,
|
BlockDriverState *file, bool flat, int64_t sectors,
|
||||||
int64_t l1_offset, int64_t l1_backup_offset,
|
int64_t l1_offset, int64_t l1_backup_offset,
|
||||||
uint32_t l1_size,
|
uint32_t l1_size,
|
||||||
int l2_size, unsigned int cluster_sectors)
|
int l2_size, uint64_t cluster_sectors,
|
||||||
|
VmdkExtent **new_extent)
|
||||||
{
|
{
|
||||||
VmdkExtent *extent;
|
VmdkExtent *extent;
|
||||||
BDRVVmdkState *s = bs->opaque;
|
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->extents = g_realloc(s->extents,
|
||||||
(s->num_extents + 1) * sizeof(VmdkExtent));
|
(s->num_extents + 1) * sizeof(VmdkExtent));
|
||||||
extent = &s->extents[s->num_extents];
|
extent = &s->extents[s->num_extents];
|
||||||
@@ -416,7 +424,10 @@ static VmdkExtent *vmdk_add_extent(BlockDriverState *bs,
|
|||||||
extent->end_sector = extent->sectors;
|
extent->end_sector = extent->sectors;
|
||||||
}
|
}
|
||||||
bs->total_sectors = extent->end_sector;
|
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)
|
static int vmdk_init_tables(BlockDriverState *bs, VmdkExtent *extent)
|
||||||
@@ -475,12 +486,17 @@ static int vmdk_open_vmdk3(BlockDriverState *bs,
|
|||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
extent = vmdk_add_extent(bs,
|
|
||||||
|
ret = vmdk_add_extent(bs,
|
||||||
bs->file, false,
|
bs->file, false,
|
||||||
le32_to_cpu(header.disk_sectors),
|
le32_to_cpu(header.disk_sectors),
|
||||||
le32_to_cpu(header.l1dir_offset) << 9,
|
le32_to_cpu(header.l1dir_offset) << 9,
|
||||||
0, 1 << 6, 1 << 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);
|
ret = vmdk_init_tables(bs, extent);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
/* free extent allocated by vmdk_add_extent */
|
/* 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,
|
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,
|
static int vmdk_open_vmdk4(BlockDriverState *bs,
|
||||||
BlockDriverState *file,
|
BlockDriverState *file,
|
||||||
@@ -508,7 +524,7 @@ static int vmdk_open_vmdk4(BlockDriverState *bs,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
if (header.capacity == 0) {
|
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) {
|
if (desc_offset) {
|
||||||
return vmdk_open_desc_file(bs, flags, desc_offset << 9);
|
return vmdk_open_desc_file(bs, flags, desc_offset << 9);
|
||||||
}
|
}
|
||||||
@@ -570,23 +586,40 @@ static int vmdk_open_vmdk4(BlockDriverState *bs,
|
|||||||
return -ENOTSUP;
|
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);
|
* le64_to_cpu(header.granularity);
|
||||||
if (l1_entry_sectors == 0) {
|
if (l1_entry_sectors == 0) {
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
l1_size = (le64_to_cpu(header.capacity) + l1_entry_sectors - 1)
|
l1_size = (le64_to_cpu(header.capacity) + l1_entry_sectors - 1)
|
||||||
/ l1_entry_sectors;
|
/ 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) {
|
if (le32_to_cpu(header.flags) & VMDK4_FLAG_RGD) {
|
||||||
l1_backup_offset = le64_to_cpu(header.rgd_offset) << 9;
|
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.capacity),
|
||||||
le64_to_cpu(header.gd_offset) << 9,
|
le64_to_cpu(header.gd_offset) << 9,
|
||||||
l1_backup_offset,
|
l1_backup_offset,
|
||||||
l1_size,
|
l1_size,
|
||||||
le32_to_cpu(header.num_gtes_per_gte),
|
le32_to_cpu(header.num_gtes_per_gt),
|
||||||
le64_to_cpu(header.granularity));
|
le64_to_cpu(header.granularity),
|
||||||
|
&extent);
|
||||||
|
if (ret < 0) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
extent->compressed =
|
extent->compressed =
|
||||||
le16_to_cpu(header.compressAlgorithm) == VMDK4_COMPRESSION_DEFLATE;
|
le16_to_cpu(header.compressAlgorithm) == VMDK4_COMPRESSION_DEFLATE;
|
||||||
extent->has_marker = le32_to_cpu(header.flags) & VMDK4_FLAG_MARKER;
|
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 */
|
/* FLAT extent */
|
||||||
VmdkExtent *extent;
|
VmdkExtent *extent;
|
||||||
|
|
||||||
extent = vmdk_add_extent(bs, extent_file, true, sectors,
|
ret = vmdk_add_extent(bs, extent_file, true, sectors,
|
||||||
0, 0, 0, 0, sectors);
|
0, 0, 0, 0, sectors, &extent);
|
||||||
|
if (ret < 0) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
extent->flat_start_offset = flat_offset << 9;
|
extent->flat_start_offset = flat_offset << 9;
|
||||||
} else if (!strcmp(type, "SPARSE")) {
|
} else if (!strcmp(type, "SPARSE")) {
|
||||||
/* SPARSE extent */
|
/* SPARSE extent */
|
||||||
@@ -728,7 +764,7 @@ next_line:
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int vmdk_open_desc_file(BlockDriverState *bs, int flags,
|
static int vmdk_open_desc_file(BlockDriverState *bs, int flags,
|
||||||
int64_t desc_offset)
|
uint64_t desc_offset)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
char *buf = NULL;
|
char *buf = NULL;
|
||||||
@@ -807,16 +843,17 @@ static int get_whole_cluster(BlockDriverState *bs,
|
|||||||
uint64_t offset,
|
uint64_t offset,
|
||||||
bool allocate)
|
bool allocate)
|
||||||
{
|
{
|
||||||
/* 128 sectors * 512 bytes each = grain size 64KB */
|
int ret = VMDK_OK;
|
||||||
uint8_t whole_grain[extent->cluster_sectors * 512];
|
uint8_t *whole_grain = NULL;
|
||||||
|
|
||||||
/* we will be here if it's first write on non-exist grain(cluster).
|
/* we will be here if it's first write on non-exist grain(cluster).
|
||||||
* try to read from parent image, if exist */
|
* try to read from parent image, if exist */
|
||||||
if (bs->backing_hd) {
|
if (bs->backing_hd) {
|
||||||
int ret;
|
whole_grain =
|
||||||
|
qemu_blockalign(bs, extent->cluster_sectors << BDRV_SECTOR_BITS);
|
||||||
if (!vmdk_is_cid_valid(bs)) {
|
if (!vmdk_is_cid_valid(bs)) {
|
||||||
return VMDK_ERROR;
|
ret = VMDK_ERROR;
|
||||||
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* floor offset to cluster */
|
/* 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,
|
ret = bdrv_read(bs->backing_hd, offset >> 9, whole_grain,
|
||||||
extent->cluster_sectors);
|
extent->cluster_sectors);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
return VMDK_ERROR;
|
ret = VMDK_ERROR;
|
||||||
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Write grain only into the active image */
|
/* Write grain only into the active image */
|
||||||
ret = bdrv_write(extent->file, cluster_offset, whole_grain,
|
ret = bdrv_write(extent->file, cluster_offset, whole_grain,
|
||||||
extent->cluster_sectors);
|
extent->cluster_sectors);
|
||||||
if (ret < 0) {
|
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)
|
static int vmdk_L2update(VmdkExtent *extent, VmdkMetaData *m_data)
|
||||||
@@ -1201,7 +1242,9 @@ static coroutine_fn int vmdk_co_read(BlockDriverState *bs, int64_t sector_num,
|
|||||||
* vmdk_write:
|
* vmdk_write:
|
||||||
* @zeroed: buf is ignored (data is zero), use zeroed_grain GTE feature
|
* @zeroed: buf is ignored (data is zero), use zeroed_grain GTE feature
|
||||||
* if possible, otherwise return -ENOTSUP.
|
* if possible, otherwise return -ENOTSUP.
|
||||||
* @zero_dry_run: used for zeroed == true only, don't update L2 table, just
|
* @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.
|
* Returns: error code with 0 for success.
|
||||||
*/
|
*/
|
||||||
@@ -1328,6 +1371,8 @@ static int coroutine_fn vmdk_co_write_zeroes(BlockDriverState *bs,
|
|||||||
int ret;
|
int ret;
|
||||||
BDRVVmdkState *s = bs->opaque;
|
BDRVVmdkState *s = bs->opaque;
|
||||||
qemu_co_mutex_lock(&s->lock);
|
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);
|
ret = vmdk_write(bs, sector_num, NULL, nb_sectors, true, true);
|
||||||
if (!ret) {
|
if (!ret) {
|
||||||
ret = vmdk_write(bs, sector_num, NULL, nb_sectors, true, false);
|
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.compressAlgorithm = compress ? VMDK4_COMPRESSION_DEFLATE : 0;
|
||||||
header.capacity = filesize / 512;
|
header.capacity = filesize / 512;
|
||||||
header.granularity = 128;
|
header.granularity = 128;
|
||||||
header.num_gtes_per_gte = 512;
|
header.num_gtes_per_gt = 512;
|
||||||
|
|
||||||
grains = (filesize / 512 + header.granularity - 1) / header.granularity;
|
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 =
|
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;
|
gd_size = (gt_count * sizeof(uint32_t) + 511) >> 9;
|
||||||
|
|
||||||
header.desc_offset = 1;
|
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.flags = cpu_to_le32(header.flags);
|
||||||
header.capacity = cpu_to_le64(header.capacity);
|
header.capacity = cpu_to_le64(header.capacity);
|
||||||
header.granularity = cpu_to_le64(header.granularity);
|
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_offset = cpu_to_le64(header.desc_offset);
|
||||||
header.desc_size = cpu_to_le64(header.desc_size);
|
header.desc_size = cpu_to_le64(header.desc_size);
|
||||||
header.rgd_offset = cpu_to_le64(header.rgd_offset);
|
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);
|
static QTAILQ_HEAD(drivelist, DriveInfo) drives = QTAILQ_HEAD_INITIALIZER(drives);
|
||||||
extern QemuOptsList qemu_common_drive_opts;
|
extern QemuOptsList qemu_common_drive_opts;
|
||||||
|
extern QemuOptsList qemu_old_drive_opts;
|
||||||
|
|
||||||
static const char *const if_name[IF_COUNT] = {
|
static const char *const if_name[IF_COUNT] = {
|
||||||
[IF_NONE] = "none",
|
[IF_NONE] = "none",
|
||||||
@@ -339,6 +340,7 @@ static DriveInfo *blockdev_init(QemuOpts *all_opts,
|
|||||||
QDict *bs_opts;
|
QDict *bs_opts;
|
||||||
const char *id;
|
const char *id;
|
||||||
bool has_driver_specific_opts;
|
bool has_driver_specific_opts;
|
||||||
|
BlockDriver *drv = NULL;
|
||||||
|
|
||||||
translation = BIOS_ATA_TRANSLATION_AUTO;
|
translation = BIOS_ATA_TRANSLATION_AUTO;
|
||||||
media = MEDIA_DISK;
|
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)) {
|
if (qemu_opt_get_bool(opts, "cache.writeback", true)) {
|
||||||
bdrv_flags |= BDRV_O_CACHE_WB;
|
bdrv_flags |= BDRV_O_CACHE_WB;
|
||||||
}
|
}
|
||||||
@@ -484,7 +485,11 @@ static DriveInfo *blockdev_init(QemuOpts *all_opts,
|
|||||||
return NULL;
|
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 */
|
/* disk I/O throttling */
|
||||||
@@ -699,12 +704,13 @@ static DriveInfo *blockdev_init(QemuOpts *all_opts,
|
|||||||
}
|
}
|
||||||
|
|
||||||
QINCREF(bs_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 < 0) {
|
||||||
if (ret == -EMEDIUMTYPE) {
|
if (ret == -EMEDIUMTYPE) {
|
||||||
error_report("could not open disk image %s: not in %s format",
|
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 {
|
} else {
|
||||||
error_report("could not open disk image %s: %s",
|
error_report("could not open disk image %s: %s",
|
||||||
file ?: dinfo->id, strerror(-ret));
|
file ?: dinfo->id, strerror(-ret));
|
||||||
@@ -745,6 +751,26 @@ DriveInfo *drive_init(QemuOpts *all_opts, BlockInterfaceType block_default_type)
|
|||||||
{
|
{
|
||||||
const char *value;
|
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 */
|
/* Change legacy command line options into QMP ones */
|
||||||
qemu_opt_rename(all_opts, "iops", "throttling.iops-total");
|
qemu_opt_rename(all_opts, "iops", "throttling.iops-total");
|
||||||
qemu_opt_rename(all_opts, "iops_rd", "throttling.iops-read");
|
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 = {
|
QemuOptsList qemu_drive_opts = {
|
||||||
.name = "drive",
|
.name = "drive",
|
||||||
.head = QTAILQ_HEAD_INITIALIZER(qemu_drive_opts.head),
|
.head = QTAILQ_HEAD_INITIALIZER(qemu_drive_opts.head),
|
||||||
|
|||||||
17
configure
vendored
17
configure
vendored
@@ -231,7 +231,7 @@ libusb=""
|
|||||||
usb_redir=""
|
usb_redir=""
|
||||||
glx=""
|
glx=""
|
||||||
zlib="yes"
|
zlib="yes"
|
||||||
guest_agent="yes"
|
guest_agent=""
|
||||||
want_tools="yes"
|
want_tools="yes"
|
||||||
libiscsi=""
|
libiscsi=""
|
||||||
coroutine=""
|
coroutine=""
|
||||||
@@ -3444,10 +3444,15 @@ if test "$softmmu" = yes ; then
|
|||||||
virtfs=no
|
virtfs=no
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
if [ "$linux" = "yes" -o "$bsd" = "yes" -o "$solaris" = "yes" ] ; then
|
|
||||||
if [ "$guest_agent" = "yes" ]; then
|
|
||||||
tools="qemu-ga\$(EXESUF) $tools"
|
|
||||||
fi
|
fi
|
||||||
|
if [ "$guest_agent" != "no" ]; then
|
||||||
|
if [ "$linux" = "yes" -o "$bsd" = "yes" -o "$solaris" = "yes" ] ; then
|
||||||
|
tools="qemu-ga\$(EXESUF) $tools"
|
||||||
|
guest_agent=yes
|
||||||
|
elif [ "$guest_agent" != yes ]; then
|
||||||
|
guest_agent=no
|
||||||
|
else
|
||||||
|
error_exit "Guest agent is not supported on this platform"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -4502,13 +4507,13 @@ if [ "$dtc_internal" = "yes" ]; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# build tree in object directory in case the source is not in the current directory
|
# 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 pc-bios/optionrom pc-bios/spapr-rtas pc-bios/s390-ccw"
|
||||||
DIRS="$DIRS roms/seabios roms/vgabios"
|
DIRS="$DIRS roms/seabios roms/vgabios"
|
||||||
DIRS="$DIRS qapi-generated"
|
DIRS="$DIRS qapi-generated"
|
||||||
FILES="Makefile tests/tcg/Makefile qdict-test-data.txt"
|
FILES="Makefile tests/tcg/Makefile qdict-test-data.txt"
|
||||||
FILES="$FILES tests/tcg/cris/Makefile tests/tcg/cris/.gdbinit"
|
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/optionrom/Makefile pc-bios/keymaps"
|
||||||
FILES="$FILES pc-bios/spapr-rtas/Makefile"
|
FILES="$FILES pc-bios/spapr-rtas/Makefile"
|
||||||
FILES="$FILES pc-bios/s390-ccw/Makefile"
|
FILES="$FILES pc-bios/s390-ccw/Makefile"
|
||||||
|
|||||||
14
cpus.c
14
cpus.c
@@ -62,12 +62,17 @@
|
|||||||
|
|
||||||
static CPUState *next_cpu;
|
static CPUState *next_cpu;
|
||||||
|
|
||||||
|
bool cpu_is_stopped(CPUState *cpu)
|
||||||
|
{
|
||||||
|
return cpu->stopped || !runstate_is_running();
|
||||||
|
}
|
||||||
|
|
||||||
static bool cpu_thread_is_idle(CPUState *cpu)
|
static bool cpu_thread_is_idle(CPUState *cpu)
|
||||||
{
|
{
|
||||||
if (cpu->stop || cpu->queued_work_first) {
|
if (cpu->stop || cpu->queued_work_first) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (cpu->stopped || !runstate_is_running()) {
|
if (cpu_is_stopped(cpu)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (!cpu->halted || qemu_cpu_has_work(cpu) ||
|
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)
|
static int do_vm_stop(RunState state)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
@@ -457,7 +457,7 @@ static bool cpu_can_run(CPUState *cpu)
|
|||||||
if (cpu->stop) {
|
if (cpu->stop) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (cpu->stopped || !runstate_is_running()) {
|
if (cpu_is_stopped(cpu)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -34,9 +34,9 @@ CONFIG_PFLASH_CFI02=y
|
|||||||
CONFIG_MICRODRIVE=y
|
CONFIG_MICRODRIVE=y
|
||||||
CONFIG_USB_MUSB=y
|
CONFIG_USB_MUSB=y
|
||||||
|
|
||||||
CONFIG_ARM9MPCORE=y
|
|
||||||
CONFIG_ARM11MPCORE=y
|
CONFIG_ARM11MPCORE=y
|
||||||
CONFIG_ARM15MPCORE=y
|
CONFIG_A9MPCORE=y
|
||||||
|
CONFIG_A15MPCORE=y
|
||||||
|
|
||||||
CONFIG_ARM_GIC=y
|
CONFIG_ARM_GIC=y
|
||||||
CONFIG_ARM_GIC_KVM=$(CONFIG_KVM)
|
CONFIG_ARM_GIC_KVM=$(CONFIG_KVM)
|
||||||
|
|||||||
@@ -33,7 +33,6 @@ CONFIG_MC146818RTC=y
|
|||||||
CONFIG_PAM=y
|
CONFIG_PAM=y
|
||||||
CONFIG_PCI_PIIX=y
|
CONFIG_PCI_PIIX=y
|
||||||
CONFIG_WDT_IB700=y
|
CONFIG_WDT_IB700=y
|
||||||
CONFIG_PC_SYSFW=y
|
|
||||||
CONFIG_XEN_I386=$(CONFIG_XEN)
|
CONFIG_XEN_I386=$(CONFIG_XEN)
|
||||||
CONFIG_ISA_DEBUG=y
|
CONFIG_ISA_DEBUG=y
|
||||||
CONFIG_ISA_TESTDEV=y
|
CONFIG_ISA_TESTDEV=y
|
||||||
|
|||||||
@@ -34,3 +34,4 @@ CONFIG_JAZZ_LED=y
|
|||||||
CONFIG_MC146818RTC=y
|
CONFIG_MC146818RTC=y
|
||||||
CONFIG_VT82C686=y
|
CONFIG_VT82C686=y
|
||||||
CONFIG_ISA_TESTDEV=y
|
CONFIG_ISA_TESTDEV=y
|
||||||
|
CONFIG_EMPTY_SLOT=y
|
||||||
|
|||||||
@@ -34,3 +34,4 @@ CONFIG_JAZZ_LED=y
|
|||||||
CONFIG_MC146818RTC=y
|
CONFIG_MC146818RTC=y
|
||||||
CONFIG_VT82C686=y
|
CONFIG_VT82C686=y
|
||||||
CONFIG_ISA_TESTDEV=y
|
CONFIG_ISA_TESTDEV=y
|
||||||
|
CONFIG_EMPTY_SLOT=y
|
||||||
|
|||||||
@@ -36,3 +36,4 @@ CONFIG_JAZZ_LED=y
|
|||||||
CONFIG_MC146818RTC=y
|
CONFIG_MC146818RTC=y
|
||||||
CONFIG_VT82C686=y
|
CONFIG_VT82C686=y
|
||||||
CONFIG_ISA_TESTDEV=y
|
CONFIG_ISA_TESTDEV=y
|
||||||
|
CONFIG_EMPTY_SLOT=y
|
||||||
|
|||||||
@@ -34,3 +34,4 @@ CONFIG_JAZZ_LED=y
|
|||||||
CONFIG_MC146818RTC=y
|
CONFIG_MC146818RTC=y
|
||||||
CONFIG_VT82C686=y
|
CONFIG_VT82C686=y
|
||||||
CONFIG_ISA_TESTDEV=y
|
CONFIG_ISA_TESTDEV=y
|
||||||
|
CONFIG_EMPTY_SLOT=y
|
||||||
|
|||||||
@@ -33,7 +33,6 @@ CONFIG_MC146818RTC=y
|
|||||||
CONFIG_PAM=y
|
CONFIG_PAM=y
|
||||||
CONFIG_PCI_PIIX=y
|
CONFIG_PCI_PIIX=y
|
||||||
CONFIG_WDT_IB700=y
|
CONFIG_WDT_IB700=y
|
||||||
CONFIG_PC_SYSFW=y
|
|
||||||
CONFIG_XEN_I386=$(CONFIG_XEN)
|
CONFIG_XEN_I386=$(CONFIG_XEN)
|
||||||
CONFIG_ISA_DEBUG=y
|
CONFIG_ISA_DEBUG=y
|
||||||
CONFIG_ISA_TESTDEV=y
|
CONFIG_ISA_TESTDEV=y
|
||||||
|
|||||||
@@ -91,6 +91,29 @@
|
|||||||
port = "4"
|
port = "4"
|
||||||
chassis = "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"]
|
[device "ich9-ehci-1"]
|
||||||
driver = "ich9-usb-ehci1"
|
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 {
|
typedef struct DumpState {
|
||||||
|
GuestPhysBlockList guest_phys_blocks;
|
||||||
ArchDumpInfo dump_info;
|
ArchDumpInfo dump_info;
|
||||||
MemoryMappingList list;
|
MemoryMappingList list;
|
||||||
uint16_t phdr_num;
|
uint16_t phdr_num;
|
||||||
@@ -69,7 +70,7 @@ typedef struct DumpState {
|
|||||||
hwaddr memory_offset;
|
hwaddr memory_offset;
|
||||||
int fd;
|
int fd;
|
||||||
|
|
||||||
RAMBlock *block;
|
GuestPhysBlock *next_block;
|
||||||
ram_addr_t start;
|
ram_addr_t start;
|
||||||
bool has_filter;
|
bool has_filter;
|
||||||
int64_t begin;
|
int64_t begin;
|
||||||
@@ -81,6 +82,7 @@ static int dump_cleanup(DumpState *s)
|
|||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
|
guest_phys_blocks_free(&s->guest_phys_blocks);
|
||||||
memory_mapping_list_free(&s->list);
|
memory_mapping_list_free(&s->list);
|
||||||
if (s->fd != -1) {
|
if (s->fd != -1) {
|
||||||
close(s->fd);
|
close(s->fd);
|
||||||
@@ -187,7 +189,8 @@ static int write_elf32_header(DumpState *s)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int write_elf64_load(DumpState *s, MemoryMapping *memory_mapping,
|
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;
|
Elf64_Phdr phdr;
|
||||||
int ret;
|
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_type = cpu_convert_to_target32(PT_LOAD, endian);
|
||||||
phdr.p_offset = cpu_convert_to_target64(offset, endian);
|
phdr.p_offset = cpu_convert_to_target64(offset, endian);
|
||||||
phdr.p_paddr = cpu_convert_to_target64(memory_mapping->phys_addr, endian);
|
phdr.p_paddr = cpu_convert_to_target64(memory_mapping->phys_addr, endian);
|
||||||
if (offset == -1) {
|
phdr.p_filesz = cpu_convert_to_target64(filesz, endian);
|
||||||
/* 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_memsz = cpu_convert_to_target64(memory_mapping->length, endian);
|
phdr.p_memsz = cpu_convert_to_target64(memory_mapping->length, endian);
|
||||||
phdr.p_vaddr = cpu_convert_to_target64(memory_mapping->virt_addr, 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);
|
ret = fd_write_vmcore(&phdr, sizeof(Elf64_Phdr), s);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
dump_error(s, "dump: failed to write program header table.\n");
|
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,
|
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;
|
Elf32_Phdr phdr;
|
||||||
int ret;
|
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_type = cpu_convert_to_target32(PT_LOAD, endian);
|
||||||
phdr.p_offset = cpu_convert_to_target32(offset, endian);
|
phdr.p_offset = cpu_convert_to_target32(offset, endian);
|
||||||
phdr.p_paddr = cpu_convert_to_target32(memory_mapping->phys_addr, endian);
|
phdr.p_paddr = cpu_convert_to_target32(memory_mapping->phys_addr, endian);
|
||||||
if (offset == -1) {
|
phdr.p_filesz = cpu_convert_to_target32(filesz, endian);
|
||||||
/* 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_memsz = cpu_convert_to_target32(memory_mapping->length, endian);
|
phdr.p_memsz = cpu_convert_to_target32(memory_mapping->length, endian);
|
||||||
phdr.p_vaddr = cpu_convert_to_target32(memory_mapping->virt_addr, 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);
|
ret = fd_write_vmcore(&phdr, sizeof(Elf32_Phdr), s);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
dump_error(s, "dump: failed to write program header table.\n");
|
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. */
|
/* 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 size)
|
||||||
{
|
{
|
||||||
int64_t i;
|
int64_t i;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
for (i = 0; i < size / TARGET_PAGE_SIZE; i++) {
|
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);
|
TARGET_PAGE_SIZE);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
return ret;
|
return ret;
|
||||||
@@ -408,7 +406,7 @@ static int write_memory(DumpState *s, RAMBlock *block, ram_addr_t start,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ((size % TARGET_PAGE_SIZE) != 0) {
|
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);
|
size % TARGET_PAGE_SIZE);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
return ret;
|
return ret;
|
||||||
@@ -418,57 +416,71 @@ static int write_memory(DumpState *s, RAMBlock *block, ram_addr_t start,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* get the memory's offset in the vmcore */
|
/* get the memory's offset and size in the vmcore */
|
||||||
static hwaddr get_offset(hwaddr phys_addr,
|
static void get_offset_range(hwaddr phys_addr,
|
||||||
DumpState *s)
|
ram_addr_t mapping_length,
|
||||||
|
DumpState *s,
|
||||||
|
hwaddr *p_offset,
|
||||||
|
hwaddr *p_filesz)
|
||||||
{
|
{
|
||||||
RAMBlock *block;
|
GuestPhysBlock *block;
|
||||||
hwaddr offset = s->memory_offset;
|
hwaddr offset = s->memory_offset;
|
||||||
int64_t size_in_block, start;
|
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 (s->has_filter) {
|
||||||
if (phys_addr < s->begin || phys_addr >= s->begin + s->length) {
|
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 (s->has_filter) {
|
||||||
if (block->offset >= s->begin + s->length ||
|
if (block->target_start >= s->begin + s->length ||
|
||||||
block->offset + block->length <= s->begin) {
|
block->target_end <= s->begin) {
|
||||||
/* This block is out of the range */
|
/* This block is out of the range */
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (s->begin <= block->offset) {
|
if (s->begin <= block->target_start) {
|
||||||
start = block->offset;
|
start = block->target_start;
|
||||||
} else {
|
} else {
|
||||||
start = s->begin;
|
start = s->begin;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_in_block = block->length - (start - block->offset);
|
size_in_block = block->target_end - start;
|
||||||
if (s->begin + s->length < block->offset + block->length) {
|
if (s->begin + s->length < block->target_end) {
|
||||||
size_in_block -= block->offset + block->length -
|
size_in_block -= block->target_end - (s->begin + s->length);
|
||||||
(s->begin + s->length);
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
start = block->offset;
|
start = block->target_start;
|
||||||
size_in_block = block->length;
|
size_in_block = block->target_end - block->target_start;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (phys_addr >= start && phys_addr < start + size_in_block) {
|
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;
|
offset += size_in_block;
|
||||||
}
|
}
|
||||||
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int write_elf_loads(DumpState *s)
|
static int write_elf_loads(DumpState *s)
|
||||||
{
|
{
|
||||||
hwaddr offset;
|
hwaddr offset, filesz;
|
||||||
MemoryMapping *memory_mapping;
|
MemoryMapping *memory_mapping;
|
||||||
uint32_t phdr_index = 1;
|
uint32_t phdr_index = 1;
|
||||||
int ret;
|
int ret;
|
||||||
@@ -481,11 +493,15 @@ static int write_elf_loads(DumpState *s)
|
|||||||
}
|
}
|
||||||
|
|
||||||
QTAILQ_FOREACH(memory_mapping, &s->list.head, next) {
|
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) {
|
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 {
|
} 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) {
|
if (ret < 0) {
|
||||||
@@ -596,7 +612,7 @@ static int dump_completed(DumpState *s)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int get_next_block(DumpState *s, RAMBlock *block)
|
static int get_next_block(DumpState *s, GuestPhysBlock *block)
|
||||||
{
|
{
|
||||||
while (1) {
|
while (1) {
|
||||||
block = QTAILQ_NEXT(block, next);
|
block = QTAILQ_NEXT(block, next);
|
||||||
@@ -606,16 +622,16 @@ static int get_next_block(DumpState *s, RAMBlock *block)
|
|||||||
}
|
}
|
||||||
|
|
||||||
s->start = 0;
|
s->start = 0;
|
||||||
s->block = block;
|
s->next_block = block;
|
||||||
if (s->has_filter) {
|
if (s->has_filter) {
|
||||||
if (block->offset >= s->begin + s->length ||
|
if (block->target_start >= s->begin + s->length ||
|
||||||
block->offset + block->length <= s->begin) {
|
block->target_end <= s->begin) {
|
||||||
/* This block is out of the range */
|
/* This block is out of the range */
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (s->begin > block->offset) {
|
if (s->begin > block->target_start) {
|
||||||
s->start = s->begin - block->offset;
|
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 */
|
/* write all memory to vmcore */
|
||||||
static int dump_iterate(DumpState *s)
|
static int dump_iterate(DumpState *s)
|
||||||
{
|
{
|
||||||
RAMBlock *block;
|
GuestPhysBlock *block;
|
||||||
int64_t size;
|
int64_t size;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
block = s->block;
|
block = s->next_block;
|
||||||
|
|
||||||
size = block->length;
|
size = block->target_end - block->target_start;
|
||||||
if (s->has_filter) {
|
if (s->has_filter) {
|
||||||
size -= s->start;
|
size -= s->start;
|
||||||
if (s->begin + s->length < block->offset + block->length) {
|
if (s->begin + s->length < block->target_end) {
|
||||||
size -= block->offset + block->length - (s->begin + s->length);
|
size -= block->target_end - (s->begin + s->length);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ret = write_memory(s, block, s->start, size);
|
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)
|
static ram_addr_t get_start_block(DumpState *s)
|
||||||
{
|
{
|
||||||
RAMBlock *block;
|
GuestPhysBlock *block;
|
||||||
|
|
||||||
if (!s->has_filter) {
|
if (!s->has_filter) {
|
||||||
s->block = QTAILQ_FIRST(&ram_list.blocks);
|
s->next_block = QTAILQ_FIRST(&s->guest_phys_blocks.head);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
QTAILQ_FOREACH(block, &ram_list.blocks, next) {
|
QTAILQ_FOREACH(block, &s->guest_phys_blocks.head, next) {
|
||||||
if (block->offset >= s->begin + s->length ||
|
if (block->target_start >= s->begin + s->length ||
|
||||||
block->offset + block->length <= s->begin) {
|
block->target_end <= s->begin) {
|
||||||
/* This block is out of the range */
|
/* This block is out of the range */
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
s->block = block;
|
s->next_block = block;
|
||||||
if (s->begin > block->offset) {
|
if (s->begin > block->target_start) {
|
||||||
s->start = s->begin - block->offset;
|
s->start = s->begin - block->target_start;
|
||||||
} else {
|
} else {
|
||||||
s->start = 0;
|
s->start = 0;
|
||||||
}
|
}
|
||||||
@@ -713,24 +729,8 @@ static int dump_init(DumpState *s, int fd, bool paging, bool has_filter,
|
|||||||
s->resume = false;
|
s->resume = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
s->errp = errp;
|
/* If we use KVM, we should synchronize the registers before we get dump
|
||||||
s->fd = fd;
|
* info or physmap info.
|
||||||
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.
|
|
||||||
*/
|
*/
|
||||||
cpu_synchronize_all_states();
|
cpu_synchronize_all_states();
|
||||||
nr_cpus = 0;
|
nr_cpus = 0;
|
||||||
@@ -738,7 +738,26 @@ static int dump_init(DumpState *s, int fd, bool paging, bool has_filter,
|
|||||||
nr_cpus++;
|
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) {
|
if (ret < 0) {
|
||||||
error_set(errp, QERR_UNSUPPORTED);
|
error_set(errp, QERR_UNSUPPORTED);
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
@@ -754,13 +773,13 @@ static int dump_init(DumpState *s, int fd, bool paging, bool has_filter,
|
|||||||
/* get memory mapping */
|
/* get memory mapping */
|
||||||
memory_mapping_list_init(&s->list);
|
memory_mapping_list_init(&s->list);
|
||||||
if (paging) {
|
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) {
|
if (err != NULL) {
|
||||||
error_propagate(errp, err);
|
error_propagate(errp, err);
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
} else {
|
} 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) {
|
if (s->has_filter) {
|
||||||
@@ -812,6 +831,8 @@ static int dump_init(DumpState *s, int fd, bool paging, bool has_filter,
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
|
guest_phys_blocks_free(&s->guest_phys_blocks);
|
||||||
|
|
||||||
if (s->resume) {
|
if (s->resume) {
|
||||||
vm_start();
|
vm_start();
|
||||||
}
|
}
|
||||||
@@ -859,7 +880,7 @@ void qmp_dump_guest_memory(bool paging, const char *file, bool has_begin,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
s = g_malloc(sizeof(DumpState));
|
s = g_malloc0(sizeof(DumpState));
|
||||||
|
|
||||||
ret = dump_init(s, fd, paging, has_begin, begin, length, errp);
|
ret = dump_init(s, fd, paging, has_begin, begin, length, errp);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
|
|||||||
3
exec.c
3
exec.c
@@ -402,11 +402,14 @@ void cpu_exec_init(CPUArchState *env)
|
|||||||
#if defined(CONFIG_USER_ONLY)
|
#if defined(CONFIG_USER_ONLY)
|
||||||
cpu_list_unlock();
|
cpu_list_unlock();
|
||||||
#endif
|
#endif
|
||||||
|
if (qdev_get_vmsd(DEVICE(cpu)) == NULL) {
|
||||||
vmstate_register(NULL, cpu_index, &vmstate_cpu_common, cpu);
|
vmstate_register(NULL, cpu_index, &vmstate_cpu_common, cpu);
|
||||||
|
}
|
||||||
#if defined(CPU_SAVE_VERSION) && !defined(CONFIG_USER_ONLY)
|
#if defined(CPU_SAVE_VERSION) && !defined(CONFIG_USER_ONLY)
|
||||||
register_savevm(NULL, "cpu", cpu_index, CPU_SAVE_VERSION,
|
register_savevm(NULL, "cpu", cpu_index, CPU_SAVE_VERSION,
|
||||||
cpu_save, cpu_load, env);
|
cpu_save, cpu_load, env);
|
||||||
assert(cc->vmsd == NULL);
|
assert(cc->vmsd == NULL);
|
||||||
|
assert(qdev_get_vmsd(DEVICE(cpu)) == NULL);
|
||||||
#endif
|
#endif
|
||||||
if (cc->vmsd != NULL) {
|
if (cc->vmsd != NULL) {
|
||||||
vmstate_register(NULL, cpu_index, cc->vmsd, cpu);
|
vmstate_register(NULL, cpu_index, cc->vmsd, cpu);
|
||||||
|
|||||||
@@ -621,6 +621,8 @@ void gdb_register_coprocessor(CPUState *cpu,
|
|||||||
if (g_pos != s->base_reg) {
|
if (g_pos != s->base_reg) {
|
||||||
fprintf(stderr, "Error: Bad gdb register numbering for '%s'\n"
|
fprintf(stderr, "Error: Bad gdb register numbering for '%s'\n"
|
||||||
"Expected %d got %d\n", xml, g_pos, s->base_reg);
|
"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':
|
case 'g':
|
||||||
cpu_synchronize_state(s->g_cpu);
|
cpu_synchronize_state(s->g_cpu);
|
||||||
len = 0;
|
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);
|
reg_size = gdb_read_register(s->g_cpu, mem_buf + len, addr);
|
||||||
len += reg_size;
|
len += reg_size;
|
||||||
}
|
}
|
||||||
@@ -914,7 +916,7 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
|
|||||||
registers = mem_buf;
|
registers = mem_buf;
|
||||||
len = strlen(p) / 2;
|
len = strlen(p) / 2;
|
||||||
hextomem((uint8_t *)registers, p, len);
|
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);
|
reg_size = gdb_write_register(s->g_cpu, registers, addr);
|
||||||
len -= reg_size;
|
len -= reg_size;
|
||||||
registers += reg_size;
|
registers += reg_size;
|
||||||
|
|||||||
@@ -61,6 +61,8 @@ static int virtio_9p_device_init(VirtIODevice *vdev)
|
|||||||
|
|
||||||
s->vq = virtio_add_queue(vdev, MAX_REQ, handle_9p_output);
|
s->vq = virtio_add_queue(vdev, MAX_REQ, handle_9p_output);
|
||||||
|
|
||||||
|
v9fs_path_init(&path);
|
||||||
|
|
||||||
fse = get_fsdev_fsentry(s->fsconf.fsdev_id);
|
fse = get_fsdev_fsentry(s->fsconf.fsdev_id);
|
||||||
|
|
||||||
if (!fse) {
|
if (!fse) {
|
||||||
@@ -111,7 +113,6 @@ static int virtio_9p_device_init(VirtIODevice *vdev)
|
|||||||
* call back to do that. Since we are in the init path, we don't
|
* call back to do that. Since we are in the init path, we don't
|
||||||
* use co-routines here.
|
* use co-routines here.
|
||||||
*/
|
*/
|
||||||
v9fs_path_init(&path);
|
|
||||||
if (s->ops->name_to_path(&s->ctx, NULL, "/", &path) < 0) {
|
if (s->ops->name_to_path(&s->ctx, NULL, "/", &path) < 0) {
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"error in converting name to path %s", strerror(errno));
|
"error in converting name to path %s", strerror(errno));
|
||||||
|
|||||||
@@ -173,7 +173,6 @@ static QEMUMachine clipper_machine = {
|
|||||||
.init = clipper_init,
|
.init = clipper_init,
|
||||||
.max_cpus = 4,
|
.max_cpus = 4,
|
||||||
.is_default = 1,
|
.is_default = 1,
|
||||||
DEFAULT_MACHINE_OPTIONS,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static void clipper_machine_init(void)
|
static void clipper_machine_init(void)
|
||||||
|
|||||||
@@ -26,9 +26,9 @@ typedef struct TyphoonCchip {
|
|||||||
} TyphoonCchip;
|
} TyphoonCchip;
|
||||||
|
|
||||||
typedef struct TyphoonWindow {
|
typedef struct TyphoonWindow {
|
||||||
uint32_t base_addr;
|
uint64_t wba;
|
||||||
uint32_t mask;
|
uint64_t wsm;
|
||||||
uint32_t translated_base_pfn;
|
uint64_t tba;
|
||||||
} TyphoonWindow;
|
} TyphoonWindow;
|
||||||
|
|
||||||
typedef struct TyphoonPchip {
|
typedef struct TyphoonPchip {
|
||||||
@@ -37,6 +37,10 @@ typedef struct TyphoonPchip {
|
|||||||
MemoryRegion reg_mem;
|
MemoryRegion reg_mem;
|
||||||
MemoryRegion reg_io;
|
MemoryRegion reg_io;
|
||||||
MemoryRegion reg_conf;
|
MemoryRegion reg_conf;
|
||||||
|
|
||||||
|
AddressSpace iommu_as;
|
||||||
|
MemoryRegion iommu;
|
||||||
|
|
||||||
uint64_t ctl;
|
uint64_t ctl;
|
||||||
TyphoonWindow win[4];
|
TyphoonWindow win[4];
|
||||||
} TyphoonPchip;
|
} TyphoonPchip;
|
||||||
@@ -209,53 +213,53 @@ static uint64_t pchip_read(void *opaque, hwaddr addr, unsigned size)
|
|||||||
switch (addr) {
|
switch (addr) {
|
||||||
case 0x0000:
|
case 0x0000:
|
||||||
/* WSBA0: Window Space Base Address Register. */
|
/* WSBA0: Window Space Base Address Register. */
|
||||||
ret = s->pchip.win[0].base_addr;
|
ret = s->pchip.win[0].wba;
|
||||||
break;
|
break;
|
||||||
case 0x0040:
|
case 0x0040:
|
||||||
/* WSBA1 */
|
/* WSBA1 */
|
||||||
ret = s->pchip.win[1].base_addr;
|
ret = s->pchip.win[1].wba;
|
||||||
break;
|
break;
|
||||||
case 0x0080:
|
case 0x0080:
|
||||||
/* WSBA2 */
|
/* WSBA2 */
|
||||||
ret = s->pchip.win[2].base_addr;
|
ret = s->pchip.win[2].wba;
|
||||||
break;
|
break;
|
||||||
case 0x00c0:
|
case 0x00c0:
|
||||||
/* WSBA3 */
|
/* WSBA3 */
|
||||||
ret = s->pchip.win[3].base_addr;
|
ret = s->pchip.win[3].wba;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x0100:
|
case 0x0100:
|
||||||
/* WSM0: Window Space Mask Register. */
|
/* WSM0: Window Space Mask Register. */
|
||||||
ret = s->pchip.win[0].mask;
|
ret = s->pchip.win[0].wsm;
|
||||||
break;
|
break;
|
||||||
case 0x0140:
|
case 0x0140:
|
||||||
/* WSM1 */
|
/* WSM1 */
|
||||||
ret = s->pchip.win[1].mask;
|
ret = s->pchip.win[1].wsm;
|
||||||
break;
|
break;
|
||||||
case 0x0180:
|
case 0x0180:
|
||||||
/* WSM2 */
|
/* WSM2 */
|
||||||
ret = s->pchip.win[2].mask;
|
ret = s->pchip.win[2].wsm;
|
||||||
break;
|
break;
|
||||||
case 0x01c0:
|
case 0x01c0:
|
||||||
/* WSM3 */
|
/* WSM3 */
|
||||||
ret = s->pchip.win[3].mask;
|
ret = s->pchip.win[3].wsm;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x0200:
|
case 0x0200:
|
||||||
/* TBA0: Translated Base Address Register. */
|
/* TBA0: Translated Base Address Register. */
|
||||||
ret = (uint64_t)s->pchip.win[0].translated_base_pfn << 10;
|
ret = s->pchip.win[0].tba;
|
||||||
break;
|
break;
|
||||||
case 0x0240:
|
case 0x0240:
|
||||||
/* TBA1 */
|
/* TBA1 */
|
||||||
ret = (uint64_t)s->pchip.win[1].translated_base_pfn << 10;
|
ret = s->pchip.win[1].tba;
|
||||||
break;
|
break;
|
||||||
case 0x0280:
|
case 0x0280:
|
||||||
/* TBA2 */
|
/* TBA2 */
|
||||||
ret = (uint64_t)s->pchip.win[2].translated_base_pfn << 10;
|
ret = s->pchip.win[2].tba;
|
||||||
break;
|
break;
|
||||||
case 0x02c0:
|
case 0x02c0:
|
||||||
/* TBA3 */
|
/* TBA3 */
|
||||||
ret = (uint64_t)s->pchip.win[3].translated_base_pfn << 10;
|
ret = s->pchip.win[3].tba;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x0300:
|
case 0x0300:
|
||||||
@@ -458,53 +462,53 @@ static void pchip_write(void *opaque, hwaddr addr,
|
|||||||
switch (addr) {
|
switch (addr) {
|
||||||
case 0x0000:
|
case 0x0000:
|
||||||
/* WSBA0: Window Space Base Address Register. */
|
/* WSBA0: Window Space Base Address Register. */
|
||||||
s->pchip.win[0].base_addr = val;
|
s->pchip.win[0].wba = val & 0xfff00003u;
|
||||||
break;
|
break;
|
||||||
case 0x0040:
|
case 0x0040:
|
||||||
/* WSBA1 */
|
/* WSBA1 */
|
||||||
s->pchip.win[1].base_addr = val;
|
s->pchip.win[1].wba = val & 0xfff00003u;
|
||||||
break;
|
break;
|
||||||
case 0x0080:
|
case 0x0080:
|
||||||
/* WSBA2 */
|
/* WSBA2 */
|
||||||
s->pchip.win[2].base_addr = val;
|
s->pchip.win[2].wba = val & 0xfff00003u;
|
||||||
break;
|
break;
|
||||||
case 0x00c0:
|
case 0x00c0:
|
||||||
/* WSBA3 */
|
/* WSBA3 */
|
||||||
s->pchip.win[3].base_addr = val;
|
s->pchip.win[3].wba = (val & 0x80fff00001ull) | 2;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x0100:
|
case 0x0100:
|
||||||
/* WSM0: Window Space Mask Register. */
|
/* WSM0: Window Space Mask Register. */
|
||||||
s->pchip.win[0].mask = val;
|
s->pchip.win[0].wsm = val & 0xfff00000u;
|
||||||
break;
|
break;
|
||||||
case 0x0140:
|
case 0x0140:
|
||||||
/* WSM1 */
|
/* WSM1 */
|
||||||
s->pchip.win[1].mask = val;
|
s->pchip.win[1].wsm = val & 0xfff00000u;
|
||||||
break;
|
break;
|
||||||
case 0x0180:
|
case 0x0180:
|
||||||
/* WSM2 */
|
/* WSM2 */
|
||||||
s->pchip.win[2].mask = val;
|
s->pchip.win[2].wsm = val & 0xfff00000u;
|
||||||
break;
|
break;
|
||||||
case 0x01c0:
|
case 0x01c0:
|
||||||
/* WSM3 */
|
/* WSM3 */
|
||||||
s->pchip.win[3].mask = val;
|
s->pchip.win[3].wsm = val & 0xfff00000u;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x0200:
|
case 0x0200:
|
||||||
/* TBA0: Translated Base Address Register. */
|
/* TBA0: Translated Base Address Register. */
|
||||||
s->pchip.win[0].translated_base_pfn = val >> 10;
|
s->pchip.win[0].tba = val & 0x7fffffc00ull;
|
||||||
break;
|
break;
|
||||||
case 0x0240:
|
case 0x0240:
|
||||||
/* TBA1 */
|
/* TBA1 */
|
||||||
s->pchip.win[1].translated_base_pfn = val >> 10;
|
s->pchip.win[1].tba = val & 0x7fffffc00ull;
|
||||||
break;
|
break;
|
||||||
case 0x0280:
|
case 0x0280:
|
||||||
/* TBA2 */
|
/* TBA2 */
|
||||||
s->pchip.win[2].translated_base_pfn = val >> 10;
|
s->pchip.win[2].tba = val & 0x7fffffc00ull;
|
||||||
break;
|
break;
|
||||||
case 0x02c0:
|
case 0x02c0:
|
||||||
/* TBA3 */
|
/* TBA3 */
|
||||||
s->pchip.win[3].translated_base_pfn = val >> 10;
|
s->pchip.win[3].tba = val & 0x7fffffc00ull;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x0300:
|
case 0x0300:
|
||||||
@@ -512,7 +516,6 @@ static void pchip_write(void *opaque, hwaddr addr,
|
|||||||
oldval = s->pchip.ctl;
|
oldval = s->pchip.ctl;
|
||||||
oldval &= ~0x00001cff0fc7ffull; /* RW fields */
|
oldval &= ~0x00001cff0fc7ffull; /* RW fields */
|
||||||
oldval |= val & 0x00001cff0fc7ffull;
|
oldval |= val & 0x00001cff0fc7ffull;
|
||||||
|
|
||||||
s->pchip.ctl = oldval;
|
s->pchip.ctl = oldval;
|
||||||
break;
|
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)
|
static void typhoon_set_irq(void *opaque, int irq, int level)
|
||||||
{
|
{
|
||||||
TyphoonState *s = opaque;
|
TyphoonState *s = opaque;
|
||||||
@@ -688,6 +825,9 @@ PCIBus *typhoon_init(ram_addr_t ram_size, ISABus **isa_bus,
|
|||||||
s = TYPHOON_PCI_HOST_BRIDGE(dev);
|
s = TYPHOON_PCI_HOST_BRIDGE(dev);
|
||||||
phb = 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. */
|
/* Remember the CPUs so that we can deliver interrupts to them. */
|
||||||
for (i = 0; i < 4; i++) {
|
for (i = 0; i < 4; i++) {
|
||||||
AlphaCPU *cpu = cpus[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);
|
0, 64, TYPE_PCI_BUS);
|
||||||
phb->bus = b;
|
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. */
|
/* Pchip0 PCI special/interrupt acknowledge, 0x801.F800.0000, 64MB. */
|
||||||
memory_region_init_io(&s->pchip.reg_iack, OBJECT(s), &alpha_pci_iack_ops,
|
memory_region_init_io(&s->pchip.reg_iack, OBJECT(s), &alpha_pci_iack_ops,
|
||||||
b, "pci0-iack", 64*MB);
|
b, "pci0-iack", 64*MB);
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
obj-y += boot.o collie.o exynos4_boards.o gumstix.o highbank.o
|
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 += 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 += 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
|
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;
|
DeviceState *nvic;
|
||||||
/* FIXME: make this local state. */
|
/* FIXME: make this local state. */
|
||||||
static qemu_irq pic[64];
|
static qemu_irq pic[64];
|
||||||
qemu_irq *cpu_pic;
|
|
||||||
int image_size;
|
int image_size;
|
||||||
uint64_t entry;
|
uint64_t entry;
|
||||||
uint64_t lowaddr;
|
uint64_t lowaddr;
|
||||||
@@ -221,8 +220,8 @@ qemu_irq *armv7m_init(MemoryRegion *address_space_mem,
|
|||||||
nvic = qdev_create(NULL, "armv7m_nvic");
|
nvic = qdev_create(NULL, "armv7m_nvic");
|
||||||
env->nvic = nvic;
|
env->nvic = nvic;
|
||||||
qdev_init_nofail(nvic);
|
qdev_init_nofail(nvic);
|
||||||
cpu_pic = arm_pic_init_cpu(cpu);
|
sysbus_connect_irq(SYS_BUS_DEVICE(nvic), 0,
|
||||||
sysbus_connect_irq(SYS_BUS_DEVICE(nvic), 0, cpu_pic[ARM_PIC_CPU_IRQ]);
|
qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_IRQ));
|
||||||
for (i = 0; i < 64; i++) {
|
for (i = 0; i < 64; i++) {
|
||||||
pic[i] = qdev_get_gpio_in(nvic, i);
|
pic[i] = qdev_get_gpio_in(nvic, i);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -62,7 +62,6 @@ static QEMUMachine collie_machine = {
|
|||||||
.name = "collie",
|
.name = "collie",
|
||||||
.desc = "Collie PDA (SA-1110)",
|
.desc = "Collie PDA (SA-1110)",
|
||||||
.init = collie_init,
|
.init = collie_init,
|
||||||
DEFAULT_MACHINE_OPTIONS,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static void collie_machine_init(void)
|
static void collie_machine_init(void)
|
||||||
|
|||||||
@@ -137,10 +137,8 @@ void exynos4210_write_secondary(ARMCPU *cpu,
|
|||||||
Exynos4210State *exynos4210_init(MemoryRegion *system_mem,
|
Exynos4210State *exynos4210_init(MemoryRegion *system_mem,
|
||||||
unsigned long ram_size)
|
unsigned long ram_size)
|
||||||
{
|
{
|
||||||
qemu_irq cpu_irq[EXYNOS4210_NCPUS];
|
|
||||||
int i, n;
|
int i, n;
|
||||||
Exynos4210State *s = g_new(Exynos4210State, 1);
|
Exynos4210State *s = g_new(Exynos4210State, 1);
|
||||||
qemu_irq *irqp;
|
|
||||||
qemu_irq gate_irq[EXYNOS4210_NCPUS][EXYNOS4210_IRQ_GATE_NINPUTS];
|
qemu_irq gate_irq[EXYNOS4210_NCPUS][EXYNOS4210_IRQ_GATE_NINPUTS];
|
||||||
unsigned long mem_size;
|
unsigned long mem_size;
|
||||||
DeviceState *dev;
|
DeviceState *dev;
|
||||||
@@ -152,15 +150,6 @@ Exynos4210State *exynos4210_init(MemoryRegion *system_mem,
|
|||||||
fprintf(stderr, "Unable to find CPU %d definition\n", n);
|
fprintf(stderr, "Unable to find CPU %d definition\n", n);
|
||||||
exit(1);
|
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 ***/
|
/*** IRQs ***/
|
||||||
@@ -178,8 +167,9 @@ Exynos4210State *exynos4210_init(MemoryRegion *system_mem,
|
|||||||
}
|
}
|
||||||
busdev = SYS_BUS_DEVICE(dev);
|
busdev = SYS_BUS_DEVICE(dev);
|
||||||
|
|
||||||
/* Connect IRQ Gate output to cpu_irq */
|
/* Connect IRQ Gate output to CPU's IRQ line */
|
||||||
sysbus_connect_irq(busdev, 0, cpu_irq[i]);
|
sysbus_connect_irq(busdev, 0,
|
||||||
|
qdev_get_gpio_in(DEVICE(s->cpu[i]), ARM_CPU_IRQ));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Private memory region and Internal GIC */
|
/* Private memory region and Internal GIC */
|
||||||
|
|||||||
@@ -150,14 +150,12 @@ static QEMUMachine exynos4_machines[EXYNOS4_NUM_OF_BOARDS] = {
|
|||||||
.desc = "Samsung NURI board (Exynos4210)",
|
.desc = "Samsung NURI board (Exynos4210)",
|
||||||
.init = nuri_init,
|
.init = nuri_init,
|
||||||
.max_cpus = EXYNOS4210_NCPUS,
|
.max_cpus = EXYNOS4210_NCPUS,
|
||||||
DEFAULT_MACHINE_OPTIONS,
|
|
||||||
},
|
},
|
||||||
[EXYNOS4_BOARD_SMDKC210] = {
|
[EXYNOS4_BOARD_SMDKC210] = {
|
||||||
.name = "smdkc210",
|
.name = "smdkc210",
|
||||||
.desc = "Samsung SMDKC210 board (Exynos4210)",
|
.desc = "Samsung SMDKC210 board (Exynos4210)",
|
||||||
.init = smdkc210_init,
|
.init = smdkc210_init,
|
||||||
.max_cpus = EXYNOS4210_NCPUS,
|
.max_cpus = EXYNOS4210_NCPUS,
|
||||||
DEFAULT_MACHINE_OPTIONS,
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -122,14 +122,12 @@ static QEMUMachine connex_machine = {
|
|||||||
.name = "connex",
|
.name = "connex",
|
||||||
.desc = "Gumstix Connex (PXA255)",
|
.desc = "Gumstix Connex (PXA255)",
|
||||||
.init = connex_init,
|
.init = connex_init,
|
||||||
DEFAULT_MACHINE_OPTIONS,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static QEMUMachine verdex_machine = {
|
static QEMUMachine verdex_machine = {
|
||||||
.name = "verdex",
|
.name = "verdex",
|
||||||
.desc = "Gumstix Verdex (PXA270)",
|
.desc = "Gumstix Verdex (PXA270)",
|
||||||
.init = verdex_init,
|
.init = verdex_init,
|
||||||
DEFAULT_MACHINE_OPTIONS,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static void gumstix_machine_init(void)
|
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;
|
const char *initrd_filename = args->initrd_filename;
|
||||||
DeviceState *dev = NULL;
|
DeviceState *dev = NULL;
|
||||||
SysBusDevice *busdev;
|
SysBusDevice *busdev;
|
||||||
qemu_irq *irqp;
|
|
||||||
qemu_irq pic[128];
|
qemu_irq pic[128];
|
||||||
int n;
|
int n;
|
||||||
qemu_irq cpu_irq[4];
|
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 */
|
/* This will become a QOM property eventually */
|
||||||
cpu->reset_cbar = GIC_BASE_ADDR;
|
cpu->reset_cbar = GIC_BASE_ADDR;
|
||||||
irqp = arm_pic_init_cpu(cpu);
|
cpu_irq[n] = qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_IRQ);
|
||||||
cpu_irq[n] = irqp[ARM_PIC_CPU_IRQ];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sysmem = get_system_memory();
|
sysmem = get_system_memory();
|
||||||
@@ -365,7 +363,6 @@ static QEMUMachine highbank_machine = {
|
|||||||
.init = highbank_init,
|
.init = highbank_init,
|
||||||
.block_default_type = IF_SCSI,
|
.block_default_type = IF_SCSI,
|
||||||
.max_cpus = 4,
|
.max_cpus = 4,
|
||||||
DEFAULT_MACHINE_OPTIONS,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static QEMUMachine midway_machine = {
|
static QEMUMachine midway_machine = {
|
||||||
@@ -374,7 +371,6 @@ static QEMUMachine midway_machine = {
|
|||||||
.init = midway_init,
|
.init = midway_init,
|
||||||
.block_default_type = IF_SCSI,
|
.block_default_type = IF_SCSI,
|
||||||
.max_cpus = 4,
|
.max_cpus = 4,
|
||||||
DEFAULT_MACHINE_OPTIONS,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static void calxeda_machines_init(void)
|
static void calxeda_machines_init(void)
|
||||||
|
|||||||
@@ -465,7 +465,6 @@ static void integratorcp_init(QEMUMachineInitArgs *args)
|
|||||||
MemoryRegion *ram = g_new(MemoryRegion, 1);
|
MemoryRegion *ram = g_new(MemoryRegion, 1);
|
||||||
MemoryRegion *ram_alias = g_new(MemoryRegion, 1);
|
MemoryRegion *ram_alias = g_new(MemoryRegion, 1);
|
||||||
qemu_irq pic[32];
|
qemu_irq pic[32];
|
||||||
qemu_irq *cpu_pic;
|
|
||||||
DeviceState *dev;
|
DeviceState *dev;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
@@ -493,10 +492,10 @@ static void integratorcp_init(QEMUMachineInitArgs *args)
|
|||||||
qdev_init_nofail(dev);
|
qdev_init_nofail(dev);
|
||||||
sysbus_mmio_map((SysBusDevice *)dev, 0, 0x10000000);
|
sysbus_mmio_map((SysBusDevice *)dev, 0, 0x10000000);
|
||||||
|
|
||||||
cpu_pic = arm_pic_init_cpu(cpu);
|
|
||||||
dev = sysbus_create_varargs(TYPE_INTEGRATOR_PIC, 0x14000000,
|
dev = sysbus_create_varargs(TYPE_INTEGRATOR_PIC, 0x14000000,
|
||||||
cpu_pic[ARM_PIC_CPU_IRQ],
|
qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_IRQ),
|
||||||
cpu_pic[ARM_PIC_CPU_FIQ], NULL);
|
qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_FIQ),
|
||||||
|
NULL);
|
||||||
for (i = 0; i < 32; i++) {
|
for (i = 0; i < 32; i++) {
|
||||||
pic[i] = qdev_get_gpio_in(dev, i);
|
pic[i] = qdev_get_gpio_in(dev, i);
|
||||||
}
|
}
|
||||||
@@ -527,7 +526,6 @@ static QEMUMachine integratorcp_machine = {
|
|||||||
.desc = "ARM Integrator/CP (ARM926EJ-S)",
|
.desc = "ARM Integrator/CP (ARM926EJ-S)",
|
||||||
.init = integratorcp_init,
|
.init = integratorcp_init,
|
||||||
.is_default = 1,
|
.is_default = 1,
|
||||||
DEFAULT_MACHINE_OPTIONS,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static void integratorcp_machine_init(void)
|
static void integratorcp_machine_init(void)
|
||||||
|
|||||||
@@ -82,7 +82,6 @@ static void kzm_init(QEMUMachineInitArgs *args)
|
|||||||
MemoryRegion *ram = g_new(MemoryRegion, 1);
|
MemoryRegion *ram = g_new(MemoryRegion, 1);
|
||||||
MemoryRegion *sram = g_new(MemoryRegion, 1);
|
MemoryRegion *sram = g_new(MemoryRegion, 1);
|
||||||
MemoryRegion *ram_alias = g_new(MemoryRegion, 1);
|
MemoryRegion *ram_alias = g_new(MemoryRegion, 1);
|
||||||
qemu_irq *cpu_pic;
|
|
||||||
DeviceState *dev;
|
DeviceState *dev;
|
||||||
DeviceState *ccm;
|
DeviceState *ccm;
|
||||||
|
|
||||||
@@ -108,11 +107,10 @@ static void kzm_init(QEMUMachineInitArgs *args)
|
|||||||
memory_region_init_ram(sram, NULL, "kzm.sram", 0x4000);
|
memory_region_init_ram(sram, NULL, "kzm.sram", 0x4000);
|
||||||
memory_region_add_subregion(address_space_mem, 0x1FFFC000, sram);
|
memory_region_add_subregion(address_space_mem, 0x1FFFC000, sram);
|
||||||
|
|
||||||
cpu_pic = arm_pic_init_cpu(cpu);
|
|
||||||
dev = sysbus_create_varargs("imx_avic", 0x68000000,
|
dev = sysbus_create_varargs("imx_avic", 0x68000000,
|
||||||
cpu_pic[ARM_PIC_CPU_IRQ],
|
qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_IRQ),
|
||||||
cpu_pic[ARM_PIC_CPU_FIQ], NULL);
|
qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_FIQ),
|
||||||
|
NULL);
|
||||||
|
|
||||||
imx_serial_create(0, 0x43f90000, qdev_get_gpio_in(dev, 45));
|
imx_serial_create(0, 0x43f90000, qdev_get_gpio_in(dev, 45));
|
||||||
imx_serial_create(1, 0x43f94000, qdev_get_gpio_in(dev, 32));
|
imx_serial_create(1, 0x43f94000, qdev_get_gpio_in(dev, 32));
|
||||||
@@ -146,7 +144,6 @@ static QEMUMachine kzm_machine = {
|
|||||||
.name = "kzm",
|
.name = "kzm",
|
||||||
.desc = "ARM KZM Emulation Baseboard (ARM1136)",
|
.desc = "ARM KZM Emulation Baseboard (ARM1136)",
|
||||||
.init = kzm_init,
|
.init = kzm_init,
|
||||||
DEFAULT_MACHINE_OPTIONS,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static void kzm_machine_init(void)
|
static void kzm_machine_init(void)
|
||||||
|
|||||||
@@ -179,7 +179,6 @@ static QEMUMachine mainstone2_machine = {
|
|||||||
.name = "mainstone",
|
.name = "mainstone",
|
||||||
.desc = "Mainstone II (PXA27x)",
|
.desc = "Mainstone II (PXA27x)",
|
||||||
.init = mainstone_init,
|
.init = mainstone_init,
|
||||||
DEFAULT_MACHINE_OPTIONS,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static void mainstone_machine_init(void)
|
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 *kernel_cmdline = args->kernel_cmdline;
|
||||||
const char *initrd_filename = args->initrd_filename;
|
const char *initrd_filename = args->initrd_filename;
|
||||||
ARMCPU *cpu;
|
ARMCPU *cpu;
|
||||||
qemu_irq *cpu_pic;
|
|
||||||
qemu_irq pic[32];
|
qemu_irq pic[32];
|
||||||
DeviceState *dev;
|
DeviceState *dev;
|
||||||
DeviceState *i2c_dev;
|
DeviceState *i2c_dev;
|
||||||
@@ -1610,7 +1609,6 @@ static void musicpal_init(QEMUMachineInitArgs *args)
|
|||||||
fprintf(stderr, "Unable to find CPU definition\n");
|
fprintf(stderr, "Unable to find CPU definition\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
cpu_pic = arm_pic_init_cpu(cpu);
|
|
||||||
|
|
||||||
/* For now we use a fixed - the original - RAM size */
|
/* For now we use a fixed - the original - RAM size */
|
||||||
memory_region_init_ram(ram, NULL, "musicpal.ram", MP_RAM_DEFAULT_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);
|
memory_region_add_subregion(address_space_mem, MP_SRAM_BASE, sram);
|
||||||
|
|
||||||
dev = sysbus_create_simple(TYPE_MV88W8618_PIC, MP_PIC_BASE,
|
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++) {
|
for (i = 0; i < 32; i++) {
|
||||||
pic[i] = qdev_get_gpio_in(dev, i);
|
pic[i] = qdev_get_gpio_in(dev, i);
|
||||||
}
|
}
|
||||||
@@ -1731,7 +1729,6 @@ static QEMUMachine musicpal_machine = {
|
|||||||
.name = "musicpal",
|
.name = "musicpal",
|
||||||
.desc = "Marvell 88w8618 / MusicPal (ARM926EJ-S)",
|
.desc = "Marvell 88w8618 / MusicPal (ARM926EJ-S)",
|
||||||
.init = musicpal_init,
|
.init = musicpal_init,
|
||||||
DEFAULT_MACHINE_OPTIONS,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static void musicpal_machine_init(void)
|
static void musicpal_machine_init(void)
|
||||||
|
|||||||
@@ -1340,7 +1340,7 @@ static void n8x0_init(QEMUMachineInitArgs *args,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (option_rom[0].name &&
|
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];
|
uint8_t nolo_tags[0x10000];
|
||||||
/* No, wait, better start at the ROM. */
|
/* No, wait, better start at the ROM. */
|
||||||
s->mpu->cpu->env.regs[15] = OMAP2_Q2_BASE + 0x400000;
|
s->mpu->cpu->env.regs[15] = OMAP2_Q2_BASE + 0x400000;
|
||||||
@@ -1396,14 +1396,14 @@ static QEMUMachine n800_machine = {
|
|||||||
.name = "n800",
|
.name = "n800",
|
||||||
.desc = "Nokia N800 tablet aka. RX-34 (OMAP2420)",
|
.desc = "Nokia N800 tablet aka. RX-34 (OMAP2420)",
|
||||||
.init = n800_init,
|
.init = n800_init,
|
||||||
DEFAULT_MACHINE_OPTIONS,
|
.default_boot_order = "",
|
||||||
};
|
};
|
||||||
|
|
||||||
static QEMUMachine n810_machine = {
|
static QEMUMachine n810_machine = {
|
||||||
.name = "n810",
|
.name = "n810",
|
||||||
.desc = "Nokia N810 tablet aka. RX-44 (OMAP2420)",
|
.desc = "Nokia N810 tablet aka. RX-44 (OMAP2420)",
|
||||||
.init = n810_init,
|
.init = n810_init,
|
||||||
DEFAULT_MACHINE_OPTIONS,
|
.default_boot_order = "",
|
||||||
};
|
};
|
||||||
|
|
||||||
static void nseries_machine_init(void)
|
static void nseries_machine_init(void)
|
||||||
|
|||||||
@@ -3827,7 +3827,6 @@ struct omap_mpu_state_s *omap310_mpu_init(MemoryRegion *system_memory,
|
|||||||
int i;
|
int i;
|
||||||
struct omap_mpu_state_s *s = (struct omap_mpu_state_s *)
|
struct omap_mpu_state_s *s = (struct omap_mpu_state_s *)
|
||||||
g_malloc0(sizeof(struct omap_mpu_state_s));
|
g_malloc0(sizeof(struct omap_mpu_state_s));
|
||||||
qemu_irq *cpu_irq;
|
|
||||||
qemu_irq dma_irqs[6];
|
qemu_irq dma_irqs[6];
|
||||||
DriveInfo *dinfo;
|
DriveInfo *dinfo;
|
||||||
SysBusDevice *busdev;
|
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);
|
omap_clkm_init(system_memory, 0xfffece00, 0xe1008000, s);
|
||||||
|
|
||||||
cpu_irq = arm_pic_init_cpu(s->cpu);
|
|
||||||
s->ih[0] = qdev_create(NULL, "omap-intc");
|
s->ih[0] = qdev_create(NULL, "omap-intc");
|
||||||
qdev_prop_set_uint32(s->ih[0], "size", 0x100);
|
qdev_prop_set_uint32(s->ih[0], "size", 0x100);
|
||||||
qdev_prop_set_ptr(s->ih[0], "clk", omap_findclk(s, "arminth_ck"));
|
qdev_prop_set_ptr(s->ih[0], "clk", omap_findclk(s, "arminth_ck"));
|
||||||
qdev_init_nofail(s->ih[0]);
|
qdev_init_nofail(s->ih[0]);
|
||||||
busdev = SYS_BUS_DEVICE(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, 0,
|
||||||
sysbus_connect_irq(busdev, 1, cpu_irq[ARM_PIC_CPU_FIQ]);
|
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);
|
sysbus_mmio_map(busdev, 0, 0xfffecb00);
|
||||||
s->ih[1] = qdev_create(NULL, "omap-intc");
|
s->ih[1] = qdev_create(NULL, "omap-intc");
|
||||||
qdev_prop_set_uint32(s->ih[1], "size", 0x800);
|
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 *)
|
struct omap_mpu_state_s *s = (struct omap_mpu_state_s *)
|
||||||
g_malloc0(sizeof(struct omap_mpu_state_s));
|
g_malloc0(sizeof(struct omap_mpu_state_s));
|
||||||
qemu_irq *cpu_irq;
|
|
||||||
qemu_irq dma_irqs[4];
|
qemu_irq dma_irqs[4];
|
||||||
DriveInfo *dinfo;
|
DriveInfo *dinfo;
|
||||||
int i;
|
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);
|
s->l4 = omap_l4_init(sysmem, OMAP2_L4_BASE, 54);
|
||||||
|
|
||||||
/* Actually mapped at any 2K boundary in the ARM11 private-peripheral if */
|
/* 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");
|
s->ih[0] = qdev_create(NULL, "omap2-intc");
|
||||||
qdev_prop_set_uint8(s->ih[0], "revision", 0x21);
|
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], "fclk", omap_findclk(s, "mpu_intc_fclk"));
|
||||||
qdev_prop_set_ptr(s->ih[0], "iclk", omap_findclk(s, "mpu_intc_iclk"));
|
qdev_prop_set_ptr(s->ih[0], "iclk", omap_findclk(s, "mpu_intc_iclk"));
|
||||||
qdev_init_nofail(s->ih[0]);
|
qdev_init_nofail(s->ih[0]);
|
||||||
busdev = SYS_BUS_DEVICE(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, 0,
|
||||||
sysbus_connect_irq(busdev, 1, cpu_irq[ARM_PIC_CPU_FIQ]);
|
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);
|
sysbus_mmio_map(busdev, 0, 0x480fe000);
|
||||||
s->prcm = omap_prcm_init(omap_l4tao(s->l4, 3),
|
s->prcm = omap_prcm_init(omap_l4tao(s->l4, 3),
|
||||||
qdev_get_gpio_in(s->ih[0],
|
qdev_get_gpio_in(s->ih[0],
|
||||||
|
|||||||
@@ -219,14 +219,12 @@ static QEMUMachine sx1_machine_v2 = {
|
|||||||
.name = "sx1",
|
.name = "sx1",
|
||||||
.desc = "Siemens SX1 (OMAP310) V2",
|
.desc = "Siemens SX1 (OMAP310) V2",
|
||||||
.init = sx1_init_v2,
|
.init = sx1_init_v2,
|
||||||
DEFAULT_MACHINE_OPTIONS,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static QEMUMachine sx1_machine_v1 = {
|
static QEMUMachine sx1_machine_v1 = {
|
||||||
.name = "sx1-v1",
|
.name = "sx1-v1",
|
||||||
.desc = "Siemens SX1 (OMAP310) V1",
|
.desc = "Siemens SX1 (OMAP310) V1",
|
||||||
.init = sx1_init_v1,
|
.init = sx1_init_v1,
|
||||||
DEFAULT_MACHINE_OPTIONS,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static void sx1_machine_init(void)
|
static void sx1_machine_init(void)
|
||||||
|
|||||||
@@ -273,7 +273,6 @@ static QEMUMachine palmte_machine = {
|
|||||||
.name = "cheetah",
|
.name = "cheetah",
|
||||||
.desc = "Palm Tungsten|E aka. Cheetah PDA (OMAP310)",
|
.desc = "Palm Tungsten|E aka. Cheetah PDA (OMAP310)",
|
||||||
.init = palmte_init,
|
.init = palmte_init,
|
||||||
DEFAULT_MACHINE_OPTIONS,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static void palmte_machine_init(void)
|
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;
|
DeviceState *dev;
|
||||||
SysBusDevice *i2c_dev;
|
SysBusDevice *i2c_dev;
|
||||||
PXA2xxI2CState *s;
|
PXA2xxI2CState *s;
|
||||||
|
i2c_bus *i2cbus;
|
||||||
|
|
||||||
dev = qdev_create(NULL, TYPE_PXA2XX_I2C);
|
dev = qdev_create(NULL, TYPE_PXA2XX_I2C);
|
||||||
qdev_prop_set_uint32(dev, "size", region_size + 1);
|
qdev_prop_set_uint32(dev, "size", region_size + 1);
|
||||||
@@ -1491,7 +1492,8 @@ PXA2xxI2CState *pxa2xx_i2c_init(hwaddr base,
|
|||||||
|
|
||||||
s = PXA2XX_I2C(i2c_dev);
|
s = PXA2XX_I2C(i2c_dev);
|
||||||
/* FIXME: Should the slave device really be on a separate bus? */
|
/* 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 = FROM_I2C_SLAVE(PXA2xxI2CSlaveState, I2C_SLAVE(dev));
|
||||||
s->slave->host = s;
|
s->slave->host = s;
|
||||||
|
|
||||||
|
|||||||
@@ -56,7 +56,6 @@ static void realview_init(QEMUMachineInitArgs *args,
|
|||||||
MemoryRegion *ram_hack = g_new(MemoryRegion, 1);
|
MemoryRegion *ram_hack = g_new(MemoryRegion, 1);
|
||||||
DeviceState *dev, *sysctl, *gpio2, *pl041;
|
DeviceState *dev, *sysctl, *gpio2, *pl041;
|
||||||
SysBusDevice *busdev;
|
SysBusDevice *busdev;
|
||||||
qemu_irq *irqp;
|
|
||||||
qemu_irq pic[64];
|
qemu_irq pic[64];
|
||||||
qemu_irq mmc_irq[2];
|
qemu_irq mmc_irq[2];
|
||||||
PCIBus *pci_bus = NULL;
|
PCIBus *pci_bus = NULL;
|
||||||
@@ -92,8 +91,7 @@ static void realview_init(QEMUMachineInitArgs *args,
|
|||||||
fprintf(stderr, "Unable to find CPU definition\n");
|
fprintf(stderr, "Unable to find CPU definition\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
irqp = arm_pic_init_cpu(cpu);
|
cpu_irq[n] = qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_IRQ);
|
||||||
cpu_irq[n] = irqp[ARM_PIC_CPU_IRQ];
|
|
||||||
}
|
}
|
||||||
env = &cpu->env;
|
env = &cpu->env;
|
||||||
if (arm_feature(env, ARM_FEATURE_V7)) {
|
if (arm_feature(env, ARM_FEATURE_V7)) {
|
||||||
@@ -371,7 +369,6 @@ static QEMUMachine realview_eb_machine = {
|
|||||||
.desc = "ARM RealView Emulation Baseboard (ARM926EJ-S)",
|
.desc = "ARM RealView Emulation Baseboard (ARM926EJ-S)",
|
||||||
.init = realview_eb_init,
|
.init = realview_eb_init,
|
||||||
.block_default_type = IF_SCSI,
|
.block_default_type = IF_SCSI,
|
||||||
DEFAULT_MACHINE_OPTIONS,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static QEMUMachine realview_eb_mpcore_machine = {
|
static QEMUMachine realview_eb_mpcore_machine = {
|
||||||
@@ -380,14 +377,12 @@ static QEMUMachine realview_eb_mpcore_machine = {
|
|||||||
.init = realview_eb_mpcore_init,
|
.init = realview_eb_mpcore_init,
|
||||||
.block_default_type = IF_SCSI,
|
.block_default_type = IF_SCSI,
|
||||||
.max_cpus = 4,
|
.max_cpus = 4,
|
||||||
DEFAULT_MACHINE_OPTIONS,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static QEMUMachine realview_pb_a8_machine = {
|
static QEMUMachine realview_pb_a8_machine = {
|
||||||
.name = "realview-pb-a8",
|
.name = "realview-pb-a8",
|
||||||
.desc = "ARM RealView Platform Baseboard for Cortex-A8",
|
.desc = "ARM RealView Platform Baseboard for Cortex-A8",
|
||||||
.init = realview_pb_a8_init,
|
.init = realview_pb_a8_init,
|
||||||
DEFAULT_MACHINE_OPTIONS,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static QEMUMachine realview_pbx_a9_machine = {
|
static QEMUMachine realview_pbx_a9_machine = {
|
||||||
@@ -396,7 +391,6 @@ static QEMUMachine realview_pbx_a9_machine = {
|
|||||||
.init = realview_pbx_a9_init,
|
.init = realview_pbx_a9_init,
|
||||||
.block_default_type = IF_SCSI,
|
.block_default_type = IF_SCSI,
|
||||||
.max_cpus = 4,
|
.max_cpus = 4,
|
||||||
DEFAULT_MACHINE_OPTIONS,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static void realview_machine_init(void)
|
static void realview_machine_init(void)
|
||||||
|
|||||||
@@ -966,28 +966,24 @@ static QEMUMachine akitapda_machine = {
|
|||||||
.name = "akita",
|
.name = "akita",
|
||||||
.desc = "Akita PDA (PXA270)",
|
.desc = "Akita PDA (PXA270)",
|
||||||
.init = akita_init,
|
.init = akita_init,
|
||||||
DEFAULT_MACHINE_OPTIONS,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static QEMUMachine spitzpda_machine = {
|
static QEMUMachine spitzpda_machine = {
|
||||||
.name = "spitz",
|
.name = "spitz",
|
||||||
.desc = "Spitz PDA (PXA270)",
|
.desc = "Spitz PDA (PXA270)",
|
||||||
.init = spitz_init,
|
.init = spitz_init,
|
||||||
DEFAULT_MACHINE_OPTIONS,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static QEMUMachine borzoipda_machine = {
|
static QEMUMachine borzoipda_machine = {
|
||||||
.name = "borzoi",
|
.name = "borzoi",
|
||||||
.desc = "Borzoi PDA (PXA270)",
|
.desc = "Borzoi PDA (PXA270)",
|
||||||
.init = borzoi_init,
|
.init = borzoi_init,
|
||||||
DEFAULT_MACHINE_OPTIONS,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static QEMUMachine terrierpda_machine = {
|
static QEMUMachine terrierpda_machine = {
|
||||||
.name = "terrier",
|
.name = "terrier",
|
||||||
.desc = "Terrier PDA (PXA270)",
|
.desc = "Terrier PDA (PXA270)",
|
||||||
.init = terrier_init,
|
.init = terrier_init,
|
||||||
DEFAULT_MACHINE_OPTIONS,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static void spitz_machine_init(void)
|
static void spitz_machine_init(void)
|
||||||
|
|||||||
@@ -1348,14 +1348,12 @@ static QEMUMachine lm3s811evb_machine = {
|
|||||||
.name = "lm3s811evb",
|
.name = "lm3s811evb",
|
||||||
.desc = "Stellaris LM3S811EVB",
|
.desc = "Stellaris LM3S811EVB",
|
||||||
.init = lm3s811evb_init,
|
.init = lm3s811evb_init,
|
||||||
DEFAULT_MACHINE_OPTIONS,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static QEMUMachine lm3s6965evb_machine = {
|
static QEMUMachine lm3s6965evb_machine = {
|
||||||
.name = "lm3s6965evb",
|
.name = "lm3s6965evb",
|
||||||
.desc = "Stellaris LM3S6965EVB",
|
.desc = "Stellaris LM3S6965EVB",
|
||||||
.init = lm3s6965evb_init,
|
.init = lm3s6965evb_init,
|
||||||
DEFAULT_MACHINE_OPTIONS,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static void stellaris_machine_init(void)
|
static void stellaris_machine_init(void)
|
||||||
|
|||||||
@@ -1588,7 +1588,6 @@ StrongARMState *sa1110_init(MemoryRegion *sysmem,
|
|||||||
unsigned int sdram_size, const char *rev)
|
unsigned int sdram_size, const char *rev)
|
||||||
{
|
{
|
||||||
StrongARMState *s;
|
StrongARMState *s;
|
||||||
qemu_irq *pic;
|
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
s = g_malloc0(sizeof(StrongARMState));
|
s = g_malloc0(sizeof(StrongARMState));
|
||||||
@@ -1613,9 +1612,10 @@ StrongARMState *sa1110_init(MemoryRegion *sysmem,
|
|||||||
vmstate_register_ram_global(&s->sdram);
|
vmstate_register_ram_global(&s->sdram);
|
||||||
memory_region_add_subregion(sysmem, SA_SDCS0, &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,
|
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,
|
sysbus_create_varargs("pxa25x-timer", 0x90000000,
|
||||||
qdev_get_gpio_in(s->pic, SA_PIC_OSTC0),
|
qdev_get_gpio_in(s->pic, SA_PIC_OSTC0),
|
||||||
|
|||||||
@@ -251,7 +251,6 @@ static QEMUMachine tosapda_machine = {
|
|||||||
.name = "tosa",
|
.name = "tosa",
|
||||||
.desc = "Tosa PDA (PXA255)",
|
.desc = "Tosa PDA (PXA255)",
|
||||||
.init = tosa_init,
|
.init = tosa_init,
|
||||||
DEFAULT_MACHINE_OPTIONS,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static void tosapda_machine_init(void)
|
static void tosapda_machine_init(void)
|
||||||
|
|||||||
@@ -178,7 +178,6 @@ static void versatile_init(QEMUMachineInitArgs *args, int board_id)
|
|||||||
ARMCPU *cpu;
|
ARMCPU *cpu;
|
||||||
MemoryRegion *sysmem = get_system_memory();
|
MemoryRegion *sysmem = get_system_memory();
|
||||||
MemoryRegion *ram = g_new(MemoryRegion, 1);
|
MemoryRegion *ram = g_new(MemoryRegion, 1);
|
||||||
qemu_irq *cpu_pic;
|
|
||||||
qemu_irq pic[32];
|
qemu_irq pic[32];
|
||||||
qemu_irq sic[32];
|
qemu_irq sic[32];
|
||||||
DeviceState *dev, *sysctl;
|
DeviceState *dev, *sysctl;
|
||||||
@@ -211,10 +210,10 @@ static void versatile_init(QEMUMachineInitArgs *args, int board_id)
|
|||||||
qdev_init_nofail(sysctl);
|
qdev_init_nofail(sysctl);
|
||||||
sysbus_mmio_map(SYS_BUS_DEVICE(sysctl), 0, 0x10000000);
|
sysbus_mmio_map(SYS_BUS_DEVICE(sysctl), 0, 0x10000000);
|
||||||
|
|
||||||
cpu_pic = arm_pic_init_cpu(cpu);
|
|
||||||
dev = sysbus_create_varargs("pl190", 0x10140000,
|
dev = sysbus_create_varargs("pl190", 0x10140000,
|
||||||
cpu_pic[ARM_PIC_CPU_IRQ],
|
qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_IRQ),
|
||||||
cpu_pic[ARM_PIC_CPU_FIQ], NULL);
|
qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_FIQ),
|
||||||
|
NULL);
|
||||||
for (n = 0; n < 32; n++) {
|
for (n = 0; n < 32; n++) {
|
||||||
pic[n] = qdev_get_gpio_in(dev, n);
|
pic[n] = qdev_get_gpio_in(dev, n);
|
||||||
}
|
}
|
||||||
@@ -368,7 +367,6 @@ static QEMUMachine versatilepb_machine = {
|
|||||||
.desc = "ARM Versatile/PB (ARM926EJ-S)",
|
.desc = "ARM Versatile/PB (ARM926EJ-S)",
|
||||||
.init = vpb_init,
|
.init = vpb_init,
|
||||||
.block_default_type = IF_SCSI,
|
.block_default_type = IF_SCSI,
|
||||||
DEFAULT_MACHINE_OPTIONS,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static QEMUMachine versatileab_machine = {
|
static QEMUMachine versatileab_machine = {
|
||||||
@@ -376,7 +374,6 @@ static QEMUMachine versatileab_machine = {
|
|||||||
.desc = "ARM Versatile/AB (ARM926EJ-S)",
|
.desc = "ARM Versatile/AB (ARM926EJ-S)",
|
||||||
.init = vab_init,
|
.init = vab_init,
|
||||||
.block_default_type = IF_SCSI,
|
.block_default_type = IF_SCSI,
|
||||||
DEFAULT_MACHINE_OPTIONS,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static void versatile_machine_init(void)
|
static void versatile_machine_init(void)
|
||||||
|
|||||||
@@ -183,7 +183,6 @@ static void a9_daughterboard_init(const VEDBoardInfo *daughterboard,
|
|||||||
MemoryRegion *lowram = g_new(MemoryRegion, 1);
|
MemoryRegion *lowram = g_new(MemoryRegion, 1);
|
||||||
DeviceState *dev;
|
DeviceState *dev;
|
||||||
SysBusDevice *busdev;
|
SysBusDevice *busdev;
|
||||||
qemu_irq *irqp;
|
|
||||||
int n;
|
int n;
|
||||||
qemu_irq cpu_irq[4];
|
qemu_irq cpu_irq[4];
|
||||||
ram_addr_t low_ram_size;
|
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");
|
fprintf(stderr, "Unable to find CPU definition\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
irqp = arm_pic_init_cpu(cpu);
|
cpu_irq[n] = qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_IRQ);
|
||||||
cpu_irq[n] = irqp[ARM_PIC_CPU_IRQ];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ram_size > 0x40000000) {
|
if (ram_size > 0x40000000) {
|
||||||
@@ -312,15 +310,13 @@ static void a15_daughterboard_init(const VEDBoardInfo *daughterboard,
|
|||||||
|
|
||||||
for (n = 0; n < smp_cpus; n++) {
|
for (n = 0; n < smp_cpus; n++) {
|
||||||
ARMCPU *cpu;
|
ARMCPU *cpu;
|
||||||
qemu_irq *irqp;
|
|
||||||
|
|
||||||
cpu = cpu_arm_init(cpu_model);
|
cpu = cpu_arm_init(cpu_model);
|
||||||
if (!cpu) {
|
if (!cpu) {
|
||||||
fprintf(stderr, "Unable to find CPU definition\n");
|
fprintf(stderr, "Unable to find CPU definition\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
irqp = arm_pic_init_cpu(cpu);
|
cpu_irq[n] = qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_IRQ);
|
||||||
cpu_irq[n] = irqp[ARM_PIC_CPU_IRQ];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
@@ -651,7 +647,6 @@ static QEMUMachine vexpress_a9_machine = {
|
|||||||
.init = vexpress_a9_init,
|
.init = vexpress_a9_init,
|
||||||
.block_default_type = IF_SCSI,
|
.block_default_type = IF_SCSI,
|
||||||
.max_cpus = 4,
|
.max_cpus = 4,
|
||||||
DEFAULT_MACHINE_OPTIONS,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static QEMUMachine vexpress_a15_machine = {
|
static QEMUMachine vexpress_a15_machine = {
|
||||||
@@ -660,7 +655,6 @@ static QEMUMachine vexpress_a15_machine = {
|
|||||||
.init = vexpress_a15_init,
|
.init = vexpress_a15_init,
|
||||||
.block_default_type = IF_SCSI,
|
.block_default_type = IF_SCSI,
|
||||||
.max_cpus = 4,
|
.max_cpus = 4,
|
||||||
DEFAULT_MACHINE_OPTIONS,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static void vexpress_machine_init(void)
|
static void vexpress_machine_init(void)
|
||||||
|
|||||||
@@ -108,11 +108,9 @@ static void zynq_init(QEMUMachineInitArgs *args)
|
|||||||
MemoryRegion *ocm_ram = g_new(MemoryRegion, 1);
|
MemoryRegion *ocm_ram = g_new(MemoryRegion, 1);
|
||||||
DeviceState *dev;
|
DeviceState *dev;
|
||||||
SysBusDevice *busdev;
|
SysBusDevice *busdev;
|
||||||
qemu_irq *irqp;
|
|
||||||
qemu_irq pic[64];
|
qemu_irq pic[64];
|
||||||
NICInfo *nd;
|
NICInfo *nd;
|
||||||
int n;
|
int n;
|
||||||
qemu_irq cpu_irq;
|
|
||||||
|
|
||||||
if (!cpu_model) {
|
if (!cpu_model) {
|
||||||
cpu_model = "cortex-a9";
|
cpu_model = "cortex-a9";
|
||||||
@@ -123,8 +121,6 @@ static void zynq_init(QEMUMachineInitArgs *args)
|
|||||||
fprintf(stderr, "Unable to find CPU definition\n");
|
fprintf(stderr, "Unable to find CPU definition\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
irqp = arm_pic_init_cpu(cpu);
|
|
||||||
cpu_irq = irqp[ARM_PIC_CPU_IRQ];
|
|
||||||
|
|
||||||
/* max 2GB ram */
|
/* max 2GB ram */
|
||||||
if (ram_size > 0x80000000) {
|
if (ram_size > 0x80000000) {
|
||||||
@@ -159,7 +155,8 @@ static void zynq_init(QEMUMachineInitArgs *args)
|
|||||||
qdev_init_nofail(dev);
|
qdev_init_nofail(dev);
|
||||||
busdev = SYS_BUS_DEVICE(dev);
|
busdev = SYS_BUS_DEVICE(dev);
|
||||||
sysbus_mmio_map(busdev, 0, 0xF8F00000);
|
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++) {
|
for (n = 0; n < 64; n++) {
|
||||||
pic[n] = qdev_get_gpio_in(dev, n);
|
pic[n] = qdev_get_gpio_in(dev, n);
|
||||||
@@ -236,7 +233,6 @@ static QEMUMachine zynq_machine = {
|
|||||||
.block_default_type = IF_SCSI,
|
.block_default_type = IF_SCSI,
|
||||||
.max_cpus = 1,
|
.max_cpus = 1,
|
||||||
.no_sdcard = 1,
|
.no_sdcard = 1,
|
||||||
DEFAULT_MACHINE_OPTIONS,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static void zynq_machine_init(void)
|
static void zynq_machine_init(void)
|
||||||
|
|||||||
@@ -373,7 +373,6 @@ static QEMUMachine z2_machine = {
|
|||||||
.name = "z2",
|
.name = "z2",
|
||||||
.desc = "Zipit Z2 (PXA27x)",
|
.desc = "Zipit Z2 (PXA27x)",
|
||||||
.init = z2_init,
|
.init = z2_init,
|
||||||
DEFAULT_MACHINE_OPTIONS,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static void z2_machine_init(void)
|
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_XEN_BACKEND) += xen_disk.o
|
||||||
common-obj-$(CONFIG_ECC) += ecc.o
|
common-obj-$(CONFIG_ECC) += ecc.o
|
||||||
common-obj-$(CONFIG_ONENAND) += onenand.o
|
common-obj-$(CONFIG_ONENAND) += onenand.o
|
||||||
common-obj-$(CONFIG_PC_SYSFW) += pc_sysfw.o
|
|
||||||
common-obj-$(CONFIG_NVME_PCI) += nvme.o
|
common-obj-$(CONFIG_NVME_PCI) += nvme.o
|
||||||
|
|
||||||
obj-$(CONFIG_SH4) += tc58128.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)
|
static void handle_notify(EventNotifier *e)
|
||||||
{
|
{
|
||||||
VirtIOBlockDataPlane *s = container_of(e, VirtIOBlockDataPlane,
|
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)
|
static void handle_io(EventNotifier *e)
|
||||||
{
|
{
|
||||||
VirtIOBlockDataPlane *s = container_of(e, VirtIOBlockDataPlane,
|
VirtIOBlockDataPlane *s = container_of(e, VirtIOBlockDataPlane,
|
||||||
@@ -376,9 +363,9 @@ static void *data_plane_thread(void *opaque)
|
|||||||
{
|
{
|
||||||
VirtIOBlockDataPlane *s = opaque;
|
VirtIOBlockDataPlane *s = opaque;
|
||||||
|
|
||||||
do {
|
while (!s->stopping || s->num_reqs > 0) {
|
||||||
aio_poll(s->ctx, true);
|
aio_poll(s->ctx, true);
|
||||||
} while (!s->stopping || s->num_reqs > 0);
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -485,7 +472,7 @@ void virtio_blk_data_plane_start(VirtIOBlockDataPlane *s)
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
s->host_notifier = *virtio_queue_get_host_notifier(vq);
|
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 */
|
/* Set up ioqueue */
|
||||||
ioq_init(&s->ioqueue, s->fd, REQ_MAX);
|
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);
|
ioq_put_iocb(&s->ioqueue, &s->requests[i].iocb);
|
||||||
}
|
}
|
||||||
s->io_notifier = *ioq_get_notifier(&s->ioqueue);
|
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;
|
s->started = true;
|
||||||
trace_virtio_blk_data_plane_start(s);
|
trace_virtio_blk_data_plane_start(s);
|
||||||
@@ -525,10 +512,10 @@ void virtio_blk_data_plane_stop(VirtIOBlockDataPlane *s)
|
|||||||
qemu_thread_join(&s->thread);
|
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);
|
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);
|
k->set_host_notifier(qbus->parent, 0, false);
|
||||||
|
|
||||||
aio_context_unref(s->ctx);
|
aio_context_unref(s->ctx);
|
||||||
|
|||||||
@@ -184,8 +184,6 @@ static int read_event_data(SCLPEvent *event, EventBufferHeader *evt_buf_hdr,
|
|||||||
static ssize_t write_console_data(SCLPEvent *event, const uint8_t *buf,
|
static ssize_t write_console_data(SCLPEvent *event, const uint8_t *buf,
|
||||||
size_t len)
|
size_t len)
|
||||||
{
|
{
|
||||||
ssize_t ret = 0;
|
|
||||||
const uint8_t *iov_offset;
|
|
||||||
SCLPConsole *scon = DO_UPCAST(SCLPConsole, event, event);
|
SCLPConsole *scon = DO_UPCAST(SCLPConsole, event, event);
|
||||||
|
|
||||||
if (!scon->chr) {
|
if (!scon->chr) {
|
||||||
@@ -193,21 +191,7 @@ static ssize_t write_console_data(SCLPEvent *event, const uint8_t *buf,
|
|||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
iov_offset = buf;
|
return qemu_chr_fe_write_all(scon->chr, buf, len);
|
||||||
while (len > 0) {
|
|
||||||
ret = qemu_chr_fe_write(scon->chr, buf, len);
|
|
||||||
if (ret == 0) {
|
|
||||||
/* a pty doesn't seem to be connected - no error */
|
|
||||||
len = 0;
|
|
||||||
} else if (ret == -EAGAIN || (ret > 0 && ret < len)) {
|
|
||||||
len -= ret;
|
|
||||||
iov_offset += ret;
|
|
||||||
} else {
|
|
||||||
len = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int write_event_data(SCLPEvent *event, EventBufferHeader *evt_buf_hdr)
|
static int write_event_data(SCLPEvent *event, EventBufferHeader *evt_buf_hdr)
|
||||||
|
|||||||
@@ -185,6 +185,7 @@ static void virtserialport_class_init(ObjectClass *klass, void *data)
|
|||||||
VirtIOSerialPortClass *k = VIRTIO_SERIAL_PORT_CLASS(klass);
|
VirtIOSerialPortClass *k = VIRTIO_SERIAL_PORT_CLASS(klass);
|
||||||
|
|
||||||
k->init = virtconsole_initfn;
|
k->init = virtconsole_initfn;
|
||||||
|
k->exit = virtconsole_exitfn;
|
||||||
k->have_data = flush_buf;
|
k->have_data = flush_buf;
|
||||||
k->set_guest_connected = set_guest_connected;
|
k->set_guest_connected = set_guest_connected;
|
||||||
dc->props = virtserialport_properties;
|
dc->props = virtserialport_properties;
|
||||||
|
|||||||
@@ -54,6 +54,8 @@
|
|||||||
|
|
||||||
#include <zlib.h>
|
#include <zlib.h>
|
||||||
|
|
||||||
|
bool rom_file_in_ram = true;
|
||||||
|
|
||||||
static int roms_loaded;
|
static int roms_loaded;
|
||||||
|
|
||||||
/* return the size or -1 if error */
|
/* return the size or -1 if error */
|
||||||
@@ -576,6 +578,7 @@ struct Rom {
|
|||||||
size_t datasize;
|
size_t datasize;
|
||||||
|
|
||||||
uint8_t *data;
|
uint8_t *data;
|
||||||
|
MemoryRegion *mr;
|
||||||
int isrom;
|
int isrom;
|
||||||
char *fw_dir;
|
char *fw_dir;
|
||||||
char *fw_file;
|
char *fw_file;
|
||||||
@@ -605,6 +608,21 @@ static void rom_insert(Rom *rom)
|
|||||||
QTAILQ_INSERT_TAIL(&roms, rom, next);
|
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,
|
int rom_add_file(const char *file, const char *fw_dir,
|
||||||
hwaddr addr, int32_t bootindex)
|
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) {
|
if (rom->fw_file && fw_cfg) {
|
||||||
const char *basename;
|
const char *basename;
|
||||||
char fw_file_name[56];
|
char fw_file_name[56];
|
||||||
|
void *data;
|
||||||
|
|
||||||
basename = strrchr(rom->fw_file, '/');
|
basename = strrchr(rom->fw_file, '/');
|
||||||
if (basename) {
|
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,
|
snprintf(fw_file_name, sizeof(fw_file_name), "%s/%s", rom->fw_dir,
|
||||||
basename);
|
basename);
|
||||||
fw_cfg_add_file(fw_cfg, fw_file_name, rom->data, rom->romsize);
|
|
||||||
snprintf(devpath, sizeof(devpath), "/rom@%s", fw_file_name);
|
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 {
|
} else {
|
||||||
snprintf(devpath, sizeof(devpath), "/rom@" TARGET_FMT_plx, addr);
|
snprintf(devpath, sizeof(devpath), "/rom@" TARGET_FMT_plx, addr);
|
||||||
}
|
}
|
||||||
@@ -731,7 +757,12 @@ static void rom_reset(void *unused)
|
|||||||
if (rom->data == NULL) {
|
if (rom->data == NULL) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
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);
|
cpu_physical_memory_write_rom(rom->addr, rom->data, rom->datasize);
|
||||||
|
}
|
||||||
if (rom->isrom) {
|
if (rom->isrom) {
|
||||||
/* rom needs to be written only once */
|
/* rom needs to be written only once */
|
||||||
g_free(rom->data);
|
g_free(rom->data);
|
||||||
@@ -781,6 +812,9 @@ static Rom *find_rom(hwaddr addr)
|
|||||||
if (rom->fw_file) {
|
if (rom->fw_file) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (rom->mr) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (rom->addr > addr) {
|
if (rom->addr > addr) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -808,15 +842,15 @@ int rom_copy(uint8_t *dest, hwaddr addr, size_t size)
|
|||||||
if (rom->fw_file) {
|
if (rom->fw_file) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (rom->mr) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (rom->addr + rom->romsize < addr) {
|
if (rom->addr + rom->romsize < addr) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (rom->addr > end) {
|
if (rom->addr > end) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (!rom->data) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
d = dest + (rom->addr - addr);
|
d = dest + (rom->addr - addr);
|
||||||
s = rom->data;
|
s = rom->data;
|
||||||
@@ -826,7 +860,9 @@ int rom_copy(uint8_t *dest, hwaddr addr, size_t size)
|
|||||||
l = dest - d;
|
l = dest - d;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (l > 0) {
|
||||||
memcpy(d, s, l);
|
memcpy(d, s, l);
|
||||||
|
}
|
||||||
|
|
||||||
if (rom->romsize > rom->datasize) {
|
if (rom->romsize > rom->datasize) {
|
||||||
/* If datasize is less than romsize, it means that we didn't
|
/* 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;
|
Rom *rom;
|
||||||
|
|
||||||
QTAILQ_FOREACH(rom, &roms, next) {
|
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
|
monitor_printf(mon, "addr=" TARGET_FMT_plx
|
||||||
" size=0x%06zx mem=%s name=\"%s\"\n",
|
" size=0x%06zx mem=%s name=\"%s\"\n",
|
||||||
rom->addr, rom->romsize,
|
rom->addr, rom->romsize,
|
||||||
|
|||||||
@@ -24,7 +24,6 @@ static QEMUMachine machine_none = {
|
|||||||
.desc = "empty machine",
|
.desc = "empty machine",
|
||||||
.init = machine_none_init,
|
.init = machine_none_init,
|
||||||
.max_cpus = 0,
|
.max_cpus = 0,
|
||||||
DEFAULT_MACHINE_OPTIONS,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static void register_machines(void)
|
static void register_machines(void)
|
||||||
|
|||||||
@@ -1172,15 +1172,21 @@ static int parse_size(DeviceState *dev, Property *prop, const char *str)
|
|||||||
|
|
||||||
static int print_size(DeviceState *dev, Property *prop, char *dest, size_t len)
|
static int print_size(DeviceState *dev, Property *prop, char *dest, size_t len)
|
||||||
{
|
{
|
||||||
uint64_t *ptr = qdev_get_prop_ptr(dev, prop);
|
static const char suffixes[] = { 'B', 'K', 'M', 'G', 'T' };
|
||||||
char suffixes[] = {'T', 'G', 'M', 'K', 'B'};
|
uint64_t div, val = *(uint64_t *)qdev_get_prop_ptr(dev, prop);
|
||||||
int i = 0;
|
int i;
|
||||||
uint64_t div;
|
|
||||||
|
|
||||||
for (div = (long int)1 << 40; !(*ptr / div) ; div >>= 10) {
|
/* Compute floor(log2(val)). */
|
||||||
i++;
|
i = 64 - clz64(val);
|
||||||
|
|
||||||
|
/* Find the power of 1024 that we'll display as the units. */
|
||||||
|
i /= 10;
|
||||||
|
if (i >= ARRAY_SIZE(suffixes)) {
|
||||||
|
i = ARRAY_SIZE(suffixes) - 1;
|
||||||
}
|
}
|
||||||
return snprintf(dest, len, "%0.03f%c", (double)*ptr/div, suffixes[i]);
|
div = 1ULL << (i * 10);
|
||||||
|
|
||||||
|
return snprintf(dest, len, "%0.03f%c", (double)val/div, suffixes[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
PropertyInfo qdev_prop_size = {
|
PropertyInfo qdev_prop_size = {
|
||||||
|
|||||||
@@ -752,7 +752,6 @@ static void device_initfn(Object *obj)
|
|||||||
}
|
}
|
||||||
class = object_class_get_parent(class);
|
class = object_class_get_parent(class);
|
||||||
} while (class != object_class_by_name(TYPE_DEVICE));
|
} while (class != object_class_by_name(TYPE_DEVICE));
|
||||||
qdev_prop_set_globals(dev, &err);
|
|
||||||
if (err != NULL) {
|
if (err != NULL) {
|
||||||
qerror_report_err(err);
|
qerror_report_err(err);
|
||||||
error_free(err);
|
error_free(err);
|
||||||
@@ -764,6 +763,15 @@ static void device_initfn(Object *obj)
|
|||||||
assert_no_error(err);
|
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. */
|
/* Unlink device from bus and free the structure. */
|
||||||
static void device_finalize(Object *obj)
|
static void device_finalize(Object *obj)
|
||||||
{
|
{
|
||||||
@@ -853,6 +861,7 @@ static const TypeInfo device_type_info = {
|
|||||||
.parent = TYPE_OBJECT,
|
.parent = TYPE_OBJECT,
|
||||||
.instance_size = sizeof(DeviceState),
|
.instance_size = sizeof(DeviceState),
|
||||||
.instance_init = device_initfn,
|
.instance_init = device_initfn,
|
||||||
|
.instance_post_init = device_post_init,
|
||||||
.instance_finalize = device_finalize,
|
.instance_finalize = device_finalize,
|
||||||
.class_base_init = device_class_base_init,
|
.class_base_init = device_class_base_init,
|
||||||
.class_init = device_class_init,
|
.class_init = device_class_init,
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
obj-$(CONFIG_ARM11MPCORE) += arm11mpcore.o
|
obj-$(CONFIG_ARM11MPCORE) += arm11mpcore.o
|
||||||
obj-$(CONFIG_ARM9MPCORE) += a9mpcore.o
|
obj-$(CONFIG_A9MPCORE) += a9mpcore.o
|
||||||
obj-$(CONFIG_ARM15MPCORE) += a15mpcore.o
|
obj-$(CONFIG_A15MPCORE) += a15mpcore.o
|
||||||
obj-$(CONFIG_ICC_BUS) += icc_bus.o
|
obj-$(CONFIG_ICC_BUS) += icc_bus.o
|
||||||
|
|
||||||
|
|||||||
@@ -49,6 +49,8 @@ static int a15mp_priv_init(SysBusDevice *dev)
|
|||||||
A15MPPrivState *s = A15MPCORE_PRIV(dev);
|
A15MPPrivState *s = A15MPCORE_PRIV(dev);
|
||||||
SysBusDevice *busdev;
|
SysBusDevice *busdev;
|
||||||
const char *gictype = "arm_gic";
|
const char *gictype = "arm_gic";
|
||||||
|
int i;
|
||||||
|
CPUState *cpu;
|
||||||
|
|
||||||
if (kvm_irqchip_in_kernel()) {
|
if (kvm_irqchip_in_kernel()) {
|
||||||
gictype = "kvm-arm-gic";
|
gictype = "kvm-arm-gic";
|
||||||
@@ -67,6 +69,22 @@ static int a15mp_priv_init(SysBusDevice *dev)
|
|||||||
/* Pass through inbound GPIO lines to the GIC */
|
/* Pass through inbound GPIO lines to the GIC */
|
||||||
qdev_init_gpio_in(DEVICE(dev), a15mp_priv_set_irq, s->num_irq - 32);
|
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):
|
/* Memory map (addresses are offsets from PERIPHBASE):
|
||||||
* 0x0000-0x0fff -- reserved
|
* 0x0000-0x0fff -- reserved
|
||||||
* 0x1000-0x1fff -- GIC Distributor
|
* 0x1000-0x1fff -- GIC Distributor
|
||||||
|
|||||||
@@ -355,7 +355,6 @@ static QEMUMachine axisdev88_machine = {
|
|||||||
.desc = "AXIS devboard 88",
|
.desc = "AXIS devboard 88",
|
||||||
.init = axisdev88_init,
|
.init = axisdev88_init,
|
||||||
.is_default = 1,
|
.is_default = 1,
|
||||||
DEFAULT_MACHINE_OPTIONS,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static void axisdev88_machine_init(void)
|
static void axisdev88_machine_init(void)
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
obj-$(CONFIG_KVM) += kvm/
|
obj-$(CONFIG_KVM) += kvm/
|
||||||
obj-y += multiboot.o smbios.o
|
obj-y += multiboot.o smbios.o
|
||||||
obj-y += pc.o pc_piix.o pc_q35.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-$(CONFIG_XEN) += xen_domainbuild.o xen_machine_pv.o
|
||||||
|
|
||||||
obj-y += kvmvapic.o
|
obj-y += kvmvapic.o
|
||||||
|
|||||||
13
hw/i386/pc.c
13
hw/i386/pc.c
@@ -912,21 +912,20 @@ static X86CPU *pc_new_cpu(const char *cpu_model, int64_t apic_id,
|
|||||||
X86CPU *cpu;
|
X86CPU *cpu;
|
||||||
Error *local_err = NULL;
|
Error *local_err = NULL;
|
||||||
|
|
||||||
cpu = cpu_x86_create(cpu_model, icc_bridge, errp);
|
cpu = cpu_x86_create(cpu_model, icc_bridge, &local_err);
|
||||||
if (!cpu) {
|
if (local_err != NULL) {
|
||||||
return cpu;
|
error_propagate(errp, local_err);
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
object_property_set_int(OBJECT(cpu), apic_id, "apic-id", &local_err);
|
object_property_set_int(OBJECT(cpu), apic_id, "apic-id", &local_err);
|
||||||
object_property_set_bool(OBJECT(cpu), true, "realized", &local_err);
|
object_property_set_bool(OBJECT(cpu), true, "realized", &local_err);
|
||||||
|
|
||||||
if (local_err) {
|
if (local_err) {
|
||||||
if (cpu != NULL) {
|
error_propagate(errp, local_err);
|
||||||
object_unref(OBJECT(cpu));
|
object_unref(OBJECT(cpu));
|
||||||
cpu = NULL;
|
cpu = NULL;
|
||||||
}
|
}
|
||||||
error_propagate(errp, local_err);
|
|
||||||
}
|
|
||||||
return cpu;
|
return cpu;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1146,7 +1145,7 @@ FWCfgState *pc_memory_init(MemoryRegion *system_memory,
|
|||||||
|
|
||||||
|
|
||||||
/* Initialize PC system firmware */
|
/* 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));
|
option_rom_mr = g_malloc(sizeof(*option_rom_mr));
|
||||||
memory_region_init_ram(option_rom_mr, NULL, "pc.rom", PC_ROM_SIZE);
|
memory_region_init_ram(option_rom_mr, NULL, "pc.rom", PC_ROM_SIZE);
|
||||||
|
|||||||
@@ -25,6 +25,7 @@
|
|||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
|
|
||||||
#include "hw/hw.h"
|
#include "hw/hw.h"
|
||||||
|
#include "hw/loader.h"
|
||||||
#include "hw/i386/pc.h"
|
#include "hw/i386/pc.h"
|
||||||
#include "hw/i386/apic.h"
|
#include "hw/i386/apic.h"
|
||||||
#include "hw/pci/pci.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_iobase2[MAX_IDE_BUS] = { 0x3f6, 0x376 };
|
||||||
static const int ide_irq[MAX_IDE_BUS] = { 14, 15 };
|
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;
|
static bool has_pci_info = true;
|
||||||
|
|
||||||
/* PC hardware initialisation */
|
/* PC hardware initialisation */
|
||||||
static void pc_init1(MemoryRegion *system_memory,
|
static void pc_init1(QEMUMachineInitArgs *args,
|
||||||
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,
|
|
||||||
int pci_enabled,
|
int pci_enabled,
|
||||||
int kvmclock_enabled)
|
int kvmclock_enabled)
|
||||||
{
|
{
|
||||||
|
MemoryRegion *system_memory = get_system_memory();
|
||||||
|
MemoryRegion *system_io = get_system_io();
|
||||||
int i;
|
int i;
|
||||||
ram_addr_t below_4g_mem_size, above_4g_mem_size;
|
ram_addr_t below_4g_mem_size, above_4g_mem_size;
|
||||||
PCIBus *pci_bus;
|
PCIBus *pci_bus;
|
||||||
@@ -102,19 +98,18 @@ static void pc_init1(MemoryRegion *system_memory,
|
|||||||
object_property_add_child(qdev_get_machine(), "icc-bridge",
|
object_property_add_child(qdev_get_machine(), "icc-bridge",
|
||||||
OBJECT(icc_bridge), NULL);
|
OBJECT(icc_bridge), NULL);
|
||||||
|
|
||||||
pc_cpus_init(cpu_model, icc_bridge);
|
pc_cpus_init(args->cpu_model, icc_bridge);
|
||||||
pc_acpi_init("acpi-dsdt.aml");
|
|
||||||
|
|
||||||
if (kvm_enabled() && kvmclock_enabled) {
|
if (kvm_enabled() && kvmclock_enabled) {
|
||||||
kvmclock_create();
|
kvmclock_create();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ram_size >= 0xe0000000 ) {
|
if (args->ram_size >= 0xe0000000) {
|
||||||
above_4g_mem_size = ram_size - 0xe0000000;
|
above_4g_mem_size = args->ram_size - 0xe0000000;
|
||||||
below_4g_mem_size = 0xe0000000;
|
below_4g_mem_size = 0xe0000000;
|
||||||
} else {
|
} else {
|
||||||
above_4g_mem_size = 0;
|
above_4g_mem_size = 0;
|
||||||
below_4g_mem_size = ram_size;
|
below_4g_mem_size = args->ram_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pci_enabled) {
|
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 = pc_guest_info_init(below_4g_mem_size, above_4g_mem_size);
|
||||||
guest_info->has_pci_info = has_pci_info;
|
guest_info->has_pci_info = has_pci_info;
|
||||||
|
guest_info->isapc_ram_fw = !pci_enabled;
|
||||||
|
|
||||||
/* allocate ram and load rom/bios */
|
/* allocate ram and load rom/bios */
|
||||||
if (!xen_enabled()) {
|
if (!xen_enabled()) {
|
||||||
fw_cfg = pc_memory_init(system_memory,
|
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,
|
below_4g_mem_size, above_4g_mem_size,
|
||||||
rom_memory, &ram_memory, guest_info);
|
rom_memory, &ram_memory, guest_info);
|
||||||
}
|
}
|
||||||
@@ -148,7 +145,7 @@ static void pc_init1(MemoryRegion *system_memory,
|
|||||||
|
|
||||||
if (pci_enabled) {
|
if (pci_enabled) {
|
||||||
pci_bus = i440fx_init(&i440fx_state, &piix3_devfn, &isa_bus, gsi,
|
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,
|
below_4g_mem_size,
|
||||||
0x100000000ULL - below_4g_mem_size,
|
0x100000000ULL - below_4g_mem_size,
|
||||||
above_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);
|
floppy, idebus[0], idebus[1], rtc_state);
|
||||||
|
|
||||||
if (pci_enabled && usb_enabled(false)) {
|
if (pci_enabled && usb_enabled(false)) {
|
||||||
@@ -236,90 +233,91 @@ static void pc_init1(MemoryRegion *system_memory,
|
|||||||
|
|
||||||
static void pc_init_pci(QEMUMachineInitArgs *args)
|
static void pc_init_pci(QEMUMachineInitArgs *args)
|
||||||
{
|
{
|
||||||
ram_addr_t ram_size = args->ram_size;
|
pc_init1(args, 1, 1);
|
||||||
const char *cpu_model = args->cpu_model;
|
}
|
||||||
const char *kernel_filename = args->kernel_filename;
|
|
||||||
const char *kernel_cmdline = args->kernel_cmdline;
|
static void pc_compat_1_6(QEMUMachineInitArgs *args)
|
||||||
const char *initrd_filename = args->initrd_filename;
|
{
|
||||||
const char *boot_device = args->boot_device;
|
has_pci_info = false;
|
||||||
pc_init1(get_system_memory(),
|
rom_file_in_ram = false;
|
||||||
get_system_io(),
|
}
|
||||||
ram_size, boot_device,
|
|
||||||
kernel_filename, kernel_cmdline,
|
static void pc_compat_1_5(QEMUMachineInitArgs *args)
|
||||||
initrd_filename, cpu_model, 1, 1);
|
{
|
||||||
|
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)
|
static void pc_init_pci_1_5(QEMUMachineInitArgs *args)
|
||||||
{
|
{
|
||||||
has_pci_info = false;
|
pc_compat_1_5(args);
|
||||||
pc_init_pci(args);
|
pc_init_pci(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pc_init_pci_1_4(QEMUMachineInitArgs *args)
|
static void pc_init_pci_1_4(QEMUMachineInitArgs *args)
|
||||||
{
|
{
|
||||||
has_pvpanic = false;
|
pc_compat_1_4(args);
|
||||||
x86_cpu_compat_set_features("n270", FEAT_1_ECX, 0, CPUID_EXT_MOVBE);
|
pc_init_pci(args);
|
||||||
pc_init_pci_1_5(args);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pc_init_pci_1_3(QEMUMachineInitArgs *args)
|
static void pc_init_pci_1_3(QEMUMachineInitArgs *args)
|
||||||
{
|
{
|
||||||
enable_compat_apic_id_mode();
|
pc_compat_1_3(args);
|
||||||
pc_init_pci_1_4(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)
|
static void pc_init_pci_1_2(QEMUMachineInitArgs *args)
|
||||||
{
|
{
|
||||||
disable_kvm_pv_eoi();
|
pc_compat_1_2(args);
|
||||||
pc_init_pci_1_3(args);
|
pc_init_pci(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 init function for pc-0.10 to pc-0.13, and reused by xenfv */
|
/* PC init function for pc-0.10 to pc-0.13, and reused by xenfv */
|
||||||
static void pc_init_pci_no_kvmclock(QEMUMachineInitArgs *args)
|
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;
|
has_pci_info = false;
|
||||||
disable_kvm_pv_eoi();
|
disable_kvm_pv_eoi();
|
||||||
enable_compat_apic_id_mode();
|
enable_compat_apic_id_mode();
|
||||||
pc_init1(get_system_memory(),
|
pc_init1(args, 1, 0);
|
||||||
get_system_io(),
|
|
||||||
ram_size, boot_device,
|
|
||||||
kernel_filename, kernel_cmdline,
|
|
||||||
initrd_filename, cpu_model, 1, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pc_init_isa(QEMUMachineInitArgs *args)
|
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;
|
has_pci_info = false;
|
||||||
if (cpu_model == NULL)
|
if (!args->cpu_model) {
|
||||||
cpu_model = "486";
|
args->cpu_model = "486";
|
||||||
|
}
|
||||||
disable_kvm_pv_eoi();
|
disable_kvm_pv_eoi();
|
||||||
enable_compat_apic_id_mode();
|
enable_compat_apic_id_mode();
|
||||||
pc_init1(get_system_memory(),
|
pc_init1(args, 0, 1);
|
||||||
get_system_io(),
|
|
||||||
ram_size, boot_device,
|
|
||||||
kernel_filename, kernel_cmdline,
|
|
||||||
initrd_filename, cpu_model, 0, 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_XEN
|
#ifdef CONFIG_XEN
|
||||||
@@ -336,40 +334,43 @@ static void pc_xen_hvm_init(QEMUMachineInitArgs *args)
|
|||||||
}
|
}
|
||||||
#endif
|
#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 = {
|
static QEMUMachine pc_i440fx_machine_v1_6 = {
|
||||||
|
PC_I440FX_1_6_MACHINE_OPTIONS,
|
||||||
.name = "pc-i440fx-1.6",
|
.name = "pc-i440fx-1.6",
|
||||||
.alias = "pc",
|
.alias = "pc",
|
||||||
.desc = "Standard PC (i440FX + PIIX, 1996)",
|
.init = pc_init_pci_1_6,
|
||||||
.init = pc_init_pci,
|
|
||||||
.hot_add_cpu = pc_hot_add_cpu,
|
|
||||||
.max_cpus = 255,
|
|
||||||
.is_default = 1,
|
.is_default = 1,
|
||||||
DEFAULT_MACHINE_OPTIONS,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static QEMUMachine pc_i440fx_machine_v1_5 = {
|
static QEMUMachine pc_i440fx_machine_v1_5 = {
|
||||||
|
PC_I440FX_1_6_MACHINE_OPTIONS,
|
||||||
.name = "pc-i440fx-1.5",
|
.name = "pc-i440fx-1.5",
|
||||||
.desc = "Standard PC (i440FX + PIIX, 1996)",
|
|
||||||
.init = pc_init_pci_1_5,
|
.init = pc_init_pci_1_5,
|
||||||
.hot_add_cpu = pc_hot_add_cpu,
|
|
||||||
.max_cpus = 255,
|
|
||||||
.compat_props = (GlobalProperty[]) {
|
.compat_props = (GlobalProperty[]) {
|
||||||
PC_COMPAT_1_5,
|
PC_COMPAT_1_5,
|
||||||
{ /* end of list */ }
|
{ /* 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 = {
|
static QEMUMachine pc_i440fx_machine_v1_4 = {
|
||||||
|
PC_I440FX_1_4_MACHINE_OPTIONS,
|
||||||
.name = "pc-i440fx-1.4",
|
.name = "pc-i440fx-1.4",
|
||||||
.desc = "Standard PC (i440FX + PIIX, 1996)",
|
|
||||||
.init = pc_init_pci_1_4,
|
.init = pc_init_pci_1_4,
|
||||||
.max_cpus = 255,
|
|
||||||
.compat_props = (GlobalProperty[]) {
|
.compat_props = (GlobalProperty[]) {
|
||||||
PC_COMPAT_1_4,
|
PC_COMPAT_1_4,
|
||||||
{ /* end of list */ }
|
{ /* end of list */ }
|
||||||
},
|
},
|
||||||
DEFAULT_MACHINE_OPTIONS,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#define PC_COMPAT_1_3 \
|
#define PC_COMPAT_1_3 \
|
||||||
@@ -393,15 +394,13 @@ static QEMUMachine pc_i440fx_machine_v1_4 = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static QEMUMachine pc_machine_v1_3 = {
|
static QEMUMachine pc_machine_v1_3 = {
|
||||||
|
PC_I440FX_1_4_MACHINE_OPTIONS,
|
||||||
.name = "pc-1.3",
|
.name = "pc-1.3",
|
||||||
.desc = "Standard PC",
|
|
||||||
.init = pc_init_pci_1_3,
|
.init = pc_init_pci_1_3,
|
||||||
.max_cpus = 255,
|
|
||||||
.compat_props = (GlobalProperty[]) {
|
.compat_props = (GlobalProperty[]) {
|
||||||
PC_COMPAT_1_3,
|
PC_COMPAT_1_3,
|
||||||
{ /* end of list */ }
|
{ /* end of list */ }
|
||||||
},
|
},
|
||||||
DEFAULT_MACHINE_OPTIONS,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#define PC_COMPAT_1_2 \
|
#define PC_COMPAT_1_2 \
|
||||||
@@ -432,16 +431,17 @@ static QEMUMachine pc_machine_v1_3 = {
|
|||||||
.value = "off",\
|
.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 = {
|
static QEMUMachine pc_machine_v1_2 = {
|
||||||
|
PC_I440FX_1_2_MACHINE_OPTIONS,
|
||||||
.name = "pc-1.2",
|
.name = "pc-1.2",
|
||||||
.desc = "Standard PC",
|
|
||||||
.init = pc_init_pci_1_2,
|
|
||||||
.max_cpus = 255,
|
|
||||||
.compat_props = (GlobalProperty[]) {
|
.compat_props = (GlobalProperty[]) {
|
||||||
PC_COMPAT_1_2,
|
PC_COMPAT_1_2,
|
||||||
{ /* end of list */ }
|
{ /* end of list */ }
|
||||||
},
|
},
|
||||||
DEFAULT_MACHINE_OPTIONS,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#define PC_COMPAT_1_1 \
|
#define PC_COMPAT_1_1 \
|
||||||
@@ -477,24 +477,17 @@ static QEMUMachine pc_machine_v1_2 = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static QEMUMachine pc_machine_v1_1 = {
|
static QEMUMachine pc_machine_v1_1 = {
|
||||||
|
PC_I440FX_1_2_MACHINE_OPTIONS,
|
||||||
.name = "pc-1.1",
|
.name = "pc-1.1",
|
||||||
.desc = "Standard PC",
|
|
||||||
.init = pc_init_pci_1_2,
|
|
||||||
.max_cpus = 255,
|
|
||||||
.compat_props = (GlobalProperty[]) {
|
.compat_props = (GlobalProperty[]) {
|
||||||
PC_COMPAT_1_1,
|
PC_COMPAT_1_1,
|
||||||
{ /* end of list */ }
|
{ /* end of list */ }
|
||||||
},
|
},
|
||||||
DEFAULT_MACHINE_OPTIONS,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#define PC_COMPAT_1_0 \
|
#define PC_COMPAT_1_0 \
|
||||||
PC_COMPAT_1_1,\
|
PC_COMPAT_1_1,\
|
||||||
{\
|
{\
|
||||||
.driver = "pc-sysfw",\
|
|
||||||
.property = "rom_only",\
|
|
||||||
.value = stringify(1),\
|
|
||||||
}, {\
|
|
||||||
.driver = TYPE_ISA_FDC,\
|
.driver = TYPE_ISA_FDC,\
|
||||||
.property = "check_media_rate",\
|
.property = "check_media_rate",\
|
||||||
.value = "off",\
|
.value = "off",\
|
||||||
@@ -513,32 +506,26 @@ static QEMUMachine pc_machine_v1_1 = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static QEMUMachine pc_machine_v1_0 = {
|
static QEMUMachine pc_machine_v1_0 = {
|
||||||
|
PC_I440FX_1_2_MACHINE_OPTIONS,
|
||||||
.name = "pc-1.0",
|
.name = "pc-1.0",
|
||||||
.desc = "Standard PC",
|
|
||||||
.init = pc_init_pci_1_0,
|
|
||||||
.max_cpus = 255,
|
|
||||||
.compat_props = (GlobalProperty[]) {
|
.compat_props = (GlobalProperty[]) {
|
||||||
PC_COMPAT_1_0,
|
PC_COMPAT_1_0,
|
||||||
{ /* end of list */ }
|
{ /* end of list */ }
|
||||||
},
|
},
|
||||||
.hw_version = "1.0",
|
.hw_version = "1.0",
|
||||||
DEFAULT_MACHINE_OPTIONS,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#define PC_COMPAT_0_15 \
|
#define PC_COMPAT_0_15 \
|
||||||
PC_COMPAT_1_0
|
PC_COMPAT_1_0
|
||||||
|
|
||||||
static QEMUMachine pc_machine_v0_15 = {
|
static QEMUMachine pc_machine_v0_15 = {
|
||||||
|
PC_I440FX_1_2_MACHINE_OPTIONS,
|
||||||
.name = "pc-0.15",
|
.name = "pc-0.15",
|
||||||
.desc = "Standard PC",
|
|
||||||
.init = pc_init_pci_1_0,
|
|
||||||
.max_cpus = 255,
|
|
||||||
.compat_props = (GlobalProperty[]) {
|
.compat_props = (GlobalProperty[]) {
|
||||||
PC_COMPAT_0_15,
|
PC_COMPAT_0_15,
|
||||||
{ /* end of list */ }
|
{ /* end of list */ }
|
||||||
},
|
},
|
||||||
.hw_version = "0.15",
|
.hw_version = "0.15",
|
||||||
DEFAULT_MACHINE_OPTIONS,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#define PC_COMPAT_0_14 \
|
#define PC_COMPAT_0_14 \
|
||||||
@@ -562,10 +549,8 @@ static QEMUMachine pc_machine_v0_15 = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static QEMUMachine pc_machine_v0_14 = {
|
static QEMUMachine pc_machine_v0_14 = {
|
||||||
|
PC_I440FX_1_2_MACHINE_OPTIONS,
|
||||||
.name = "pc-0.14",
|
.name = "pc-0.14",
|
||||||
.desc = "Standard PC",
|
|
||||||
.init = pc_init_pci_1_0,
|
|
||||||
.max_cpus = 255,
|
|
||||||
.compat_props = (GlobalProperty[]) {
|
.compat_props = (GlobalProperty[]) {
|
||||||
PC_COMPAT_0_14,
|
PC_COMPAT_0_14,
|
||||||
{
|
{
|
||||||
@@ -580,7 +565,6 @@ static QEMUMachine pc_machine_v0_14 = {
|
|||||||
{ /* end of list */ }
|
{ /* end of list */ }
|
||||||
},
|
},
|
||||||
.hw_version = "0.14",
|
.hw_version = "0.14",
|
||||||
DEFAULT_MACHINE_OPTIONS,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#define PC_COMPAT_0_13 \
|
#define PC_COMPAT_0_13 \
|
||||||
@@ -595,11 +579,13 @@ static QEMUMachine pc_machine_v0_14 = {
|
|||||||
.value = stringify(1),\
|
.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 = {
|
static QEMUMachine pc_machine_v0_13 = {
|
||||||
|
PC_I440FX_0_13_MACHINE_OPTIONS,
|
||||||
.name = "pc-0.13",
|
.name = "pc-0.13",
|
||||||
.desc = "Standard PC",
|
|
||||||
.init = pc_init_pci_no_kvmclock,
|
|
||||||
.max_cpus = 255,
|
|
||||||
.compat_props = (GlobalProperty[]) {
|
.compat_props = (GlobalProperty[]) {
|
||||||
PC_COMPAT_0_13,
|
PC_COMPAT_0_13,
|
||||||
{
|
{
|
||||||
@@ -618,7 +604,6 @@ static QEMUMachine pc_machine_v0_13 = {
|
|||||||
{ /* end of list */ }
|
{ /* end of list */ }
|
||||||
},
|
},
|
||||||
.hw_version = "0.13",
|
.hw_version = "0.13",
|
||||||
DEFAULT_MACHINE_OPTIONS,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#define PC_COMPAT_0_12 \
|
#define PC_COMPAT_0_12 \
|
||||||
@@ -646,10 +631,8 @@ static QEMUMachine pc_machine_v0_13 = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static QEMUMachine pc_machine_v0_12 = {
|
static QEMUMachine pc_machine_v0_12 = {
|
||||||
|
PC_I440FX_0_13_MACHINE_OPTIONS,
|
||||||
.name = "pc-0.12",
|
.name = "pc-0.12",
|
||||||
.desc = "Standard PC",
|
|
||||||
.init = pc_init_pci_no_kvmclock,
|
|
||||||
.max_cpus = 255,
|
|
||||||
.compat_props = (GlobalProperty[]) {
|
.compat_props = (GlobalProperty[]) {
|
||||||
PC_COMPAT_0_12,
|
PC_COMPAT_0_12,
|
||||||
{
|
{
|
||||||
@@ -664,7 +647,6 @@ static QEMUMachine pc_machine_v0_12 = {
|
|||||||
{ /* end of list */ }
|
{ /* end of list */ }
|
||||||
},
|
},
|
||||||
.hw_version = "0.12",
|
.hw_version = "0.12",
|
||||||
DEFAULT_MACHINE_OPTIONS,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#define PC_COMPAT_0_11 \
|
#define PC_COMPAT_0_11 \
|
||||||
@@ -680,10 +662,8 @@ static QEMUMachine pc_machine_v0_12 = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static QEMUMachine pc_machine_v0_11 = {
|
static QEMUMachine pc_machine_v0_11 = {
|
||||||
|
PC_I440FX_0_13_MACHINE_OPTIONS,
|
||||||
.name = "pc-0.11",
|
.name = "pc-0.11",
|
||||||
.desc = "Standard PC, qemu 0.11",
|
|
||||||
.init = pc_init_pci_no_kvmclock,
|
|
||||||
.max_cpus = 255,
|
|
||||||
.compat_props = (GlobalProperty[]) {
|
.compat_props = (GlobalProperty[]) {
|
||||||
PC_COMPAT_0_11,
|
PC_COMPAT_0_11,
|
||||||
{
|
{
|
||||||
@@ -698,14 +678,11 @@ static QEMUMachine pc_machine_v0_11 = {
|
|||||||
{ /* end of list */ }
|
{ /* end of list */ }
|
||||||
},
|
},
|
||||||
.hw_version = "0.11",
|
.hw_version = "0.11",
|
||||||
DEFAULT_MACHINE_OPTIONS,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static QEMUMachine pc_machine_v0_10 = {
|
static QEMUMachine pc_machine_v0_10 = {
|
||||||
|
PC_I440FX_0_13_MACHINE_OPTIONS,
|
||||||
.name = "pc-0.10",
|
.name = "pc-0.10",
|
||||||
.desc = "Standard PC, qemu 0.10",
|
|
||||||
.init = pc_init_pci_no_kvmclock,
|
|
||||||
.max_cpus = 255,
|
|
||||||
.compat_props = (GlobalProperty[]) {
|
.compat_props = (GlobalProperty[]) {
|
||||||
PC_COMPAT_0_11,
|
PC_COMPAT_0_11,
|
||||||
{
|
{
|
||||||
@@ -732,38 +709,27 @@ static QEMUMachine pc_machine_v0_10 = {
|
|||||||
{ /* end of list */ }
|
{ /* end of list */ }
|
||||||
},
|
},
|
||||||
.hw_version = "0.10",
|
.hw_version = "0.10",
|
||||||
DEFAULT_MACHINE_OPTIONS,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static QEMUMachine isapc_machine = {
|
static QEMUMachine isapc_machine = {
|
||||||
|
PC_COMMON_MACHINE_OPTIONS,
|
||||||
.name = "isapc",
|
.name = "isapc",
|
||||||
.desc = "ISA-only PC",
|
.desc = "ISA-only PC",
|
||||||
.init = pc_init_isa,
|
.init = pc_init_isa,
|
||||||
.max_cpus = 1,
|
.max_cpus = 1,
|
||||||
.compat_props = (GlobalProperty[]) {
|
.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 */ }
|
{ /* end of list */ }
|
||||||
},
|
},
|
||||||
DEFAULT_MACHINE_OPTIONS,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef CONFIG_XEN
|
#ifdef CONFIG_XEN
|
||||||
static QEMUMachine xenfv_machine = {
|
static QEMUMachine xenfv_machine = {
|
||||||
|
PC_COMMON_MACHINE_OPTIONS,
|
||||||
.name = "xenfv",
|
.name = "xenfv",
|
||||||
.desc = "Xen Fully-virtualized PC",
|
.desc = "Xen Fully-virtualized PC",
|
||||||
.init = pc_xen_hvm_init,
|
.init = pc_xen_hvm_init,
|
||||||
.max_cpus = HVM_MAX_VCPUS,
|
.max_cpus = HVM_MAX_VCPUS,
|
||||||
.default_machine_opts = "accel=xen",
|
.default_machine_opts = "accel=xen",
|
||||||
DEFAULT_MACHINE_OPTIONS,
|
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -28,6 +28,7 @@
|
|||||||
* THE SOFTWARE.
|
* THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
#include "hw/hw.h"
|
#include "hw/hw.h"
|
||||||
|
#include "hw/loader.h"
|
||||||
#include "sysemu/arch_init.h"
|
#include "sysemu/arch_init.h"
|
||||||
#include "hw/i2c/smbus.h"
|
#include "hw/i2c/smbus.h"
|
||||||
#include "hw/boards.h"
|
#include "hw/boards.h"
|
||||||
@@ -46,18 +47,12 @@
|
|||||||
/* ICH9 AHCI has 6 ports */
|
/* ICH9 AHCI has 6 ports */
|
||||||
#define MAX_SATA_PORTS 6
|
#define MAX_SATA_PORTS 6
|
||||||
|
|
||||||
static bool has_pvpanic = true;
|
static bool has_pvpanic;
|
||||||
static bool has_pci_info = true;
|
static bool has_pci_info = true;
|
||||||
|
|
||||||
/* PC hardware initialisation */
|
/* PC hardware initialisation */
|
||||||
static void pc_q35_init(QEMUMachineInitArgs *args)
|
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;
|
ram_addr_t below_4g_mem_size, above_4g_mem_size;
|
||||||
Q35PCIHost *q35_host;
|
Q35PCIHost *q35_host;
|
||||||
PCIHostState *phb;
|
PCIHostState *phb;
|
||||||
@@ -85,17 +80,17 @@ static void pc_q35_init(QEMUMachineInitArgs *args)
|
|||||||
object_property_add_child(qdev_get_machine(), "icc-bridge",
|
object_property_add_child(qdev_get_machine(), "icc-bridge",
|
||||||
OBJECT(icc_bridge), NULL);
|
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");
|
pc_acpi_init("q35-acpi-dsdt.aml");
|
||||||
|
|
||||||
kvmclock_create();
|
kvmclock_create();
|
||||||
|
|
||||||
if (ram_size >= 0xb0000000) {
|
if (args->ram_size >= 0xb0000000) {
|
||||||
above_4g_mem_size = ram_size - 0xb0000000;
|
above_4g_mem_size = args->ram_size - 0xb0000000;
|
||||||
below_4g_mem_size = 0xb0000000;
|
below_4g_mem_size = 0xb0000000;
|
||||||
} else {
|
} else {
|
||||||
above_4g_mem_size = 0;
|
above_4g_mem_size = 0;
|
||||||
below_4g_mem_size = ram_size;
|
below_4g_mem_size = args->ram_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* pci enabled */
|
/* 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 = pc_guest_info_init(below_4g_mem_size, above_4g_mem_size);
|
||||||
guest_info->has_pci_info = has_pci_info;
|
guest_info->has_pci_info = has_pci_info;
|
||||||
|
guest_info->isapc_ram_fw = false;
|
||||||
|
|
||||||
/* allocate ram and load rom/bios */
|
/* allocate ram and load rom/bios */
|
||||||
if (!xen_enabled()) {
|
if (!xen_enabled()) {
|
||||||
pc_memory_init(get_system_memory(), kernel_filename, kernel_cmdline,
|
pc_memory_init(get_system_memory(),
|
||||||
initrd_filename, below_4g_mem_size, above_4g_mem_size,
|
args->kernel_filename, args->kernel_cmdline,
|
||||||
|
args->initrd_filename,
|
||||||
|
below_4g_mem_size, above_4g_mem_size,
|
||||||
rom_memory, &ram_memory, guest_info);
|
rom_memory, &ram_memory, guest_info);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -202,7 +200,7 @@ static void pc_q35_init(QEMUMachineInitArgs *args)
|
|||||||
0xb100),
|
0xb100),
|
||||||
8, NULL, 0);
|
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);
|
floppy, idebus[0], idebus[1], rtc_state);
|
||||||
|
|
||||||
/* the rest devices to which pci devfn is automatically assigned */
|
/* 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;
|
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);
|
pc_q35_init(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pc_q35_init_1_4(QEMUMachineInitArgs *args)
|
static void pc_q35_init_1_4(QEMUMachineInitArgs *args)
|
||||||
{
|
{
|
||||||
has_pvpanic = false;
|
pc_compat_1_4(args);
|
||||||
x86_cpu_compat_set_features("n270", FEAT_1_ECX, 0, CPUID_EXT_MOVBE);
|
pc_q35_init(args);
|
||||||
pc_q35_init_1_5(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 = {
|
static QEMUMachine pc_q35_machine_v1_6 = {
|
||||||
|
PC_Q35_1_6_MACHINE_OPTIONS,
|
||||||
.name = "pc-q35-1.6",
|
.name = "pc-q35-1.6",
|
||||||
.alias = "q35",
|
.alias = "q35",
|
||||||
.desc = "Standard PC (Q35 + ICH9, 2009)",
|
.init = pc_q35_init_1_6,
|
||||||
.init = pc_q35_init,
|
|
||||||
.hot_add_cpu = pc_hot_add_cpu,
|
|
||||||
.max_cpus = 255,
|
|
||||||
DEFAULT_MACHINE_OPTIONS,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static QEMUMachine pc_q35_machine_v1_5 = {
|
static QEMUMachine pc_q35_machine_v1_5 = {
|
||||||
|
PC_Q35_1_6_MACHINE_OPTIONS,
|
||||||
.name = "pc-q35-1.5",
|
.name = "pc-q35-1.5",
|
||||||
.desc = "Standard PC (Q35 + ICH9, 2009)",
|
|
||||||
.init = pc_q35_init_1_5,
|
.init = pc_q35_init_1_5,
|
||||||
.hot_add_cpu = pc_hot_add_cpu,
|
|
||||||
.max_cpus = 255,
|
|
||||||
.compat_props = (GlobalProperty[]) {
|
.compat_props = (GlobalProperty[]) {
|
||||||
PC_COMPAT_1_5,
|
PC_COMPAT_1_5,
|
||||||
{ /* end of list */ }
|
{ /* 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 = {
|
static QEMUMachine pc_q35_machine_v1_4 = {
|
||||||
|
PC_Q35_1_4_MACHINE_OPTIONS,
|
||||||
.name = "pc-q35-1.4",
|
.name = "pc-q35-1.4",
|
||||||
.desc = "Standard PC (Q35 + ICH9, 2009)",
|
|
||||||
.init = pc_q35_init_1_4,
|
.init = pc_q35_init_1_4,
|
||||||
.max_cpus = 255,
|
|
||||||
.compat_props = (GlobalProperty[]) {
|
.compat_props = (GlobalProperty[]) {
|
||||||
PC_COMPAT_1_4,
|
PC_COMPAT_1_4,
|
||||||
{ /* end of list */ }
|
{ /* end of list */ }
|
||||||
},
|
},
|
||||||
DEFAULT_MACHINE_OPTIONS,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static void pc_q35_machine_init(void)
|
static void pc_q35_machine_init(void)
|
||||||
|
|||||||
@@ -38,7 +38,6 @@
|
|||||||
|
|
||||||
typedef struct PcSysFwDevice {
|
typedef struct PcSysFwDevice {
|
||||||
SysBusDevice busdev;
|
SysBusDevice busdev;
|
||||||
uint8_t rom_only;
|
|
||||||
uint8_t isapc_ram_fw;
|
uint8_t isapc_ram_fw;
|
||||||
} PcSysFwDevice;
|
} PcSysFwDevice;
|
||||||
|
|
||||||
@@ -76,39 +75,6 @@ static void pc_isa_bios_init(MemoryRegion *rom_memory,
|
|||||||
memory_region_set_readonly(isa_bios, true);
|
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,
|
static void pc_system_flash_init(MemoryRegion *rom_memory,
|
||||||
DriveInfo *pflash_drv)
|
DriveInfo *pflash_drv)
|
||||||
{
|
{
|
||||||
@@ -199,110 +165,24 @@ static void old_pc_system_rom_init(MemoryRegion *rom_memory, bool isapc_ram_fw)
|
|||||||
bios);
|
bios);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
void pc_system_firmware_init(MemoryRegion *rom_memory, bool isapc_ram_fw)
|
||||||
* 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)
|
|
||||||
{
|
{
|
||||||
DriveInfo *pflash_drv;
|
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);
|
pflash_drv = drive_get(IF_PFLASH, 0, 0);
|
||||||
|
|
||||||
if (pc_sysfw_flash_vs_rom_bug_compatible) {
|
if (isapc_ram_fw || pflash_drv == NULL) {
|
||||||
/*
|
|
||||||
* 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) {
|
|
||||||
/* When a pflash drive is not found, use rom-mode */
|
/* When a pflash drive is not found, use rom-mode */
|
||||||
sysfw_dev->rom_only = 1;
|
old_pc_system_rom_init(rom_memory, isapc_ram_fw);
|
||||||
} else if (kvm_enabled() && !kvm_readonly_mem_enabled()) {
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (kvm_enabled() && !kvm_readonly_mem_enabled()) {
|
||||||
/* Older KVM cannot execute from device memory. So, flash memory
|
/* Older KVM cannot execute from device memory. So, flash memory
|
||||||
* cannot be used unless the readonly memory kvm capability is present. */
|
* cannot be used unless the readonly memory kvm capability is present. */
|
||||||
fprintf(stderr, "qemu: pflash with kvm requires KVM readonly memory support\n");
|
fprintf(stderr, "qemu: pflash with kvm requires KVM readonly memory support\n");
|
||||||
exit(1);
|
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);
|
pc_system_flash_init(rom_memory, pflash_drv);
|
||||||
} else {
|
|
||||||
fprintf(stderr, "qemu: PC system firmware (pflash) not available\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
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,
|
.init = xen_init_pv,
|
||||||
.max_cpus = 1,
|
.max_cpus = 1,
|
||||||
.default_machine_opts = "accel=xen",
|
.default_machine_opts = "accel=xen",
|
||||||
DEFAULT_MACHINE_OPTIONS,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static void xenpv_machine_init(void)
|
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/timer/i8254.h"
|
||||||
#include "hw/audio/pcspk.h"
|
#include "hw/audio/pcspk.h"
|
||||||
|
|
||||||
//#define DEBUG_I82378
|
#define TYPE_I82378 "i82378"
|
||||||
|
#define I82378(obj) \
|
||||||
#ifdef DEBUG_I82378
|
OBJECT_CHECK(I82378State, (obj), TYPE_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)
|
|
||||||
|
|
||||||
typedef struct I82378State {
|
typedef struct I82378State {
|
||||||
|
PCIDevice parent_obj;
|
||||||
|
|
||||||
qemu_irq out[2];
|
qemu_irq out[2];
|
||||||
qemu_irq *i8259;
|
qemu_irq *i8259;
|
||||||
MemoryRegion io;
|
MemoryRegion io;
|
||||||
MemoryRegion mem;
|
|
||||||
} I82378State;
|
} I82378State;
|
||||||
|
|
||||||
typedef struct PCIi82378State {
|
static const VMStateDescription vmstate_i82378 = {
|
||||||
PCIDevice pci_dev;
|
|
||||||
uint32_t isa_io_base;
|
|
||||||
uint32_t isa_mem_base;
|
|
||||||
I82378State state;
|
|
||||||
} PCIi82378State;
|
|
||||||
|
|
||||||
static const VMStateDescription vmstate_pci_i82378 = {
|
|
||||||
.name = "pci-i82378",
|
.name = "pci-i82378",
|
||||||
.version_id = 0,
|
.version_id = 0,
|
||||||
.minimum_version_id = 0,
|
.minimum_version_id = 0,
|
||||||
.fields = (VMStateField[]) {
|
.fields = (VMStateField[]) {
|
||||||
VMSTATE_PCI_DEVICE(pci_dev, PCIi82378State),
|
VMSTATE_PCI_DEVICE(parent_obj, I82378State),
|
||||||
VMSTATE_END_OF_LIST()
|
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)
|
static void i82378_request_out0_irq(void *opaque, int irq, int level)
|
||||||
{
|
{
|
||||||
I82378State *s = opaque;
|
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)
|
static void i82378_request_pic_irq(void *opaque, int irq, int level)
|
||||||
{
|
{
|
||||||
DeviceState *dev = opaque;
|
DeviceState *dev = opaque;
|
||||||
PCIDevice *pci = DO_UPCAST(PCIDevice, qdev, dev);
|
I82378State *s = I82378(dev);
|
||||||
PCIi82378State *s = DO_UPCAST(PCIi82378State, pci_dev, pci);
|
|
||||||
|
|
||||||
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"));
|
DeviceState *dev = DEVICE(pci);
|
||||||
ISADevice *pit;
|
I82378State *s = I82378(dev);
|
||||||
|
uint8_t *pci_conf;
|
||||||
|
ISABus *isabus;
|
||||||
ISADevice *isa;
|
ISADevice *isa;
|
||||||
qemu_irq *out0_irq;
|
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:
|
/* This device has:
|
||||||
2 82C59 (irq)
|
2 82C59 (irq)
|
||||||
1 82C54 (pit)
|
1 82C54 (pit)
|
||||||
@@ -183,9 +87,6 @@ static void i82378_init(DeviceState *dev, I82378State *s)
|
|||||||
All devices accept byte access only, except timer
|
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... */
|
/* Workaround the fact that i8259 is not qdev'ified... */
|
||||||
out0_irq = qemu_allocate_irqs(i82378_request_out0_irq, s, 1);
|
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);
|
isa_bus_irqs(isabus, s->i8259);
|
||||||
|
|
||||||
/* 1 82C54 (pit) */
|
/* 1 82C54 (pit) */
|
||||||
pit = pit_init(isabus, 0x40, 0, NULL);
|
isa = pit_init(isabus, 0x40, 0, NULL);
|
||||||
|
|
||||||
/* speaker */
|
/* speaker */
|
||||||
pcspk_init(isabus, pit);
|
pcspk_init(isabus, isa);
|
||||||
|
|
||||||
/* 2 82C37 (dma) */
|
/* 2 82C37 (dma) */
|
||||||
isa = isa_create_simple(isabus, "i82374");
|
isa = isa_create_simple(isabus, "i82374");
|
||||||
@@ -205,76 +106,44 @@ static void i82378_init(DeviceState *dev, I82378State *s)
|
|||||||
|
|
||||||
/* timer */
|
/* timer */
|
||||||
isa_create_simple(isabus, "mc146818rtc");
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Property i82378_properties[] = {
|
static void i82378_init(Object *obj)
|
||||||
DEFINE_PROP_HEX32("iobase", PCIi82378State, isa_io_base, 0x80000000),
|
{
|
||||||
DEFINE_PROP_HEX32("membase", PCIi82378State, isa_mem_base, 0xc0000000),
|
DeviceState *dev = DEVICE(obj);
|
||||||
DEFINE_PROP_END_OF_LIST()
|
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);
|
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
|
||||||
DeviceClass *dc = 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->vendor_id = PCI_VENDOR_ID_INTEL;
|
||||||
k->device_id = PCI_DEVICE_ID_INTEL_82378;
|
k->device_id = PCI_DEVICE_ID_INTEL_82378;
|
||||||
k->revision = 0x03;
|
k->revision = 0x03;
|
||||||
k->class_id = PCI_CLASS_BRIDGE_ISA;
|
k->class_id = PCI_CLASS_BRIDGE_ISA;
|
||||||
k->subsystem_vendor_id = 0x0;
|
dc->vmsd = &vmstate_i82378;
|
||||||
k->subsystem_id = 0x0;
|
|
||||||
dc->vmsd = &vmstate_pci_i82378;
|
|
||||||
set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
|
set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
|
||||||
dc->props = i82378_properties;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static const TypeInfo pci_i82378_info = {
|
static const TypeInfo i82378_type_info = {
|
||||||
.name = "i82378",
|
.name = TYPE_I82378,
|
||||||
.parent = TYPE_PCI_DEVICE,
|
.parent = TYPE_PCI_DEVICE,
|
||||||
.instance_size = sizeof(PCIi82378State),
|
.instance_size = sizeof(I82378State),
|
||||||
.class_init = pci_i82378_class_init,
|
.instance_init = i82378_init,
|
||||||
|
.class_init = i82378_class_init,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void i82378_register_types(void)
|
static void i82378_register_types(void)
|
||||||
{
|
{
|
||||||
type_register_static(&pci_i82378_info);
|
type_register_static(&i82378_type_info);
|
||||||
}
|
}
|
||||||
|
|
||||||
type_init(i82378_register_types)
|
type_init(i82378_register_types)
|
||||||
|
|||||||
@@ -289,7 +289,6 @@ static QEMUMachine lm32_evr_machine = {
|
|||||||
.desc = "LatticeMico32 EVR32 eval system",
|
.desc = "LatticeMico32 EVR32 eval system",
|
||||||
.init = lm32_evr_init,
|
.init = lm32_evr_init,
|
||||||
.is_default = 1,
|
.is_default = 1,
|
||||||
DEFAULT_MACHINE_OPTIONS,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static QEMUMachine lm32_uclinux_machine = {
|
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",
|
.desc = "lm32 platform for uClinux and u-boot by Theobroma Systems",
|
||||||
.init = lm32_uclinux_init,
|
.init = lm32_uclinux_init,
|
||||||
.is_default = 0,
|
.is_default = 0,
|
||||||
DEFAULT_MACHINE_OPTIONS,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static void lm32_machine_init(void)
|
static void lm32_machine_init(void)
|
||||||
|
|||||||
@@ -208,7 +208,6 @@ static QEMUMachine milkymist_machine = {
|
|||||||
.desc = "Milkymist One",
|
.desc = "Milkymist One",
|
||||||
.init = milkymist_init,
|
.init = milkymist_init,
|
||||||
.is_default = 0,
|
.is_default = 0,
|
||||||
DEFAULT_MACHINE_OPTIONS,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static void milkymist_machine_init(void)
|
static void milkymist_machine_init(void)
|
||||||
|
|||||||
@@ -89,7 +89,6 @@ static QEMUMachine an5206_machine = {
|
|||||||
.name = "an5206",
|
.name = "an5206",
|
||||||
.desc = "Arnewsh 5206",
|
.desc = "Arnewsh 5206",
|
||||||
.init = an5206_init,
|
.init = an5206_init,
|
||||||
DEFAULT_MACHINE_OPTIONS,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static void an5206_machine_init(void)
|
static void an5206_machine_init(void)
|
||||||
|
|||||||
@@ -73,7 +73,6 @@ static QEMUMachine dummy_m68k_machine = {
|
|||||||
.name = "dummy",
|
.name = "dummy",
|
||||||
.desc = "Dummy board",
|
.desc = "Dummy board",
|
||||||
.init = dummy_m68k_init,
|
.init = dummy_m68k_init,
|
||||||
DEFAULT_MACHINE_OPTIONS,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static void dummy_m68k_machine_init(void)
|
static void dummy_m68k_machine_init(void)
|
||||||
|
|||||||
@@ -295,7 +295,6 @@ static QEMUMachine mcf5208evb_machine = {
|
|||||||
.desc = "MCF5206EVB",
|
.desc = "MCF5206EVB",
|
||||||
.init = mcf5208evb_init,
|
.init = mcf5208evb_init,
|
||||||
.is_default = 1,
|
.is_default = 1,
|
||||||
DEFAULT_MACHINE_OPTIONS,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static void mcf5208evb_machine_init(void)
|
static void mcf5208evb_machine_init(void)
|
||||||
|
|||||||
@@ -186,7 +186,6 @@ static QEMUMachine petalogix_ml605_machine = {
|
|||||||
.desc = "PetaLogix linux refdesign for xilinx ml605 little endian",
|
.desc = "PetaLogix linux refdesign for xilinx ml605 little endian",
|
||||||
.init = petalogix_ml605_init,
|
.init = petalogix_ml605_init,
|
||||||
.is_default = 0,
|
.is_default = 0,
|
||||||
DEFAULT_MACHINE_OPTIONS,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static void petalogix_ml605_machine_init(void)
|
static void petalogix_ml605_machine_init(void)
|
||||||
|
|||||||
@@ -116,7 +116,6 @@ static QEMUMachine petalogix_s3adsp1800_machine = {
|
|||||||
.desc = "PetaLogix linux refdesign for xilinx Spartan 3ADSP1800",
|
.desc = "PetaLogix linux refdesign for xilinx Spartan 3ADSP1800",
|
||||||
.init = petalogix_s3adsp1800_init,
|
.init = petalogix_s3adsp1800_init,
|
||||||
.is_default = 1,
|
.is_default = 1,
|
||||||
DEFAULT_MACHINE_OPTIONS,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static void petalogix_s3adsp1800_machine_init(void)
|
static void petalogix_s3adsp1800_machine_init(void)
|
||||||
|
|||||||
@@ -43,6 +43,8 @@
|
|||||||
#include "hw/timer/i8254.h"
|
#include "hw/timer/i8254.h"
|
||||||
#include "sysemu/blockdev.h"
|
#include "sysemu/blockdev.h"
|
||||||
#include "exec/address-spaces.h"
|
#include "exec/address-spaces.h"
|
||||||
|
#include "sysemu/qtest.h"
|
||||||
|
#include "qemu/error-report.h"
|
||||||
|
|
||||||
#define DEBUG_FULONG2E_INIT
|
#define DEBUG_FULONG2E_INIT
|
||||||
|
|
||||||
@@ -332,8 +334,10 @@ static void mips_fulong2e_init(QEMUMachineInitArgs *args)
|
|||||||
bios_size = -1;
|
bios_size = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((bios_size < 0 || bios_size > BIOS_SIZE) && !kernel_filename) {
|
if ((bios_size < 0 || bios_size > BIOS_SIZE) &&
|
||||||
fprintf(stderr, "qemu: Warning, could not load MIPS bios '%s'\n", bios_name);
|
!kernel_filename && !qtest_enabled()) {
|
||||||
|
error_report("Could not load MIPS bios '%s'", bios_name);
|
||||||
|
exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -399,7 +403,6 @@ static QEMUMachine mips_fulong2e_machine = {
|
|||||||
.name = "fulong2e",
|
.name = "fulong2e",
|
||||||
.desc = "Fulong 2e mini pc",
|
.desc = "Fulong 2e mini pc",
|
||||||
.init = mips_fulong2e_init,
|
.init = mips_fulong2e_init,
|
||||||
DEFAULT_MACHINE_OPTIONS,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static void mips_fulong2e_machine_init(void)
|
static void mips_fulong2e_machine_init(void)
|
||||||
|
|||||||
@@ -42,6 +42,8 @@
|
|||||||
#include "sysemu/blockdev.h"
|
#include "sysemu/blockdev.h"
|
||||||
#include "hw/sysbus.h"
|
#include "hw/sysbus.h"
|
||||||
#include "exec/address-spaces.h"
|
#include "exec/address-spaces.h"
|
||||||
|
#include "sysemu/qtest.h"
|
||||||
|
#include "qemu/error-report.h"
|
||||||
|
|
||||||
enum jazz_model_e
|
enum jazz_model_e
|
||||||
{
|
{
|
||||||
@@ -176,9 +178,9 @@ static void mips_jazz_init(MemoryRegion *address_space,
|
|||||||
} else {
|
} else {
|
||||||
bios_size = -1;
|
bios_size = -1;
|
||||||
}
|
}
|
||||||
if (bios_size < 0 || bios_size > MAGNUM_BIOS_SIZE) {
|
if ((bios_size < 0 || bios_size > MAGNUM_BIOS_SIZE) && !qtest_enabled()) {
|
||||||
fprintf(stderr, "qemu: Warning, could not load MIPS bios '%s'\n",
|
error_report("Could not load MIPS bios '%s'", bios_name);
|
||||||
bios_name);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Init CPU internal devices */
|
/* Init CPU internal devices */
|
||||||
@@ -325,7 +327,6 @@ static QEMUMachine mips_magnum_machine = {
|
|||||||
.desc = "MIPS Magnum",
|
.desc = "MIPS Magnum",
|
||||||
.init = mips_magnum_init,
|
.init = mips_magnum_init,
|
||||||
.block_default_type = IF_SCSI,
|
.block_default_type = IF_SCSI,
|
||||||
DEFAULT_MACHINE_OPTIONS,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static QEMUMachine mips_pica61_machine = {
|
static QEMUMachine mips_pica61_machine = {
|
||||||
@@ -333,7 +334,6 @@ static QEMUMachine mips_pica61_machine = {
|
|||||||
.desc = "Acer Pica 61",
|
.desc = "Acer Pica 61",
|
||||||
.init = mips_pica61_init,
|
.init = mips_pica61_init,
|
||||||
.block_default_type = IF_SCSI,
|
.block_default_type = IF_SCSI,
|
||||||
DEFAULT_MACHINE_OPTIONS,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static void mips_jazz_machine_init(void)
|
static void mips_jazz_machine_init(void)
|
||||||
|
|||||||
@@ -48,6 +48,9 @@
|
|||||||
#include "exec/address-spaces.h"
|
#include "exec/address-spaces.h"
|
||||||
#include "hw/sysbus.h" /* SysBusDevice */
|
#include "hw/sysbus.h" /* SysBusDevice */
|
||||||
#include "qemu/host-utils.h"
|
#include "qemu/host-utils.h"
|
||||||
|
#include "sysemu/qtest.h"
|
||||||
|
#include "qemu/error-report.h"
|
||||||
|
#include "hw/empty_slot.h"
|
||||||
|
|
||||||
//#define DEBUG_BOARD_INIT
|
//#define DEBUG_BOARD_INIT
|
||||||
|
|
||||||
@@ -906,6 +909,11 @@ void mips_malta_init(QEMUMachineInitArgs *args)
|
|||||||
DeviceState *dev = qdev_create(NULL, TYPE_MIPS_MALTA);
|
DeviceState *dev = qdev_create(NULL, TYPE_MIPS_MALTA);
|
||||||
MaltaState *s = MIPS_MALTA(dev);
|
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);
|
qdev_init_nofail(dev);
|
||||||
|
|
||||||
/* Make sure the first 3 serial ports are associated with a device. */
|
/* Make sure the first 3 serial ports are associated with a device. */
|
||||||
@@ -1005,10 +1013,11 @@ void mips_malta_init(QEMUMachineInitArgs *args)
|
|||||||
} else {
|
} else {
|
||||||
bios_size = -1;
|
bios_size = -1;
|
||||||
}
|
}
|
||||||
if ((bios_size < 0 || bios_size > BIOS_SIZE) && !kernel_filename) {
|
if ((bios_size < 0 || bios_size > BIOS_SIZE) &&
|
||||||
fprintf(stderr,
|
!kernel_filename && !qtest_enabled()) {
|
||||||
"qemu: Warning, could not load MIPS bios '%s', and no -kernel argument was specified\n",
|
error_report("Could not load MIPS bios '%s', and no "
|
||||||
bios_name);
|
"-kernel argument was specified", bios_name);
|
||||||
|
exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* In little endian mode the 32bit words in the bios are swapped,
|
/* In little endian mode the 32bit words in the bios are swapped,
|
||||||
@@ -1127,7 +1136,6 @@ static QEMUMachine mips_malta_machine = {
|
|||||||
.init = mips_malta_init,
|
.init = mips_malta_init,
|
||||||
.max_cpus = 16,
|
.max_cpus = 16,
|
||||||
.is_default = 1,
|
.is_default = 1,
|
||||||
DEFAULT_MACHINE_OPTIONS,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static void mips_malta_register_types(void)
|
static void mips_malta_register_types(void)
|
||||||
|
|||||||
@@ -37,6 +37,7 @@
|
|||||||
#include "elf.h"
|
#include "elf.h"
|
||||||
#include "hw/sysbus.h"
|
#include "hw/sysbus.h"
|
||||||
#include "exec/address-spaces.h"
|
#include "exec/address-spaces.h"
|
||||||
|
#include "qemu/error-report.h"
|
||||||
|
|
||||||
static struct _loaderparams {
|
static struct _loaderparams {
|
||||||
int ram_size;
|
int ram_size;
|
||||||
@@ -191,9 +192,9 @@ mips_mipssim_init(QEMUMachineInitArgs *args)
|
|||||||
}
|
}
|
||||||
if ((bios_size < 0 || bios_size > BIOS_SIZE) && !kernel_filename) {
|
if ((bios_size < 0 || bios_size > BIOS_SIZE) && !kernel_filename) {
|
||||||
/* Bail out if we have neither a kernel image nor boot vector code. */
|
/* Bail out if we have neither a kernel image nor boot vector code. */
|
||||||
fprintf(stderr,
|
error_report("Could not load MIPS bios '%s', and no "
|
||||||
"qemu: Warning, could not load MIPS bios '%s', and no -kernel argument was specified\n",
|
"-kernel argument was specified", filename);
|
||||||
filename);
|
exit(1);
|
||||||
} else {
|
} else {
|
||||||
/* We have a boot vector start address. */
|
/* We have a boot vector start address. */
|
||||||
env->active_tc.PC = (target_long)(int32_t)0xbfc00000;
|
env->active_tc.PC = (target_long)(int32_t)0xbfc00000;
|
||||||
@@ -231,7 +232,6 @@ static QEMUMachine mips_mipssim_machine = {
|
|||||||
.name = "mipssim",
|
.name = "mipssim",
|
||||||
.desc = "MIPS MIPSsim platform",
|
.desc = "MIPS MIPSsim platform",
|
||||||
.init = mips_mipssim_init,
|
.init = mips_mipssim_init,
|
||||||
DEFAULT_MACHINE_OPTIONS,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static void mips_mipssim_machine_init(void)
|
static void mips_mipssim_machine_init(void)
|
||||||
|
|||||||
@@ -26,6 +26,7 @@
|
|||||||
#include "hw/timer/i8254.h"
|
#include "hw/timer/i8254.h"
|
||||||
#include "sysemu/blockdev.h"
|
#include "sysemu/blockdev.h"
|
||||||
#include "exec/address-spaces.h"
|
#include "exec/address-spaces.h"
|
||||||
|
#include "sysemu/qtest.h"
|
||||||
|
|
||||||
#define MAX_IDE_BUS 2
|
#define MAX_IDE_BUS 2
|
||||||
|
|
||||||
@@ -244,8 +245,7 @@ void mips_r4k_init(QEMUMachineInitArgs *args)
|
|||||||
4, 0, 0, 0, 0, be)) {
|
4, 0, 0, 0, 0, be)) {
|
||||||
fprintf(stderr, "qemu: Error registering flash memory.\n");
|
fprintf(stderr, "qemu: Error registering flash memory.\n");
|
||||||
}
|
}
|
||||||
}
|
} else if (!qtest_enabled()) {
|
||||||
else {
|
|
||||||
/* not fatal */
|
/* not fatal */
|
||||||
fprintf(stderr, "qemu: Warning, could not load MIPS bios '%s'\n",
|
fprintf(stderr, "qemu: Warning, could not load MIPS bios '%s'\n",
|
||||||
bios_name);
|
bios_name);
|
||||||
@@ -306,7 +306,6 @@ static QEMUMachine mips_machine = {
|
|||||||
.name = "mips",
|
.name = "mips",
|
||||||
.desc = "mips r4k platform",
|
.desc = "mips r4k platform",
|
||||||
.init = mips_r4k_init,
|
.init = mips_r4k_init,
|
||||||
DEFAULT_MACHINE_OPTIONS,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static void mips_machine_init(void)
|
static void mips_machine_init(void)
|
||||||
|
|||||||
@@ -97,29 +97,24 @@ static void pvpanic_isa_realizefn(DeviceState *dev, Error **errp)
|
|||||||
{
|
{
|
||||||
ISADevice *d = ISA_DEVICE(dev);
|
ISADevice *d = ISA_DEVICE(dev);
|
||||||
PVPanicState *s = ISA_PVPANIC_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);
|
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)
|
void pvpanic_init(ISABus *bus)
|
||||||
{
|
{
|
||||||
ISADevice *dev;
|
isa_create_simple(bus, TYPE_ISA_PVPANIC_DEVICE);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static Property pvpanic_isa_properties[] = {
|
static Property pvpanic_isa_properties[] = {
|
||||||
@@ -132,8 +127,8 @@ static void pvpanic_isa_class_init(ObjectClass *klass, void *data)
|
|||||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||||
|
|
||||||
dc->realize = pvpanic_isa_realizefn;
|
dc->realize = pvpanic_isa_realizefn;
|
||||||
dc->no_user = 1;
|
|
||||||
dc->props = pvpanic_isa_properties;
|
dc->props = pvpanic_isa_properties;
|
||||||
|
set_bit(DEVICE_CATEGORY_MISC, dc->categories);
|
||||||
}
|
}
|
||||||
|
|
||||||
static TypeInfo pvpanic_isa_info = {
|
static TypeInfo pvpanic_isa_info = {
|
||||||
|
|||||||
@@ -861,6 +861,8 @@ static void pcnet_init(PCNetState *s)
|
|||||||
|
|
||||||
s->csr[0] |= 0x0101;
|
s->csr[0] |= 0x0101;
|
||||||
s->csr[0] &= ~0x0004; /* clear STOP bit */
|
s->csr[0] &= ~0x0004; /* clear STOP bit */
|
||||||
|
|
||||||
|
qemu_flush_queued_packets(qemu_get_queue(s->nic));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pcnet_start(PCNetState *s)
|
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] &= ~0x0004; /* clear STOP bit */
|
||||||
s->csr[0] |= 0x0002;
|
s->csr[0] |= 0x0002;
|
||||||
pcnet_poll_timer(s);
|
pcnet_poll_timer(s);
|
||||||
|
|
||||||
|
qemu_flush_queued_packets(qemu_get_queue(s->nic));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pcnet_stop(PCNetState *s)
|
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 = {
|
static const MemoryRegionOps fw_cfg_comb_mem_ops = {
|
||||||
.read = fw_cfg_comb_read,
|
.read = fw_cfg_comb_read,
|
||||||
.write = fw_cfg_comb_write,
|
.write = fw_cfg_comb_write,
|
||||||
.endianness = DEVICE_NATIVE_ENDIAN,
|
.endianness = DEVICE_LITTLE_ENDIAN,
|
||||||
.valid.accepts = fw_cfg_comb_valid,
|
.valid.accepts = fw_cfg_comb_valid,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -139,7 +139,6 @@ static QEMUMachine openrisc_sim_machine = {
|
|||||||
.init = openrisc_sim_init,
|
.init = openrisc_sim_init,
|
||||||
.max_cpus = 1,
|
.max_cpus = 1,
|
||||||
.is_default = 1,
|
.is_default = 1,
|
||||||
DEFAULT_MACHINE_OPTIONS,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static void openrisc_sim_machine_init(void)
|
static void openrisc_sim_machine_init(void)
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user