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