Compare commits
241 Commits
pull-input
...
pull-vnc-2
Author | SHA1 | Date | |
---|---|---|---|
|
2f487a3d40 | ||
|
315b593441 | ||
|
cdf0592cb8 | ||
|
4f3ed190a6 | ||
|
b074e62205 | ||
|
7b53f2940e | ||
|
0a1bec8a4e | ||
|
cab0a7ea00 | ||
|
7ea5d7256d | ||
|
a8b12c108c | ||
|
eef0d9e740 | ||
|
a9c7d27bd1 | ||
|
1d0a60681a | ||
|
5f9eb02555 | ||
|
c8fc56cedd | ||
|
aad2f06a7f | ||
|
d801a8f2ce | ||
|
e7bc9004e7 | ||
|
87f6396293 | ||
|
2bda66028b | ||
|
298526fe92 | ||
|
881249c792 | ||
|
087edb503a | ||
|
025172d56e | ||
|
83d1c8ae88 | ||
|
0c544d73bb | ||
|
6295b98d7b | ||
|
f4b11eee2f | ||
|
6fffa26244 | ||
|
e638308097 | ||
|
9c749e4dbe | ||
|
379e21c258 | ||
|
a00f66ab9b | ||
|
69df1c3c9d | ||
|
6d4adef48d | ||
|
3b163b0165 | ||
|
f214530f56 | ||
|
9d5614d582 | ||
|
39d16d29c8 | ||
|
cc13eead53 | ||
|
86c3b20a5f | ||
|
6d585ca559 | ||
|
dfb3804d47 | ||
|
4191d0eb41 | ||
|
03d51428e2 | ||
|
582ab779c5 | ||
|
8678b71ce6 | ||
|
1fcc9ddfb3 | ||
|
c6e929e784 | ||
|
b3c56df769 | ||
|
ed7a0aa8bc | ||
|
04ce397b33 | ||
|
14b155ddc4 | ||
|
e029f29385 | ||
|
90f1cd9138 | ||
|
7d11fc7c2b | ||
|
096c46c0ff | ||
|
df9351e372 | ||
|
50573c66eb | ||
|
46dea4160d | ||
|
dc668ded10 | ||
|
1e8ece0db3 | ||
|
4a41a2d68a | ||
|
62e466e845 | ||
|
c3adb58fe0 | ||
|
aa7a6a399f | ||
|
2e323f03bf | ||
|
22956a3755 | ||
|
5d92c74f8a | ||
|
b19fc63cad | ||
|
90c5d39cb8 | ||
|
01c22f2cdd | ||
|
cb201b4872 | ||
|
f33f991185 | ||
|
be21c33616 | ||
|
8bf0975902 | ||
|
7effdaa321 | ||
|
d44229c54f | ||
|
d0b2542574 | ||
|
4c1410d59c | ||
|
bbbd67f0cc | ||
|
2ef1f68d4f | ||
|
0c591eb0a9 | ||
|
00c8cb0a36 | ||
|
31b030d4ab | ||
|
0063ebd6ac | ||
|
0dd106c5f0 | ||
|
a47dddd734 | ||
|
d7f0a59ff0 | ||
|
bb0e627a84 | ||
|
baea4fae7b | ||
|
0ea8cb8895 | ||
|
b3310ab338 | ||
|
75a34036d4 | ||
|
d0e39c5d70 | ||
|
611d4f996f | ||
|
648f034c6c | ||
|
90b40a696a | ||
|
239c51a54f | ||
|
74f10515d1 | ||
|
3f38f309b2 | ||
|
5638d180d6 | ||
|
d5a11fefef | ||
|
f0c3c505a8 | ||
|
ff4700b05c | ||
|
0429a97195 | ||
|
27103424c4 | ||
|
6f03bef0ff | ||
|
8cd70437f3 | ||
|
28ecfd7a62 | ||
|
efee734004 | ||
|
99df7dce8a | ||
|
93afeade09 | ||
|
7510454e3e | ||
|
7372c2b926 | ||
|
9262685b81 | ||
|
1590bbcb02 | ||
|
247bf011f6 | ||
|
433ac7a968 | ||
|
db5d39f786 | ||
|
94a444b295 | ||
|
d940ee9b78 | ||
|
500050d1e0 | ||
|
ef02ef5f45 | ||
|
8fb4f821e9 | ||
|
5fcca9ff3b | ||
|
74f54bc4ba | ||
|
9576de7573 | ||
|
285f025d2c | ||
|
c080e30ec8 | ||
|
8c2e1b0093 | ||
|
1cf5ccbca8 | ||
|
62864712b3 | ||
|
2fad1112db | ||
|
2efc6be2ea | ||
|
33276f1b9c | ||
|
19d6ca16d9 | ||
|
70d74660e7 | ||
|
d2810ffd34 | ||
|
9d111183d5 | ||
|
4a9a1f49c5 | ||
|
57fac92c2d | ||
|
41975b269c | ||
|
57ed25b1b0 | ||
|
cc28c6aa46 | ||
|
18fa1c42a3 | ||
|
d3f4984583 | ||
|
7af803d4f8 | ||
|
f988388025 | ||
|
9562f69cfd | ||
|
27eb6c097c | ||
|
d475e5acd2 | ||
|
dc3dd0d2be | ||
|
88eb7c29e4 | ||
|
48ff269272 | ||
|
6e4a876b43 | ||
|
7d1de46448 | ||
|
be8d853766 | ||
|
98563fc3ec | ||
|
2da61b671e | ||
|
11f590b1a2 | ||
|
b5042a3622 | ||
|
98d39e34fe | ||
|
938789ea92 | ||
|
dba2855572 | ||
|
3456a8d185 | ||
|
26d49c4675 | ||
|
be86c53c05 | ||
|
c8d146aecc | ||
|
0100f42550 | ||
|
ac1b84dd1e | ||
|
295d51aa6a | ||
|
c6ba42f6bc | ||
|
fb0e843a11 | ||
|
8f3babb74d | ||
|
7a1a4dac94 | ||
|
602a3921ff | ||
|
f8762027a3 | ||
|
d2f69df746 | ||
|
5c21ce77d7 | ||
|
02e7f85dac | ||
|
04e9a20b49 | ||
|
2ef66625f3 | ||
|
0399a3819b | ||
|
6e8114a065 | ||
|
aa97405e32 | ||
|
26c9a015ef | ||
|
b6f46f02f4 | ||
|
02063aaa65 | ||
|
c7a59bed62 | ||
|
83bb0b2ffd | ||
|
dc06cbd286 | ||
|
0056ae24bc | ||
|
261747f176 | ||
|
36d20cb2b3 | ||
|
49649f23db | ||
|
a3d7cbc139 | ||
|
1b8601b0ea | ||
|
cdccf7d7e7 | ||
|
1f760d5f2b | ||
|
7c77b654c5 | ||
|
5ef4a1c304 | ||
|
d43269dddc | ||
|
1a7d9ee6dd | ||
|
a01aedc8d3 | ||
|
7b0309490c | ||
|
267a3264cd | ||
|
2b81b35f8f | ||
|
750036a848 | ||
|
2f23e9ae2c | ||
|
21143b615a | ||
|
fd3ece2533 | ||
|
a822837d12 | ||
|
01ac27ce7f | ||
|
84f3fe1b07 | ||
|
2c3445bb85 | ||
|
7602e3e4a3 | ||
|
613c12ec28 | ||
|
dc9528fdf9 | ||
|
68e5ec6400 | ||
|
5c1e1890bf | ||
|
c2804ee6c0 | ||
|
16c358e96e | ||
|
be813ef02d | ||
|
2a7a1a56d1 | ||
|
5d371f41b4 | ||
|
5223070c47 | ||
|
59ca664ef8 | ||
|
bceae7697f | ||
|
b0b58195e4 | ||
|
6299659f54 | ||
|
b86b05ed60 | ||
|
515b943a91 | ||
|
4b35991a3b | ||
|
dad1fcab91 | ||
|
13f65b2e10 | ||
|
b4e5a4bffd | ||
|
263cf4367f | ||
|
dc65540465 | ||
|
ac41881b48 | ||
|
98bc3ab0f2 |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -21,6 +21,7 @@
|
||||
libdis*
|
||||
libuser
|
||||
/linux-headers/asm
|
||||
/qga/qapi-generated
|
||||
/qapi-generated
|
||||
/qapi-types.[ch]
|
||||
/qapi-visit.[ch]
|
||||
|
3
.gitmodules
vendored
3
.gitmodules
vendored
@@ -13,6 +13,9 @@
|
||||
[submodule "roms/openbios"]
|
||||
path = roms/openbios
|
||||
url = git://git.qemu-project.org/openbios.git
|
||||
[submodule "roms/openhackware"]
|
||||
path = roms/openhackware
|
||||
url = git://git.qemu-project.org/openhackware.git
|
||||
[submodule "roms/qemu-palcode"]
|
||||
path = roms/qemu-palcode
|
||||
url = git://github.com/rth7680/qemu-palcode.git
|
||||
|
53
.travis.yml
53
.travis.yml
@@ -4,6 +4,12 @@ python:
|
||||
compiler:
|
||||
- gcc
|
||||
- clang
|
||||
notifications:
|
||||
irc:
|
||||
channels:
|
||||
- "irc.oftc.net#qemu"
|
||||
on_success: change
|
||||
on_failure: always
|
||||
env:
|
||||
global:
|
||||
- TEST_CMD="make check"
|
||||
@@ -14,23 +20,23 @@ env:
|
||||
- GUI_PKGS="libgtk-3-dev libvte-2.90-dev libsdl1.2-dev libpng12-dev libpixman-1-dev"
|
||||
- EXTRA_PKGS=""
|
||||
matrix:
|
||||
- TARGETS=alpha-softmmu,alpha-linux-user
|
||||
- TARGETS=arm-softmmu,arm-linux-user
|
||||
- TARGETS=aarch64-softmmu,aarch64-linux-user
|
||||
- TARGETS=cris-softmmu
|
||||
- TARGETS=i386-softmmu,x86_64-softmmu
|
||||
- TARGETS=lm32-softmmu
|
||||
- TARGETS=m68k-softmmu
|
||||
- TARGETS=microblaze-softmmu,microblazeel-softmmu
|
||||
- TARGETS=mips-softmmu,mips64-softmmu,mips64el-softmmu,mipsel-softmmu
|
||||
- TARGETS=moxie-softmmu
|
||||
- TARGETS=or32-softmmu,
|
||||
- TARGETS=ppc-softmmu,ppc64-softmmu,ppcemb-softmmu
|
||||
- TARGETS=s390x-softmmu
|
||||
- TARGETS=sh4-softmmu,sh4eb-softmmu
|
||||
- TARGETS=sparc-softmmu,sparc64-softmmu
|
||||
- TARGETS=unicore32-softmmu
|
||||
- TARGETS=xtensa-softmmu,xtensaeb-softmmu
|
||||
- TARGETS=alpha-softmmu,alpha-linux-user
|
||||
- TARGETS=arm-softmmu,arm-linux-user
|
||||
- TARGETS=aarch64-softmmu,aarch64-linux-user
|
||||
- TARGETS=cris-softmmu
|
||||
- TARGETS=i386-softmmu,x86_64-softmmu
|
||||
- TARGETS=lm32-softmmu
|
||||
- TARGETS=m68k-softmmu
|
||||
- TARGETS=microblaze-softmmu,microblazeel-softmmu
|
||||
- TARGETS=mips-softmmu,mips64-softmmu,mips64el-softmmu,mipsel-softmmu
|
||||
- TARGETS=moxie-softmmu
|
||||
- TARGETS=or32-softmmu,
|
||||
- TARGETS=ppc-softmmu,ppc64-softmmu,ppcemb-softmmu
|
||||
- TARGETS=s390x-softmmu
|
||||
- TARGETS=sh4-softmmu,sh4eb-softmmu
|
||||
- TARGETS=sparc-softmmu,sparc64-softmmu
|
||||
- TARGETS=unicore32-softmmu
|
||||
- TARGETS=xtensa-softmmu,xtensaeb-softmmu
|
||||
before_install:
|
||||
- git submodule update --init --recursive
|
||||
- sudo apt-get update -qq
|
||||
@@ -46,6 +52,10 @@ matrix:
|
||||
- env: TARGETS=i386-softmmu,x86_64-softmmu
|
||||
EXTRA_CONFIG="--enable-debug --enable-tcg-interpreter"
|
||||
compiler: gcc
|
||||
# All the extra -dev packages
|
||||
- env: TARGETS=i386-softmmu,x86_64-softmmu
|
||||
EXTRA_PKGS="libaio-dev libcap-ng-dev libattr1-dev libbrlapi-dev uuid-dev libusb-1.0.0-dev"
|
||||
compiler: gcc
|
||||
# Currently configure doesn't force --disable-pie
|
||||
- env: TARGETS=i386-softmmu,x86_64-softmmu
|
||||
EXTRA_CONFIG="--enable-gprof --enable-gcov --disable-pie"
|
||||
@@ -65,8 +75,7 @@ matrix:
|
||||
EXTRA_CONFIG="--enable-trace-backend=ftrace"
|
||||
TEST_CMD=""
|
||||
compiler: gcc
|
||||
# This disabled make check for the ftrace backend which needs more setting up
|
||||
# Currently broken on 12.04 due to mis-packaged liburcu and changed API, will be pulled.
|
||||
#- env: TARGETS=i386-softmmu,x86_64-softmmu
|
||||
# EXTRA_PKGS="liblttng-ust-dev liburcu-dev"
|
||||
# EXTRA_CONFIG="--enable-trace-backend=ust"
|
||||
- env: TARGETS=i386-softmmu,x86_64-softmmu
|
||||
EXTRA_PKGS="liblttng-ust-dev liburcu-dev"
|
||||
EXTRA_CONFIG="--enable-trace-backend=ust"
|
||||
compiler: gcc
|
||||
|
5
Makefile
5
Makefile
@@ -265,10 +265,7 @@ clean:
|
||||
# avoid old build problems by removing potentially incorrect old files
|
||||
rm -f config.mak op-i386.h opc-i386.h gen-op-i386.h op-arm.h opc-arm.h gen-op-arm.h
|
||||
rm -f qemu-options.def
|
||||
find . -name '*.[oda]' -type f -exec rm -f {} +
|
||||
find . -name '*.l[oa]' -type f -exec rm -f {} +
|
||||
find . -name '*$(DSOSUF)' -type f -exec rm -f {} +
|
||||
find . -name '*.mo' -type f -exec rm -f {} +
|
||||
find . \( -name '*.l[oa]' -o -name '*.so' -o -name '*.dll' -o -name '*.mo' -o -name '*.[oda]' \) -type f -exec rm {} +
|
||||
rm -f $(filter-out %.tlb,$(TOOLS)) $(HELPERS-y) qemu-ga TAGS cscope.* *.pod *~ */*~
|
||||
rm -f fsdev/*.pod
|
||||
rm -rf .libs */.libs
|
||||
|
@@ -39,6 +39,7 @@ libcacard-y += libcacard/vcardt.o
|
||||
|
||||
ifeq ($(CONFIG_SOFTMMU),y)
|
||||
common-obj-y = blockdev.o blockdev-nbd.o block/
|
||||
common-obj-y += iothread.o
|
||||
common-obj-y += net/
|
||||
common-obj-y += qdev-monitor.o device-hotplug.o
|
||||
common-obj-$(CONFIG_WIN32) += os-win32.o
|
||||
|
18
async.c
18
async.c
@@ -214,6 +214,7 @@ aio_ctx_finalize(GSource *source)
|
||||
thread_pool_free(ctx->thread_pool);
|
||||
aio_set_event_notifier(ctx, &ctx->notifier, NULL);
|
||||
event_notifier_cleanup(&ctx->notifier);
|
||||
rfifolock_destroy(&ctx->lock);
|
||||
qemu_mutex_destroy(&ctx->bh_lock);
|
||||
g_array_free(ctx->pollfds, TRUE);
|
||||
timerlistgroup_deinit(&ctx->tlg);
|
||||
@@ -250,6 +251,12 @@ static void aio_timerlist_notify(void *opaque)
|
||||
aio_notify(opaque);
|
||||
}
|
||||
|
||||
static void aio_rfifolock_cb(void *opaque)
|
||||
{
|
||||
/* Kick owner thread in case they are blocked in aio_poll() */
|
||||
aio_notify(opaque);
|
||||
}
|
||||
|
||||
AioContext *aio_context_new(void)
|
||||
{
|
||||
AioContext *ctx;
|
||||
@@ -257,6 +264,7 @@ AioContext *aio_context_new(void)
|
||||
ctx->pollfds = g_array_new(FALSE, FALSE, sizeof(GPollFD));
|
||||
ctx->thread_pool = NULL;
|
||||
qemu_mutex_init(&ctx->bh_lock);
|
||||
rfifolock_init(&ctx->lock, aio_rfifolock_cb, ctx);
|
||||
event_notifier_init(&ctx->notifier, false);
|
||||
aio_set_event_notifier(ctx, &ctx->notifier,
|
||||
(EventNotifierHandler *)
|
||||
@@ -275,3 +283,13 @@ void aio_context_unref(AioContext *ctx)
|
||||
{
|
||||
g_source_unref(&ctx->source);
|
||||
}
|
||||
|
||||
void aio_context_acquire(AioContext *ctx)
|
||||
{
|
||||
rfifolock_lock(&ctx->lock);
|
||||
}
|
||||
|
||||
void aio_context_release(AioContext *ctx)
|
||||
{
|
||||
rfifolock_unlock(&ctx->lock);
|
||||
}
|
||||
|
80
block.c
80
block.c
@@ -1321,7 +1321,7 @@ int bdrv_open(BlockDriverState **pbs, const char *filename,
|
||||
bdrv_open_flags(bs, flags | BDRV_O_UNMAP) |
|
||||
BDRV_O_PROTOCOL, true, &local_err);
|
||||
if (ret < 0) {
|
||||
goto fail;
|
||||
goto unlink_and_fail;
|
||||
}
|
||||
|
||||
/* Find the right image format driver */
|
||||
@@ -1388,12 +1388,19 @@ done:
|
||||
ret = -EINVAL;
|
||||
goto close_and_fail;
|
||||
}
|
||||
QDECREF(options);
|
||||
|
||||
if (!bdrv_key_required(bs)) {
|
||||
bdrv_dev_change_media_cb(bs, true);
|
||||
} else if (!runstate_check(RUN_STATE_PRELAUNCH)
|
||||
&& !runstate_check(RUN_STATE_INMIGRATE)
|
||||
&& !runstate_check(RUN_STATE_PAUSED)) { /* HACK */
|
||||
error_setg(errp,
|
||||
"Guest must be stopped for opening of encrypted image");
|
||||
ret = -EBUSY;
|
||||
goto close_and_fail;
|
||||
}
|
||||
|
||||
QDECREF(options);
|
||||
*pbs = bs;
|
||||
return 0;
|
||||
|
||||
@@ -4055,7 +4062,7 @@ int bdrv_debug_remove_breakpoint(BlockDriverState *bs, const char *tag)
|
||||
|
||||
int bdrv_debug_resume(BlockDriverState *bs, const char *tag)
|
||||
{
|
||||
while (bs && bs->drv && !bs->drv->bdrv_debug_resume) {
|
||||
while (bs && (!bs->drv || !bs->drv->bdrv_debug_resume)) {
|
||||
bs = bs->file;
|
||||
}
|
||||
|
||||
@@ -4776,9 +4783,17 @@ flush_parent:
|
||||
|
||||
void bdrv_invalidate_cache(BlockDriverState *bs)
|
||||
{
|
||||
if (bs->drv && bs->drv->bdrv_invalidate_cache) {
|
||||
bs->drv->bdrv_invalidate_cache(bs);
|
||||
if (!bs->drv) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (bs->drv->bdrv_invalidate_cache) {
|
||||
bs->drv->bdrv_invalidate_cache(bs);
|
||||
} else if (bs->file) {
|
||||
bdrv_invalidate_cache(bs->file);
|
||||
}
|
||||
|
||||
refresh_total_sectors(bs, bs->total_sectors);
|
||||
}
|
||||
|
||||
void bdrv_invalidate_cache_all(void)
|
||||
@@ -5390,43 +5405,37 @@ int bdrv_amend_options(BlockDriverState *bs, QEMUOptionParameter *options)
|
||||
return bs->drv->bdrv_amend_options(bs, options);
|
||||
}
|
||||
|
||||
/* Used to recurse on single child block filters.
|
||||
* Single child block filter will store their child in bs->file.
|
||||
/* This function will be called by the bdrv_recurse_is_first_non_filter method
|
||||
* of block filter and by bdrv_is_first_non_filter.
|
||||
* It is used to test if the given bs is the candidate or recurse more in the
|
||||
* node graph.
|
||||
*/
|
||||
bool bdrv_generic_is_first_non_filter(BlockDriverState *bs,
|
||||
BlockDriverState *candidate)
|
||||
{
|
||||
if (!bs->drv) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!bs->drv->authorizations[BS_IS_A_FILTER]) {
|
||||
if (bs == candidate) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!bs->drv->authorizations[BS_FILTER_PASS_DOWN]) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!bs->file) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return bdrv_recurse_is_first_non_filter(bs->file, candidate);
|
||||
}
|
||||
|
||||
bool bdrv_recurse_is_first_non_filter(BlockDriverState *bs,
|
||||
BlockDriverState *candidate)
|
||||
{
|
||||
if (bs->drv && bs->drv->bdrv_recurse_is_first_non_filter) {
|
||||
/* return false if basic checks fails */
|
||||
if (!bs || !bs->drv) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* the code reached a non block filter driver -> check if the bs is
|
||||
* the same as the candidate. It's the recursion termination condition.
|
||||
*/
|
||||
if (!bs->drv->is_filter) {
|
||||
return bs == candidate;
|
||||
}
|
||||
/* Down this path the driver is a block filter driver */
|
||||
|
||||
/* If the block filter recursion method is defined use it to recurse down
|
||||
* the node graph.
|
||||
*/
|
||||
if (bs->drv->bdrv_recurse_is_first_non_filter) {
|
||||
return bs->drv->bdrv_recurse_is_first_non_filter(bs, candidate);
|
||||
}
|
||||
|
||||
return bdrv_generic_is_first_non_filter(bs, candidate);
|
||||
/* the driver is a block filter but don't allow to recurse -> return false
|
||||
*/
|
||||
return false;
|
||||
}
|
||||
|
||||
/* This function checks if the candidate is the first non filter bs down it's
|
||||
@@ -5441,6 +5450,7 @@ bool bdrv_is_first_non_filter(BlockDriverState *candidate)
|
||||
QTAILQ_FOREACH(bs, &bdrv_states, device_list) {
|
||||
bool perm;
|
||||
|
||||
/* try to recurse in this top level bs */
|
||||
perm = bdrv_recurse_is_first_non_filter(bs, candidate);
|
||||
|
||||
/* candidate is the first non filter */
|
||||
|
@@ -288,6 +288,20 @@ static BlockDriverAIOCB *blkverify_aio_flush(BlockDriverState *bs,
|
||||
return bdrv_aio_flush(s->test_file, cb, opaque);
|
||||
}
|
||||
|
||||
static bool blkverify_recurse_is_first_non_filter(BlockDriverState *bs,
|
||||
BlockDriverState *candidate)
|
||||
{
|
||||
BDRVBlkverifyState *s = bs->opaque;
|
||||
|
||||
bool perm = bdrv_recurse_is_first_non_filter(bs->file, candidate);
|
||||
|
||||
if (perm) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return bdrv_recurse_is_first_non_filter(s->test_file, candidate);
|
||||
}
|
||||
|
||||
static BlockDriver bdrv_blkverify = {
|
||||
.format_name = "blkverify",
|
||||
.protocol_name = "blkverify",
|
||||
@@ -302,7 +316,8 @@ static BlockDriver bdrv_blkverify = {
|
||||
.bdrv_aio_writev = blkverify_aio_writev,
|
||||
.bdrv_aio_flush = blkverify_aio_flush,
|
||||
|
||||
.authorizations = { true, false },
|
||||
.is_filter = true,
|
||||
.bdrv_recurse_is_first_non_filter = blkverify_recurse_is_first_non_filter,
|
||||
};
|
||||
|
||||
static void bdrv_blkverify_init(void)
|
||||
|
@@ -43,6 +43,17 @@ static void nbd_recv_coroutines_enter_all(NbdClientSession *s)
|
||||
}
|
||||
}
|
||||
|
||||
static void nbd_teardown_connection(NbdClientSession *client)
|
||||
{
|
||||
/* finish any pending coroutines */
|
||||
shutdown(client->sock, 2);
|
||||
nbd_recv_coroutines_enter_all(client);
|
||||
|
||||
qemu_aio_set_fd_handler(client->sock, NULL, NULL, NULL);
|
||||
closesocket(client->sock);
|
||||
client->sock = -1;
|
||||
}
|
||||
|
||||
static void nbd_reply_ready(void *opaque)
|
||||
{
|
||||
NbdClientSession *s = opaque;
|
||||
@@ -78,7 +89,7 @@ static void nbd_reply_ready(void *opaque)
|
||||
}
|
||||
|
||||
fail:
|
||||
nbd_recv_coroutines_enter_all(s);
|
||||
nbd_teardown_connection(s);
|
||||
}
|
||||
|
||||
static void nbd_restart_write(void *opaque)
|
||||
@@ -324,7 +335,7 @@ int nbd_client_session_co_discard(NbdClientSession *client, int64_t sector_num,
|
||||
|
||||
}
|
||||
|
||||
static void nbd_teardown_connection(NbdClientSession *client)
|
||||
void nbd_client_session_close(NbdClientSession *client)
|
||||
{
|
||||
struct nbd_request request = {
|
||||
.type = NBD_CMD_DISC,
|
||||
@@ -332,22 +343,14 @@ static void nbd_teardown_connection(NbdClientSession *client)
|
||||
.len = 0
|
||||
};
|
||||
|
||||
nbd_send_request(client->sock, &request);
|
||||
|
||||
/* finish any pending coroutines */
|
||||
shutdown(client->sock, 2);
|
||||
nbd_recv_coroutines_enter_all(client);
|
||||
|
||||
qemu_aio_set_fd_handler(client->sock, NULL, NULL, NULL);
|
||||
closesocket(client->sock);
|
||||
client->sock = -1;
|
||||
}
|
||||
|
||||
void nbd_client_session_close(NbdClientSession *client)
|
||||
{
|
||||
if (!client->bs) {
|
||||
return;
|
||||
}
|
||||
if (client->sock == -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
nbd_send_request(client->sock, &request);
|
||||
|
||||
nbd_teardown_connection(client);
|
||||
client->bs = NULL;
|
||||
|
@@ -380,6 +380,10 @@ static int coroutine_fn copy_sectors(BlockDriverState *bs,
|
||||
|
||||
BLKDBG_EVENT(bs->file, BLKDBG_COW_READ);
|
||||
|
||||
if (!bs->drv) {
|
||||
return -ENOMEDIUM;
|
||||
}
|
||||
|
||||
/* Call .bdrv_co_readv() directly instead of using the public block-layer
|
||||
* interface. This avoids double I/O throttling and request tracking,
|
||||
* which can lead to deadlock when block layer copy-on-read is enabled.
|
||||
|
@@ -96,7 +96,8 @@ static int get_refcount(BlockDriverState *bs, int64_t cluster_index)
|
||||
refcount_table_index = cluster_index >> (s->cluster_bits - REFCOUNT_SHIFT);
|
||||
if (refcount_table_index >= s->refcount_table_size)
|
||||
return 0;
|
||||
refcount_block_offset = s->refcount_table[refcount_table_index];
|
||||
refcount_block_offset =
|
||||
s->refcount_table[refcount_table_index] & REFT_OFFSET_MASK;
|
||||
if (!refcount_block_offset)
|
||||
return 0;
|
||||
|
||||
|
@@ -644,7 +644,7 @@ static int qcow2_open(BlockDriverState *bs, QDict *options, int flags,
|
||||
}
|
||||
|
||||
/* Clear unknown autoclear feature bits */
|
||||
if (!bs->read_only && s->autoclear_features != 0) {
|
||||
if (!bs->read_only && !(flags & BDRV_O_INCOMING) && s->autoclear_features) {
|
||||
s->autoclear_features = 0;
|
||||
ret = qcow2_update_header(bs);
|
||||
if (ret < 0) {
|
||||
@@ -657,7 +657,7 @@ static int qcow2_open(BlockDriverState *bs, QDict *options, int flags,
|
||||
qemu_co_mutex_init(&s->lock);
|
||||
|
||||
/* Repair image if dirty */
|
||||
if (!(flags & BDRV_O_CHECK) && !bs->read_only &&
|
||||
if (!(flags & (BDRV_O_CHECK | BDRV_O_INCOMING)) && !bs->read_only &&
|
||||
(s->incompatible_features & QCOW2_INCOMPAT_DIRTY)) {
|
||||
BdrvCheckResult result = {0};
|
||||
|
||||
@@ -1137,10 +1137,12 @@ static void qcow2_close(BlockDriverState *bs)
|
||||
/* else pre-write overlap checks in cache_destroy may crash */
|
||||
s->l1_table = NULL;
|
||||
|
||||
qcow2_cache_flush(bs, s->l2_table_cache);
|
||||
qcow2_cache_flush(bs, s->refcount_block_cache);
|
||||
if (!(bs->open_flags & BDRV_O_INCOMING)) {
|
||||
qcow2_cache_flush(bs, s->l2_table_cache);
|
||||
qcow2_cache_flush(bs, s->refcount_block_cache);
|
||||
|
||||
qcow2_mark_clean(bs);
|
||||
qcow2_mark_clean(bs);
|
||||
}
|
||||
|
||||
qcow2_cache_destroy(bs, s->l2_table_cache);
|
||||
qcow2_cache_destroy(bs, s->refcount_block_cache);
|
||||
@@ -1176,11 +1178,10 @@ static void qcow2_invalidate_cache(BlockDriverState *bs)
|
||||
|
||||
qcow2_close(bs);
|
||||
|
||||
options = qdict_new();
|
||||
qdict_put(options, QCOW2_OPT_LAZY_REFCOUNTS,
|
||||
qbool_from_int(s->use_lazy_refcounts));
|
||||
bdrv_invalidate_cache(bs->file);
|
||||
|
||||
memset(s, 0, sizeof(BDRVQcowState));
|
||||
options = qdict_clone_shallow(bs->options);
|
||||
qcow2_open(bs, options, flags, NULL);
|
||||
|
||||
QDECREF(options);
|
||||
|
@@ -1563,6 +1563,9 @@ static void bdrv_qed_invalidate_cache(BlockDriverState *bs)
|
||||
BDRVQEDState *s = bs->opaque;
|
||||
|
||||
bdrv_qed_close(bs);
|
||||
|
||||
bdrv_invalidate_cache(bs->file);
|
||||
|
||||
memset(s, 0, sizeof(BDRVQEDState));
|
||||
bdrv_qed_open(bs, NULL, bs->open_flags, NULL);
|
||||
}
|
||||
|
@@ -852,8 +852,6 @@ static BlockDriver bdrv_quorum = {
|
||||
.bdrv_file_open = quorum_open,
|
||||
.bdrv_close = quorum_close,
|
||||
|
||||
.authorizations = { true, true },
|
||||
|
||||
.bdrv_co_flush_to_disk = quorum_co_flush,
|
||||
|
||||
.bdrv_getlength = quorum_getlength,
|
||||
@@ -862,6 +860,7 @@ static BlockDriver bdrv_quorum = {
|
||||
.bdrv_aio_writev = quorum_aio_writev,
|
||||
.bdrv_invalidate_cache = quorum_invalidate_cache,
|
||||
|
||||
.is_filter = true,
|
||||
.bdrv_recurse_is_first_non_filter = quorum_recurse_is_first_non_filter,
|
||||
};
|
||||
|
||||
|
@@ -1561,6 +1561,15 @@ static int check_hdev_writable(BDRVRawState *s)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void hdev_parse_filename(const char *filename, QDict *options,
|
||||
Error **errp)
|
||||
{
|
||||
/* The prefix is optional, just as for "file". */
|
||||
strstart(filename, "host_device:", &filename);
|
||||
|
||||
qdict_put_obj(options, "filename", QOBJECT(qstring_from_str(filename)));
|
||||
}
|
||||
|
||||
static int hdev_open(BlockDriverState *bs, QDict *options, int flags,
|
||||
Error **errp)
|
||||
{
|
||||
@@ -1767,6 +1776,18 @@ static int hdev_create(const char *filename, QEMUOptionParameter *options,
|
||||
int ret = 0;
|
||||
struct stat stat_buf;
|
||||
int64_t total_size = 0;
|
||||
bool has_prefix;
|
||||
|
||||
/* This function is used by all three protocol block drivers and therefore
|
||||
* any of these three prefixes may be given.
|
||||
* The return value has to be stored somewhere, otherwise this is an error
|
||||
* due to -Werror=unused-value. */
|
||||
has_prefix =
|
||||
strstart(filename, "host_device:", &filename) ||
|
||||
strstart(filename, "host_cdrom:" , &filename) ||
|
||||
strstart(filename, "host_floppy:", &filename);
|
||||
|
||||
(void)has_prefix;
|
||||
|
||||
/* Read out options */
|
||||
while (options && options->name) {
|
||||
@@ -1805,6 +1826,7 @@ static BlockDriver bdrv_host_device = {
|
||||
.instance_size = sizeof(BDRVRawState),
|
||||
.bdrv_needs_filename = true,
|
||||
.bdrv_probe_device = hdev_probe_device,
|
||||
.bdrv_parse_filename = hdev_parse_filename,
|
||||
.bdrv_file_open = hdev_open,
|
||||
.bdrv_close = raw_close,
|
||||
.bdrv_reopen_prepare = raw_reopen_prepare,
|
||||
@@ -1834,6 +1856,15 @@ static BlockDriver bdrv_host_device = {
|
||||
};
|
||||
|
||||
#ifdef __linux__
|
||||
static void floppy_parse_filename(const char *filename, QDict *options,
|
||||
Error **errp)
|
||||
{
|
||||
/* The prefix is optional, just as for "file". */
|
||||
strstart(filename, "host_floppy:", &filename);
|
||||
|
||||
qdict_put_obj(options, "filename", QOBJECT(qstring_from_str(filename)));
|
||||
}
|
||||
|
||||
static int floppy_open(BlockDriverState *bs, QDict *options, int flags,
|
||||
Error **errp)
|
||||
{
|
||||
@@ -1939,6 +1970,7 @@ static BlockDriver bdrv_host_floppy = {
|
||||
.instance_size = sizeof(BDRVRawState),
|
||||
.bdrv_needs_filename = true,
|
||||
.bdrv_probe_device = floppy_probe_device,
|
||||
.bdrv_parse_filename = floppy_parse_filename,
|
||||
.bdrv_file_open = floppy_open,
|
||||
.bdrv_close = raw_close,
|
||||
.bdrv_reopen_prepare = raw_reopen_prepare,
|
||||
@@ -1963,7 +1995,20 @@ static BlockDriver bdrv_host_floppy = {
|
||||
.bdrv_media_changed = floppy_media_changed,
|
||||
.bdrv_eject = floppy_eject,
|
||||
};
|
||||
#endif
|
||||
|
||||
#if defined(__linux__) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
|
||||
static void cdrom_parse_filename(const char *filename, QDict *options,
|
||||
Error **errp)
|
||||
{
|
||||
/* The prefix is optional, just as for "file". */
|
||||
strstart(filename, "host_cdrom:", &filename);
|
||||
|
||||
qdict_put_obj(options, "filename", QOBJECT(qstring_from_str(filename)));
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef __linux__
|
||||
static int cdrom_open(BlockDriverState *bs, QDict *options, int flags,
|
||||
Error **errp)
|
||||
{
|
||||
@@ -2050,6 +2095,7 @@ static BlockDriver bdrv_host_cdrom = {
|
||||
.instance_size = sizeof(BDRVRawState),
|
||||
.bdrv_needs_filename = true,
|
||||
.bdrv_probe_device = cdrom_probe_device,
|
||||
.bdrv_parse_filename = cdrom_parse_filename,
|
||||
.bdrv_file_open = cdrom_open,
|
||||
.bdrv_close = raw_close,
|
||||
.bdrv_reopen_prepare = raw_reopen_prepare,
|
||||
@@ -2180,6 +2226,7 @@ static BlockDriver bdrv_host_cdrom = {
|
||||
.instance_size = sizeof(BDRVRawState),
|
||||
.bdrv_needs_filename = true,
|
||||
.bdrv_probe_device = cdrom_probe_device,
|
||||
.bdrv_parse_filename = cdrom_parse_filename,
|
||||
.bdrv_file_open = cdrom_open,
|
||||
.bdrv_close = raw_close,
|
||||
.bdrv_reopen_prepare = raw_reopen_prepare,
|
||||
|
@@ -593,6 +593,15 @@ static int hdev_probe_device(const char *filename)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void hdev_parse_filename(const char *filename, QDict *options,
|
||||
Error **errp)
|
||||
{
|
||||
/* The prefix is optional, just as for "file". */
|
||||
strstart(filename, "host_device:", &filename);
|
||||
|
||||
qdict_put_obj(options, "filename", QOBJECT(qstring_from_str(filename)));
|
||||
}
|
||||
|
||||
static int hdev_open(BlockDriverState *bs, QDict *options, int flags,
|
||||
Error **errp)
|
||||
{
|
||||
@@ -663,6 +672,7 @@ static BlockDriver bdrv_host_device = {
|
||||
.protocol_name = "host_device",
|
||||
.instance_size = sizeof(BDRVRawState),
|
||||
.bdrv_needs_filename = true,
|
||||
.bdrv_parse_filename = hdev_parse_filename,
|
||||
.bdrv_probe_device = hdev_probe_device,
|
||||
.bdrv_file_open = hdev_open,
|
||||
.bdrv_close = raw_close,
|
||||
|
@@ -61,7 +61,7 @@
|
||||
/* These structures are ones that are defined in the VHDX specification
|
||||
* document */
|
||||
|
||||
#define VHDX_FILE_SIGNATURE 0x656C696678646876 /* "vhdxfile" in ASCII */
|
||||
#define VHDX_FILE_SIGNATURE 0x656C696678646876ULL /* "vhdxfile" in ASCII */
|
||||
typedef struct VHDXFileIdentifier {
|
||||
uint64_t signature; /* "vhdxfile" in ASCII */
|
||||
uint16_t creator[256]; /* optional; utf-16 string to identify
|
||||
@@ -238,7 +238,7 @@ typedef struct QEMU_PACKED VHDXLogDataSector {
|
||||
/* upper 44 bits are the file offset in 1MB units lower 3 bits are the state
|
||||
other bits are reserved */
|
||||
#define VHDX_BAT_STATE_BIT_MASK 0x07
|
||||
#define VHDX_BAT_FILE_OFF_MASK 0xFFFFFFFFFFF00000 /* upper 44 bits */
|
||||
#define VHDX_BAT_FILE_OFF_MASK 0xFFFFFFFFFFF00000ULL /* upper 44 bits */
|
||||
typedef uint64_t VHDXBatEntry;
|
||||
|
||||
/* ---- METADATA REGION STRUCTURES ---- */
|
||||
@@ -247,7 +247,7 @@ typedef uint64_t VHDXBatEntry;
|
||||
#define VHDX_METADATA_MAX_ENTRIES 2047 /* not including the header */
|
||||
#define VHDX_METADATA_TABLE_MAX_SIZE \
|
||||
(VHDX_METADATA_ENTRY_SIZE * (VHDX_METADATA_MAX_ENTRIES+1))
|
||||
#define VHDX_METADATA_SIGNATURE 0x617461646174656D /* "metadata" in ASCII */
|
||||
#define VHDX_METADATA_SIGNATURE 0x617461646174656DULL /* "metadata" in ASCII */
|
||||
typedef struct QEMU_PACKED VHDXMetadataTableHeader {
|
||||
uint64_t signature; /* "metadata" in ASCII */
|
||||
uint16_t reserved;
|
||||
|
@@ -1000,7 +1000,7 @@ int main(int argc, char **argv)
|
||||
memset(ts, 0, sizeof(TaskState));
|
||||
init_task_state(ts);
|
||||
ts->info = info;
|
||||
env->opaque = ts;
|
||||
cpu->opaque = ts;
|
||||
|
||||
#if defined(TARGET_I386)
|
||||
cpu_x86_set_cpl(env, 3);
|
||||
|
32
configure
vendored
32
configure
vendored
@@ -31,19 +31,6 @@ printf " '%s'" "$0" "$@" >> config.log
|
||||
echo >> config.log
|
||||
echo "#" >> config.log
|
||||
|
||||
# Save the configure command line for later reuse.
|
||||
cat <<EOD >config.status
|
||||
#!/bin/sh
|
||||
# Generated by configure.
|
||||
# Run this file to recreate the current configuration.
|
||||
# Compiler output produced by configure, useful for debugging
|
||||
# configure, is in config.log if it exists.
|
||||
EOD
|
||||
printf "exec" >>config.status
|
||||
printf " '%s'" "$0" "$@" >>config.status
|
||||
echo >>config.status
|
||||
chmod +x config.status
|
||||
|
||||
error_exit() {
|
||||
echo
|
||||
echo "ERROR: $1"
|
||||
@@ -3835,6 +3822,11 @@ fi
|
||||
|
||||
int128=no
|
||||
cat > $TMPC << EOF
|
||||
#if defined(__clang_major__) && defined(__clang_minor__)
|
||||
# if ((__clang_major__ < 3) || (__clang_major__ == 3) && (__clang_minor__ < 2))
|
||||
# error __int128_t does not work in CLANG before 3.2
|
||||
# endif
|
||||
#endif
|
||||
__int128_t a;
|
||||
__uint128_t b;
|
||||
int main (void) {
|
||||
@@ -5146,3 +5138,17 @@ done
|
||||
if test "$docs" = "yes" ; then
|
||||
mkdir -p QMP
|
||||
fi
|
||||
|
||||
# Save the configure command line for later reuse.
|
||||
cat <<EOD >config.status
|
||||
#!/bin/sh
|
||||
# Generated by configure.
|
||||
# Run this file to recreate the current configuration.
|
||||
# Compiler output produced by configure, useful for debugging
|
||||
# configure, is in config.log if it exists.
|
||||
EOD
|
||||
printf "exec" >>config.status
|
||||
printf " '%s'" "$0" "$@" >>config.status
|
||||
echo >>config.status
|
||||
chmod +x config.status
|
||||
|
||||
|
106
cpu-exec.c
106
cpu-exec.c
@@ -23,29 +23,22 @@
|
||||
#include "qemu/atomic.h"
|
||||
#include "sysemu/qtest.h"
|
||||
|
||||
bool qemu_cpu_has_work(CPUState *cpu)
|
||||
void cpu_loop_exit(CPUState *cpu)
|
||||
{
|
||||
return cpu_has_work(cpu);
|
||||
}
|
||||
|
||||
void cpu_loop_exit(CPUArchState *env)
|
||||
{
|
||||
CPUState *cpu = ENV_GET_CPU(env);
|
||||
|
||||
cpu->current_tb = NULL;
|
||||
siglongjmp(env->jmp_env, 1);
|
||||
siglongjmp(cpu->jmp_env, 1);
|
||||
}
|
||||
|
||||
/* exit the current TB from a signal handler. The host registers are
|
||||
restored in a state compatible with the CPU emulator
|
||||
*/
|
||||
#if defined(CONFIG_SOFTMMU)
|
||||
void cpu_resume_from_signal(CPUArchState *env, void *puc)
|
||||
void cpu_resume_from_signal(CPUState *cpu, void *puc)
|
||||
{
|
||||
/* XXX: restore cpu registers saved in host registers */
|
||||
|
||||
env->exception_index = -1;
|
||||
siglongjmp(env->jmp_env, 1);
|
||||
cpu->exception_index = -1;
|
||||
siglongjmp(cpu->jmp_env, 1);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -108,7 +101,7 @@ static void cpu_exec_nocache(CPUArchState *env, int max_cycles,
|
||||
if (max_cycles > CF_COUNT_MASK)
|
||||
max_cycles = CF_COUNT_MASK;
|
||||
|
||||
tb = tb_gen_code(env, orig_tb->pc, orig_tb->cs_base, orig_tb->flags,
|
||||
tb = tb_gen_code(cpu, orig_tb->pc, orig_tb->cs_base, orig_tb->flags,
|
||||
max_cycles);
|
||||
cpu->current_tb = tb;
|
||||
/* execute the generated code */
|
||||
@@ -123,6 +116,7 @@ static TranslationBlock *tb_find_slow(CPUArchState *env,
|
||||
target_ulong cs_base,
|
||||
uint64_t flags)
|
||||
{
|
||||
CPUState *cpu = ENV_GET_CPU(env);
|
||||
TranslationBlock *tb, **ptb1;
|
||||
unsigned int h;
|
||||
tb_page_addr_t phys_pc, phys_page1;
|
||||
@@ -160,7 +154,7 @@ static TranslationBlock *tb_find_slow(CPUArchState *env,
|
||||
}
|
||||
not_found:
|
||||
/* if no translated code available, then translate it now */
|
||||
tb = tb_gen_code(env, pc, cs_base, flags, 0);
|
||||
tb = tb_gen_code(cpu, pc, cs_base, flags, 0);
|
||||
|
||||
found:
|
||||
/* Move the last found TB to the head of the list */
|
||||
@@ -170,12 +164,13 @@ static TranslationBlock *tb_find_slow(CPUArchState *env,
|
||||
tcg_ctx.tb_ctx.tb_phys_hash[h] = tb;
|
||||
}
|
||||
/* we add the TB in the virtual pc hash table */
|
||||
env->tb_jmp_cache[tb_jmp_cache_hash_func(pc)] = tb;
|
||||
cpu->tb_jmp_cache[tb_jmp_cache_hash_func(pc)] = tb;
|
||||
return tb;
|
||||
}
|
||||
|
||||
static inline TranslationBlock *tb_find_fast(CPUArchState *env)
|
||||
{
|
||||
CPUState *cpu = ENV_GET_CPU(env);
|
||||
TranslationBlock *tb;
|
||||
target_ulong cs_base, pc;
|
||||
int flags;
|
||||
@@ -184,7 +179,7 @@ static inline TranslationBlock *tb_find_fast(CPUArchState *env)
|
||||
always be the same before a given translated block
|
||||
is executed. */
|
||||
cpu_get_tb_cpu_state(env, &pc, &cs_base, &flags);
|
||||
tb = env->tb_jmp_cache[tb_jmp_cache_hash_func(pc)];
|
||||
tb = cpu->tb_jmp_cache[tb_jmp_cache_hash_func(pc)];
|
||||
if (unlikely(!tb || tb->pc != pc || tb->cs_base != cs_base ||
|
||||
tb->flags != flags)) {
|
||||
tb = tb_find_slow(env, pc, cs_base, flags);
|
||||
@@ -201,10 +196,11 @@ void cpu_set_debug_excp_handler(CPUDebugExcpHandler *handler)
|
||||
|
||||
static void cpu_handle_debug_exception(CPUArchState *env)
|
||||
{
|
||||
CPUState *cpu = ENV_GET_CPU(env);
|
||||
CPUWatchpoint *wp;
|
||||
|
||||
if (!env->watchpoint_hit) {
|
||||
QTAILQ_FOREACH(wp, &env->watchpoints, entry) {
|
||||
if (!cpu->watchpoint_hit) {
|
||||
QTAILQ_FOREACH(wp, &cpu->watchpoints, entry) {
|
||||
wp->flags &= ~BP_WATCHPOINT_HIT;
|
||||
}
|
||||
}
|
||||
@@ -283,16 +279,16 @@ int cpu_exec(CPUArchState *env)
|
||||
#else
|
||||
#error unsupported target CPU
|
||||
#endif
|
||||
env->exception_index = -1;
|
||||
cpu->exception_index = -1;
|
||||
|
||||
/* prepare setjmp context for exception handling */
|
||||
for(;;) {
|
||||
if (sigsetjmp(env->jmp_env, 0) == 0) {
|
||||
if (sigsetjmp(cpu->jmp_env, 0) == 0) {
|
||||
/* if an exception is pending, we execute it here */
|
||||
if (env->exception_index >= 0) {
|
||||
if (env->exception_index >= EXCP_INTERRUPT) {
|
||||
if (cpu->exception_index >= 0) {
|
||||
if (cpu->exception_index >= EXCP_INTERRUPT) {
|
||||
/* exit request from the cpu execution loop */
|
||||
ret = env->exception_index;
|
||||
ret = cpu->exception_index;
|
||||
if (ret == EXCP_DEBUG) {
|
||||
cpu_handle_debug_exception(env);
|
||||
}
|
||||
@@ -305,11 +301,11 @@ int cpu_exec(CPUArchState *env)
|
||||
#if defined(TARGET_I386)
|
||||
cc->do_interrupt(cpu);
|
||||
#endif
|
||||
ret = env->exception_index;
|
||||
ret = cpu->exception_index;
|
||||
break;
|
||||
#else
|
||||
cc->do_interrupt(cpu);
|
||||
env->exception_index = -1;
|
||||
cpu->exception_index = -1;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -324,8 +320,8 @@ int cpu_exec(CPUArchState *env)
|
||||
}
|
||||
if (interrupt_request & CPU_INTERRUPT_DEBUG) {
|
||||
cpu->interrupt_request &= ~CPU_INTERRUPT_DEBUG;
|
||||
env->exception_index = EXCP_DEBUG;
|
||||
cpu_loop_exit(env);
|
||||
cpu->exception_index = EXCP_DEBUG;
|
||||
cpu_loop_exit(cpu);
|
||||
}
|
||||
#if defined(TARGET_ARM) || defined(TARGET_SPARC) || defined(TARGET_MIPS) || \
|
||||
defined(TARGET_PPC) || defined(TARGET_ALPHA) || defined(TARGET_CRIS) || \
|
||||
@@ -333,8 +329,8 @@ int cpu_exec(CPUArchState *env)
|
||||
if (interrupt_request & CPU_INTERRUPT_HALT) {
|
||||
cpu->interrupt_request &= ~CPU_INTERRUPT_HALT;
|
||||
cpu->halted = 1;
|
||||
env->exception_index = EXCP_HLT;
|
||||
cpu_loop_exit(env);
|
||||
cpu->exception_index = EXCP_HLT;
|
||||
cpu_loop_exit(cpu);
|
||||
}
|
||||
#endif
|
||||
#if defined(TARGET_I386)
|
||||
@@ -348,8 +344,8 @@ int cpu_exec(CPUArchState *env)
|
||||
cpu_svm_check_intercept_param(env, SVM_EXIT_INIT,
|
||||
0);
|
||||
do_cpu_init(x86_cpu);
|
||||
env->exception_index = EXCP_HALTED;
|
||||
cpu_loop_exit(env);
|
||||
cpu->exception_index = EXCP_HALTED;
|
||||
cpu_loop_exit(cpu);
|
||||
} else if (interrupt_request & CPU_INTERRUPT_SIPI) {
|
||||
do_cpu_sipi(x86_cpu);
|
||||
} else if (env->hflags2 & HF2_GIF_MASK) {
|
||||
@@ -420,7 +416,7 @@ int cpu_exec(CPUArchState *env)
|
||||
#elif defined(TARGET_LM32)
|
||||
if ((interrupt_request & CPU_INTERRUPT_HARD)
|
||||
&& (env->ie & IE_IE)) {
|
||||
env->exception_index = EXCP_IRQ;
|
||||
cpu->exception_index = EXCP_IRQ;
|
||||
cc->do_interrupt(cpu);
|
||||
next_tb = 0;
|
||||
}
|
||||
@@ -429,7 +425,7 @@ int cpu_exec(CPUArchState *env)
|
||||
&& (env->sregs[SR_MSR] & MSR_IE)
|
||||
&& !(env->sregs[SR_MSR] & (MSR_EIP | MSR_BIP))
|
||||
&& !(env->iflags & (D_FLAG | IMM_FLAG))) {
|
||||
env->exception_index = EXCP_IRQ;
|
||||
cpu->exception_index = EXCP_IRQ;
|
||||
cc->do_interrupt(cpu);
|
||||
next_tb = 0;
|
||||
}
|
||||
@@ -437,7 +433,7 @@ int cpu_exec(CPUArchState *env)
|
||||
if ((interrupt_request & CPU_INTERRUPT_HARD) &&
|
||||
cpu_mips_hw_interrupts_pending(env)) {
|
||||
/* Raise it */
|
||||
env->exception_index = EXCP_EXT_INTERRUPT;
|
||||
cpu->exception_index = EXCP_EXT_INTERRUPT;
|
||||
env->error_code = 0;
|
||||
cc->do_interrupt(cpu);
|
||||
next_tb = 0;
|
||||
@@ -454,7 +450,7 @@ int cpu_exec(CPUArchState *env)
|
||||
idx = EXCP_TICK;
|
||||
}
|
||||
if (idx >= 0) {
|
||||
env->exception_index = idx;
|
||||
cpu->exception_index = idx;
|
||||
cc->do_interrupt(cpu);
|
||||
next_tb = 0;
|
||||
}
|
||||
@@ -469,7 +465,7 @@ int cpu_exec(CPUArchState *env)
|
||||
if (((type == TT_EXTINT) &&
|
||||
cpu_pil_allowed(env, pil)) ||
|
||||
type != TT_EXTINT) {
|
||||
env->exception_index = env->interrupt_index;
|
||||
cpu->exception_index = env->interrupt_index;
|
||||
cc->do_interrupt(cpu);
|
||||
next_tb = 0;
|
||||
}
|
||||
@@ -478,7 +474,7 @@ int cpu_exec(CPUArchState *env)
|
||||
#elif defined(TARGET_ARM)
|
||||
if (interrupt_request & CPU_INTERRUPT_FIQ
|
||||
&& !(env->daif & PSTATE_F)) {
|
||||
env->exception_index = EXCP_FIQ;
|
||||
cpu->exception_index = EXCP_FIQ;
|
||||
cc->do_interrupt(cpu);
|
||||
next_tb = 0;
|
||||
}
|
||||
@@ -494,14 +490,14 @@ int cpu_exec(CPUArchState *env)
|
||||
if (interrupt_request & CPU_INTERRUPT_HARD
|
||||
&& ((IS_M(env) && env->regs[15] < 0xfffffff0)
|
||||
|| !(env->daif & PSTATE_I))) {
|
||||
env->exception_index = EXCP_IRQ;
|
||||
cpu->exception_index = EXCP_IRQ;
|
||||
cc->do_interrupt(cpu);
|
||||
next_tb = 0;
|
||||
}
|
||||
#elif defined(TARGET_UNICORE32)
|
||||
if (interrupt_request & CPU_INTERRUPT_HARD
|
||||
&& !(env->uncached_asr & ASR_I)) {
|
||||
env->exception_index = UC32_EXCP_INTR;
|
||||
cpu->exception_index = UC32_EXCP_INTR;
|
||||
cc->do_interrupt(cpu);
|
||||
next_tb = 0;
|
||||
}
|
||||
@@ -536,7 +532,7 @@ int cpu_exec(CPUArchState *env)
|
||||
}
|
||||
}
|
||||
if (idx >= 0) {
|
||||
env->exception_index = idx;
|
||||
cpu->exception_index = idx;
|
||||
env->error_code = 0;
|
||||
cc->do_interrupt(cpu);
|
||||
next_tb = 0;
|
||||
@@ -546,7 +542,7 @@ int cpu_exec(CPUArchState *env)
|
||||
if (interrupt_request & CPU_INTERRUPT_HARD
|
||||
&& (env->pregs[PR_CCS] & I_FLAG)
|
||||
&& !env->locked_irq) {
|
||||
env->exception_index = EXCP_IRQ;
|
||||
cpu->exception_index = EXCP_IRQ;
|
||||
cc->do_interrupt(cpu);
|
||||
next_tb = 0;
|
||||
}
|
||||
@@ -558,7 +554,7 @@ int cpu_exec(CPUArchState *env)
|
||||
m_flag_archval = M_FLAG_V32;
|
||||
}
|
||||
if ((env->pregs[PR_CCS] & m_flag_archval)) {
|
||||
env->exception_index = EXCP_NMI;
|
||||
cpu->exception_index = EXCP_NMI;
|
||||
cc->do_interrupt(cpu);
|
||||
next_tb = 0;
|
||||
}
|
||||
@@ -572,7 +568,7 @@ int cpu_exec(CPUArchState *env)
|
||||
hardware doesn't rely on this, so we
|
||||
provide/save the vector when the interrupt is
|
||||
first signalled. */
|
||||
env->exception_index = env->pending_vector;
|
||||
cpu->exception_index = env->pending_vector;
|
||||
do_interrupt_m68k_hardirq(env);
|
||||
next_tb = 0;
|
||||
}
|
||||
@@ -584,7 +580,7 @@ int cpu_exec(CPUArchState *env)
|
||||
}
|
||||
#elif defined(TARGET_XTENSA)
|
||||
if (interrupt_request & CPU_INTERRUPT_HARD) {
|
||||
env->exception_index = EXC_IRQ;
|
||||
cpu->exception_index = EXC_IRQ;
|
||||
cc->do_interrupt(cpu);
|
||||
next_tb = 0;
|
||||
}
|
||||
@@ -600,8 +596,8 @@ int cpu_exec(CPUArchState *env)
|
||||
}
|
||||
if (unlikely(cpu->exit_request)) {
|
||||
cpu->exit_request = 0;
|
||||
env->exception_index = EXCP_INTERRUPT;
|
||||
cpu_loop_exit(env);
|
||||
cpu->exception_index = EXCP_INTERRUPT;
|
||||
cpu_loop_exit(cpu);
|
||||
}
|
||||
spin_lock(&tcg_ctx.tb_ctx.tb_lock);
|
||||
tb = tb_find_fast(env);
|
||||
@@ -654,25 +650,25 @@ int cpu_exec(CPUArchState *env)
|
||||
/* Instruction counter expired. */
|
||||
int insns_left;
|
||||
tb = (TranslationBlock *)(next_tb & ~TB_EXIT_MASK);
|
||||
insns_left = env->icount_decr.u32;
|
||||
if (env->icount_extra && insns_left >= 0) {
|
||||
insns_left = cpu->icount_decr.u32;
|
||||
if (cpu->icount_extra && insns_left >= 0) {
|
||||
/* Refill decrementer and continue execution. */
|
||||
env->icount_extra += insns_left;
|
||||
if (env->icount_extra > 0xffff) {
|
||||
cpu->icount_extra += insns_left;
|
||||
if (cpu->icount_extra > 0xffff) {
|
||||
insns_left = 0xffff;
|
||||
} else {
|
||||
insns_left = env->icount_extra;
|
||||
insns_left = cpu->icount_extra;
|
||||
}
|
||||
env->icount_extra -= insns_left;
|
||||
env->icount_decr.u16.low = insns_left;
|
||||
cpu->icount_extra -= insns_left;
|
||||
cpu->icount_decr.u16.low = insns_left;
|
||||
} else {
|
||||
if (insns_left > 0) {
|
||||
/* Execute remaining instructions. */
|
||||
cpu_exec_nocache(env, insns_left, tb);
|
||||
}
|
||||
env->exception_index = EXCP_INTERRUPT;
|
||||
cpu->exception_index = EXCP_INTERRUPT;
|
||||
next_tb = 0;
|
||||
cpu_loop_exit(env);
|
||||
cpu_loop_exit(cpu);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
25
cpus.c
25
cpus.c
@@ -76,7 +76,7 @@ static bool cpu_thread_is_idle(CPUState *cpu)
|
||||
if (cpu_is_stopped(cpu)) {
|
||||
return true;
|
||||
}
|
||||
if (!cpu->halted || qemu_cpu_has_work(cpu) ||
|
||||
if (!cpu->halted || cpu_has_work(cpu) ||
|
||||
kvm_halt_in_kernel()) {
|
||||
return false;
|
||||
}
|
||||
@@ -139,11 +139,10 @@ static int64_t cpu_get_icount_locked(void)
|
||||
|
||||
icount = qemu_icount;
|
||||
if (cpu) {
|
||||
CPUArchState *env = cpu->env_ptr;
|
||||
if (!can_do_io(env)) {
|
||||
if (!cpu_can_do_io(cpu)) {
|
||||
fprintf(stderr, "Bad clock read\n");
|
||||
}
|
||||
icount -= (env->icount_decr.u16.low + env->icount_extra);
|
||||
icount -= (cpu->icount_decr.u16.low + cpu->icount_extra);
|
||||
}
|
||||
return qemu_icount_bias + (icount << icount_time_shift);
|
||||
}
|
||||
@@ -1236,6 +1235,7 @@ int vm_stop_force_state(RunState state)
|
||||
|
||||
static int tcg_cpu_exec(CPUArchState *env)
|
||||
{
|
||||
CPUState *cpu = ENV_GET_CPU(env);
|
||||
int ret;
|
||||
#ifdef CONFIG_PROFILER
|
||||
int64_t ti;
|
||||
@@ -1248,9 +1248,9 @@ static int tcg_cpu_exec(CPUArchState *env)
|
||||
int64_t count;
|
||||
int64_t deadline;
|
||||
int decr;
|
||||
qemu_icount -= (env->icount_decr.u16.low + env->icount_extra);
|
||||
env->icount_decr.u16.low = 0;
|
||||
env->icount_extra = 0;
|
||||
qemu_icount -= (cpu->icount_decr.u16.low + cpu->icount_extra);
|
||||
cpu->icount_decr.u16.low = 0;
|
||||
cpu->icount_extra = 0;
|
||||
deadline = qemu_clock_deadline_ns_all(QEMU_CLOCK_VIRTUAL);
|
||||
|
||||
/* Maintain prior (possibly buggy) behaviour where if no deadline
|
||||
@@ -1266,8 +1266,8 @@ static int tcg_cpu_exec(CPUArchState *env)
|
||||
qemu_icount += count;
|
||||
decr = (count > 0xffff) ? 0xffff : count;
|
||||
count -= decr;
|
||||
env->icount_decr.u16.low = decr;
|
||||
env->icount_extra = count;
|
||||
cpu->icount_decr.u16.low = decr;
|
||||
cpu->icount_extra = count;
|
||||
}
|
||||
ret = cpu_exec(env);
|
||||
#ifdef CONFIG_PROFILER
|
||||
@@ -1276,10 +1276,9 @@ static int tcg_cpu_exec(CPUArchState *env)
|
||||
if (use_icount) {
|
||||
/* Fold pending instructions back into the
|
||||
instruction counter, and clear the interrupt flag. */
|
||||
qemu_icount -= (env->icount_decr.u16.low
|
||||
+ env->icount_extra);
|
||||
env->icount_decr.u32 = 0;
|
||||
env->icount_extra = 0;
|
||||
qemu_icount -= (cpu->icount_decr.u16.low + cpu->icount_extra);
|
||||
cpu->icount_decr.u32 = 0;
|
||||
cpu->icount_extra = 0;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
24
cputlb.c
24
cputlb.c
@@ -46,9 +46,9 @@ int tlb_flush_count;
|
||||
* entries from the TLB at any time, so flushing more entries than
|
||||
* required is only an efficiency issue, not a correctness issue.
|
||||
*/
|
||||
void tlb_flush(CPUArchState *env, int flush_global)
|
||||
void tlb_flush(CPUState *cpu, int flush_global)
|
||||
{
|
||||
CPUState *cpu = ENV_GET_CPU(env);
|
||||
CPUArchState *env = cpu->env_ptr;
|
||||
|
||||
#if defined(DEBUG_TLB)
|
||||
printf("tlb_flush:\n");
|
||||
@@ -58,7 +58,7 @@ void tlb_flush(CPUArchState *env, int flush_global)
|
||||
cpu->current_tb = NULL;
|
||||
|
||||
memset(env->tlb_table, -1, sizeof(env->tlb_table));
|
||||
memset(env->tb_jmp_cache, 0, sizeof(env->tb_jmp_cache));
|
||||
memset(cpu->tb_jmp_cache, 0, sizeof(cpu->tb_jmp_cache));
|
||||
|
||||
env->tlb_flush_addr = -1;
|
||||
env->tlb_flush_mask = 0;
|
||||
@@ -77,9 +77,9 @@ static inline void tlb_flush_entry(CPUTLBEntry *tlb_entry, target_ulong addr)
|
||||
}
|
||||
}
|
||||
|
||||
void tlb_flush_page(CPUArchState *env, target_ulong addr)
|
||||
void tlb_flush_page(CPUState *cpu, target_ulong addr)
|
||||
{
|
||||
CPUState *cpu = ENV_GET_CPU(env);
|
||||
CPUArchState *env = cpu->env_ptr;
|
||||
int i;
|
||||
int mmu_idx;
|
||||
|
||||
@@ -93,7 +93,7 @@ void tlb_flush_page(CPUArchState *env, target_ulong addr)
|
||||
TARGET_FMT_lx "/" TARGET_FMT_lx ")\n",
|
||||
env->tlb_flush_addr, env->tlb_flush_mask);
|
||||
#endif
|
||||
tlb_flush(env, 1);
|
||||
tlb_flush(cpu, 1);
|
||||
return;
|
||||
}
|
||||
/* must reset current TB so that interrupts cannot modify the
|
||||
@@ -106,7 +106,7 @@ void tlb_flush_page(CPUArchState *env, target_ulong addr)
|
||||
tlb_flush_entry(&env->tlb_table[mmu_idx][i], addr);
|
||||
}
|
||||
|
||||
tb_flush_jmp_cache(env, addr);
|
||||
tb_flush_jmp_cache(cpu, addr);
|
||||
}
|
||||
|
||||
/* update the TLBs so that writes to code in the virtual page 'addr'
|
||||
@@ -119,7 +119,7 @@ void tlb_protect_code(ram_addr_t ram_addr)
|
||||
|
||||
/* update the TLB so that writes in physical page 'phys_addr' are no longer
|
||||
tested for self modifying code */
|
||||
void tlb_unprotect_code_phys(CPUArchState *env, ram_addr_t ram_addr,
|
||||
void tlb_unprotect_code_phys(CPUState *cpu, ram_addr_t ram_addr,
|
||||
target_ulong vaddr)
|
||||
{
|
||||
cpu_physical_memory_set_dirty_flag(ram_addr, DIRTY_MEMORY_CODE);
|
||||
@@ -221,10 +221,11 @@ static void tlb_add_large_page(CPUArchState *env, target_ulong vaddr,
|
||||
/* Add a new TLB entry. At most one entry for a given virtual address
|
||||
is permitted. Only a single TARGET_PAGE_SIZE region is mapped, the
|
||||
supplied size is only used by tlb_flush_page. */
|
||||
void tlb_set_page(CPUArchState *env, target_ulong vaddr,
|
||||
void tlb_set_page(CPUState *cpu, target_ulong vaddr,
|
||||
hwaddr paddr, int prot,
|
||||
int mmu_idx, target_ulong size)
|
||||
{
|
||||
CPUArchState *env = cpu->env_ptr;
|
||||
MemoryRegionSection *section;
|
||||
unsigned int index;
|
||||
target_ulong address;
|
||||
@@ -232,7 +233,6 @@ void tlb_set_page(CPUArchState *env, target_ulong vaddr,
|
||||
uintptr_t addend;
|
||||
CPUTLBEntry *te;
|
||||
hwaddr iotlb, xlat, sz;
|
||||
CPUState *cpu = ENV_GET_CPU(env);
|
||||
|
||||
assert(size >= TARGET_PAGE_SIZE);
|
||||
if (size != TARGET_PAGE_SIZE) {
|
||||
@@ -261,7 +261,7 @@ void tlb_set_page(CPUArchState *env, target_ulong vaddr,
|
||||
}
|
||||
|
||||
code_address = address;
|
||||
iotlb = memory_region_section_get_iotlb(env, section, vaddr, paddr, xlat,
|
||||
iotlb = memory_region_section_get_iotlb(cpu, section, vaddr, paddr, xlat,
|
||||
prot, &address);
|
||||
|
||||
index = (vaddr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
|
||||
@@ -322,7 +322,7 @@ tb_page_addr_t get_page_addr_code(CPUArchState *env1, target_ulong addr)
|
||||
if (cc->do_unassigned_access) {
|
||||
cc->do_unassigned_access(cpu, addr, false, true, 0, 4);
|
||||
} else {
|
||||
cpu_abort(env1, "Trying to execute code outside RAM or ROM at 0x"
|
||||
cpu_abort(cpu, "Trying to execute code outside RAM or ROM at 0x"
|
||||
TARGET_FMT_lx "\n", addr);
|
||||
}
|
||||
}
|
||||
|
@@ -33,12 +33,14 @@ DriveInfo *add_init_drive(const char *optstr)
|
||||
{
|
||||
DriveInfo *dinfo;
|
||||
QemuOpts *opts;
|
||||
MachineClass *mc;
|
||||
|
||||
opts = drive_def(optstr);
|
||||
if (!opts)
|
||||
return NULL;
|
||||
|
||||
dinfo = drive_init(opts, current_machine->block_default_type);
|
||||
mc = MACHINE_GET_CLASS(current_machine);
|
||||
dinfo = drive_init(opts, mc->qemu_machine->block_default_type);
|
||||
if (!dinfo) {
|
||||
qemu_opts_del(opts);
|
||||
return NULL;
|
||||
|
@@ -123,11 +123,12 @@ And it looks like this on the wire:
|
||||
|
||||
Flat union types avoid the nesting on the wire. They are used whenever a
|
||||
specific field of the base type is declared as the discriminator ('type' is
|
||||
then no longer generated). The discriminator must always be a string field.
|
||||
then no longer generated). The discriminator must be of enumeration type.
|
||||
The above example can then be modified as follows:
|
||||
|
||||
{ 'enum': 'BlockdevDriver', 'data': [ 'raw', 'qcow2' ] }
|
||||
{ 'type': 'BlockdevCommonOptions',
|
||||
'data': { 'driver': 'str', 'readonly': 'bool' } }
|
||||
'data': { 'driver': 'BlockdevDriver', 'readonly': 'bool' } }
|
||||
{ 'union': 'BlockdevOptions',
|
||||
'base': 'BlockdevCommonOptions',
|
||||
'discriminator': 'driver',
|
||||
|
@@ -11,99 +11,92 @@
|
||||
; (Com+Lpt)" from the list. Click "Have a disk". Select this file.
|
||||
; Procedure may vary a bit depending on the windows version.
|
||||
|
||||
; FIXME: This file covers the single port version only.
|
||||
; This file covers all options: pci-serial, pci-serial-2x, pci-serial-4x
|
||||
; for both 32 and 64 bit platforms.
|
||||
|
||||
[Version]
|
||||
Signature="$CHICAGO$"
|
||||
Class=Ports
|
||||
ClassGuid={4D36E978-E325-11CE-BFC1-08002BE10318}
|
||||
Signature="$Windows NT$"
|
||||
Class=MultiFunction
|
||||
ClassGUID={4d36e971-e325-11ce-bfc1-08002be10318}
|
||||
Provider=%QEMU%
|
||||
DriverVer=09/24/2012,1.3.0
|
||||
|
||||
[SourceDisksNames]
|
||||
3426=windows cd
|
||||
|
||||
[SourceDisksFiles]
|
||||
serial.sys = 3426
|
||||
serenum.sys = 3426
|
||||
|
||||
[DestinationDirs]
|
||||
DefaultDestDir = 11 ;LDID_SYS
|
||||
ComPort.NT.Copy = 12 ;DIRID_DRIVERS
|
||||
SerialEnumerator.NT.Copy=12 ;DIRID_DRIVERS
|
||||
|
||||
; Drivers
|
||||
;----------------------------------------------------------
|
||||
DriverVer=12/29/2013,1.3.0
|
||||
[ControlFlags]
|
||||
ExcludeFromSelect=*
|
||||
[Manufacturer]
|
||||
%QEMU%=QEMU,NTx86
|
||||
%QEMU%=QEMU,NTx86,NTAMD64
|
||||
|
||||
[QEMU.NTx86]
|
||||
%QEMU-PCI_SERIAL.DeviceDesc% = ComPort, "PCI\VEN_1b36&DEV_0002&CC_0700"
|
||||
%QEMU-PCI_SERIAL_1_PORT%=ComPort_inst1, PCI\VEN_1B36&DEV_0002
|
||||
%QEMU-PCI_SERIAL_2_PORT%=ComPort_inst2, PCI\VEN_1B36&DEV_0003
|
||||
%QEMU-PCI_SERIAL_4_PORT%=ComPort_inst4, PCI\VEN_1B36&DEV_0004
|
||||
|
||||
; COM sections
|
||||
;----------------------------------------------------------
|
||||
[ComPort.AddReg]
|
||||
HKR,,PortSubClass,1,01
|
||||
[QEMU.NTAMD64]
|
||||
%QEMU-PCI_SERIAL_1_PORT%=ComPort_inst1, PCI\VEN_1B36&DEV_0002
|
||||
%QEMU-PCI_SERIAL_2_PORT%=ComPort_inst2, PCI\VEN_1B36&DEV_0003
|
||||
%QEMU-PCI_SERIAL_4_PORT%=ComPort_inst4, PCI\VEN_1B36&DEV_0004
|
||||
|
||||
[ComPort.NT]
|
||||
AddReg=ComPort.AddReg, ComPort.NT.AddReg
|
||||
LogConfig=caa
|
||||
SyssetupPnPFlags = 1
|
||||
[ComPort_inst1]
|
||||
Include=mf.inf
|
||||
Needs=MFINSTALL.mf
|
||||
|
||||
[ComPort.NT.HW]
|
||||
AddReg=ComPort.NT.HW.AddReg
|
||||
[ComPort_inst2]
|
||||
Include=mf.inf
|
||||
Needs=MFINSTALL.mf
|
||||
|
||||
[ComPort.NT.AddReg]
|
||||
HKR,,EnumPropPages32,,"MsPorts.dll,SerialPortPropPageProvider"
|
||||
[ComPort_inst4]
|
||||
Include=mf.inf
|
||||
Needs=MFINSTALL.mf
|
||||
|
||||
[ComPort.NT.HW.AddReg]
|
||||
HKR,,"UpperFilters",0x00010000,"serenum"
|
||||
[ComPort_inst1.HW]
|
||||
AddReg=ComPort_inst1.RegHW
|
||||
|
||||
;-------------- Service installation
|
||||
; Port Driver (function driver for this device)
|
||||
[ComPort.NT.Services]
|
||||
AddService = Serial, 0x00000002, Serial_Service_Inst, Serial_EventLog_Inst
|
||||
AddService = Serenum,,Serenum_Service_Inst
|
||||
[ComPort_inst2.HW]
|
||||
AddReg=ComPort_inst2.RegHW
|
||||
|
||||
; -------------- Serial Port Driver install sections
|
||||
[Serial_Service_Inst]
|
||||
DisplayName = %Serial.SVCDESC%
|
||||
ServiceType = 1 ; SERVICE_KERNEL_DRIVER
|
||||
StartType = 1 ; SERVICE_SYSTEM_START (this driver may do detection)
|
||||
ErrorControl = 0 ; SERVICE_ERROR_IGNORE
|
||||
ServiceBinary = %12%\serial.sys
|
||||
LoadOrderGroup = Extended base
|
||||
[ComPort_inst4.HW]
|
||||
AddReg=ComPort_inst4.RegHW
|
||||
|
||||
; -------------- Serenum Driver install section
|
||||
[Serenum_Service_Inst]
|
||||
DisplayName = %Serenum.SVCDESC%
|
||||
ServiceType = 1 ; SERVICE_KERNEL_DRIVER
|
||||
StartType = 3 ; SERVICE_DEMAND_START
|
||||
ErrorControl = 1 ; SERVICE_ERROR_NORMAL
|
||||
ServiceBinary = %12%\serenum.sys
|
||||
LoadOrderGroup = PNP Filter
|
||||
[ComPort_inst1.Services]
|
||||
Include=mf.inf
|
||||
Needs=MFINSTALL.mf.Services
|
||||
|
||||
[Serial_EventLog_Inst]
|
||||
AddReg = Serial_EventLog_AddReg
|
||||
[ComPort_inst2.Services]
|
||||
Include=mf.inf
|
||||
Needs=MFINSTALL.mf.Services
|
||||
|
||||
[Serial_EventLog_AddReg]
|
||||
HKR,,EventMessageFile,0x00020000,"%%SystemRoot%%\System32\IoLogMsg.dll;%%SystemRoot%%\System32\drivers\serial.sys"
|
||||
HKR,,TypesSupported,0x00010001,7
|
||||
[ComPort_inst4.Services]
|
||||
Include=mf.inf
|
||||
Needs=MFINSTALL.mf.Services
|
||||
|
||||
; The following sections are COM port resource configs.
|
||||
; Section name format means:
|
||||
; Char 1 = c (COM port)
|
||||
; Char 2 = I/O config: 1 (3f8), 2 (2f8), 3 (3e8), 4 (2e8), a (any)
|
||||
; Char 3 = IRQ config: #, a (any)
|
||||
[ComPort_inst1.RegHW]
|
||||
HKR,Child0000,HardwareID,,*PNP0501
|
||||
HKR,Child0000,VaryingResourceMap,1,00, 00,00,00,00, 08,00,00,00
|
||||
HKR,Child0000,ResourceMap,1,02
|
||||
|
||||
[caa] ; Any base, any IRQ
|
||||
ConfigPriority=HARDRECONFIG
|
||||
IOConfig=8@100-ffff%fff8(3ff::)
|
||||
IRQConfig=S:3,4,5,7,9,10,11,12,14,15
|
||||
[ComPort_inst2.RegHW]
|
||||
HKR,Child0000,HardwareID,,*PNP0501
|
||||
HKR,Child0000,VaryingResourceMap,1,00, 00,00,00,00, 08,00,00,00
|
||||
HKR,Child0000,ResourceMap,1,02
|
||||
HKR,Child0001,HardwareID,,*PNP0501
|
||||
HKR,Child0001,VaryingResourceMap,1,00, 08,00,00,00, 08,00,00,00
|
||||
HKR,Child0001,ResourceMap,1,02
|
||||
|
||||
[ComPort_inst4.RegHW]
|
||||
HKR,Child0000,HardwareID,,*PNP0501
|
||||
HKR,Child0000,VaryingResourceMap,1,00, 00,00,00,00, 08,00,00,00
|
||||
HKR,Child0000,ResourceMap,1,02
|
||||
HKR,Child0001,HardwareID,,*PNP0501
|
||||
HKR,Child0001,VaryingResourceMap,1,00, 08,00,00,00, 08,00,00,00
|
||||
HKR,Child0001,ResourceMap,1,02
|
||||
HKR,Child0002,HardwareID,,*PNP0501
|
||||
HKR,Child0002,VaryingResourceMap,1,00, 10,00,00,00, 08,00,00,00
|
||||
HKR,Child0002,ResourceMap,1,02
|
||||
HKR,Child0003,HardwareID,,*PNP0501
|
||||
HKR,Child0003,VaryingResourceMap,1,00, 18,00,00,00, 08,00,00,00
|
||||
HKR,Child0003,ResourceMap,1,02
|
||||
|
||||
[Strings]
|
||||
QEMU="QEMU"
|
||||
QEMU-PCI_SERIAL.DeviceDesc="QEMU Serial PCI Card"
|
||||
|
||||
Serial.SVCDESC = "Serial port driver"
|
||||
Serenum.SVCDESC = "Serenum Filter Driver"
|
||||
QEMU-PCI_SERIAL_1_PORT="1x QEMU PCI Serial Card"
|
||||
QEMU-PCI_SERIAL_2_PORT="2x QEMU PCI Serial Card"
|
||||
QEMU-PCI_SERIAL_4_PORT="4x QEMU PCI Serial Card"
|
||||
|
118
exec.c
118
exec.c
@@ -33,6 +33,7 @@
|
||||
#include "hw/xen/xen.h"
|
||||
#include "qemu/timer.h"
|
||||
#include "qemu/config-file.h"
|
||||
#include "qemu/error-report.h"
|
||||
#include "exec/memory.h"
|
||||
#include "sysemu/dma.h"
|
||||
#include "exec/address-spaces.h"
|
||||
@@ -484,8 +485,8 @@ void cpu_exec_init(CPUArchState *env)
|
||||
}
|
||||
cpu->cpu_index = cpu_index;
|
||||
cpu->numa_node = 0;
|
||||
QTAILQ_INIT(&env->breakpoints);
|
||||
QTAILQ_INIT(&env->watchpoints);
|
||||
QTAILQ_INIT(&cpu->breakpoints);
|
||||
QTAILQ_INIT(&cpu->watchpoints);
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
cpu->as = &address_space_memory;
|
||||
cpu->thread_id = qemu_get_thread_id();
|
||||
@@ -527,29 +528,29 @@ static void breakpoint_invalidate(CPUState *cpu, target_ulong pc)
|
||||
#endif /* TARGET_HAS_ICE */
|
||||
|
||||
#if defined(CONFIG_USER_ONLY)
|
||||
void cpu_watchpoint_remove_all(CPUArchState *env, int mask)
|
||||
void cpu_watchpoint_remove_all(CPUState *cpu, int mask)
|
||||
|
||||
{
|
||||
}
|
||||
|
||||
int cpu_watchpoint_insert(CPUArchState *env, target_ulong addr, target_ulong len,
|
||||
int cpu_watchpoint_insert(CPUState *cpu, vaddr addr, vaddr len,
|
||||
int flags, CPUWatchpoint **watchpoint)
|
||||
{
|
||||
return -ENOSYS;
|
||||
}
|
||||
#else
|
||||
/* Add a watchpoint. */
|
||||
int cpu_watchpoint_insert(CPUArchState *env, target_ulong addr, target_ulong len,
|
||||
int cpu_watchpoint_insert(CPUState *cpu, vaddr addr, vaddr len,
|
||||
int flags, CPUWatchpoint **watchpoint)
|
||||
{
|
||||
target_ulong len_mask = ~(len - 1);
|
||||
vaddr len_mask = ~(len - 1);
|
||||
CPUWatchpoint *wp;
|
||||
|
||||
/* sanity checks: allow power-of-2 lengths, deny unaligned watchpoints */
|
||||
if ((len & (len - 1)) || (addr & ~len_mask) ||
|
||||
len == 0 || len > TARGET_PAGE_SIZE) {
|
||||
fprintf(stderr, "qemu: tried to set invalid watchpoint at "
|
||||
TARGET_FMT_lx ", len=" TARGET_FMT_lu "\n", addr, len);
|
||||
error_report("tried to set invalid watchpoint at %"
|
||||
VADDR_PRIx ", len=%" VADDR_PRIu, addr, len);
|
||||
return -EINVAL;
|
||||
}
|
||||
wp = g_malloc(sizeof(*wp));
|
||||
@@ -559,12 +560,13 @@ int cpu_watchpoint_insert(CPUArchState *env, target_ulong addr, target_ulong len
|
||||
wp->flags = flags;
|
||||
|
||||
/* keep all GDB-injected watchpoints in front */
|
||||
if (flags & BP_GDB)
|
||||
QTAILQ_INSERT_HEAD(&env->watchpoints, wp, entry);
|
||||
else
|
||||
QTAILQ_INSERT_TAIL(&env->watchpoints, wp, entry);
|
||||
if (flags & BP_GDB) {
|
||||
QTAILQ_INSERT_HEAD(&cpu->watchpoints, wp, entry);
|
||||
} else {
|
||||
QTAILQ_INSERT_TAIL(&cpu->watchpoints, wp, entry);
|
||||
}
|
||||
|
||||
tlb_flush_page(env, addr);
|
||||
tlb_flush_page(cpu, addr);
|
||||
|
||||
if (watchpoint)
|
||||
*watchpoint = wp;
|
||||
@@ -572,16 +574,16 @@ int cpu_watchpoint_insert(CPUArchState *env, target_ulong addr, target_ulong len
|
||||
}
|
||||
|
||||
/* Remove a specific watchpoint. */
|
||||
int cpu_watchpoint_remove(CPUArchState *env, target_ulong addr, target_ulong len,
|
||||
int cpu_watchpoint_remove(CPUState *cpu, vaddr addr, vaddr len,
|
||||
int flags)
|
||||
{
|
||||
target_ulong len_mask = ~(len - 1);
|
||||
vaddr len_mask = ~(len - 1);
|
||||
CPUWatchpoint *wp;
|
||||
|
||||
QTAILQ_FOREACH(wp, &env->watchpoints, entry) {
|
||||
QTAILQ_FOREACH(wp, &cpu->watchpoints, entry) {
|
||||
if (addr == wp->vaddr && len_mask == wp->len_mask
|
||||
&& flags == (wp->flags & ~BP_WATCHPOINT_HIT)) {
|
||||
cpu_watchpoint_remove_by_ref(env, wp);
|
||||
cpu_watchpoint_remove_by_ref(cpu, wp);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -589,29 +591,30 @@ int cpu_watchpoint_remove(CPUArchState *env, target_ulong addr, target_ulong len
|
||||
}
|
||||
|
||||
/* Remove a specific watchpoint by reference. */
|
||||
void cpu_watchpoint_remove_by_ref(CPUArchState *env, CPUWatchpoint *watchpoint)
|
||||
void cpu_watchpoint_remove_by_ref(CPUState *cpu, CPUWatchpoint *watchpoint)
|
||||
{
|
||||
QTAILQ_REMOVE(&env->watchpoints, watchpoint, entry);
|
||||
QTAILQ_REMOVE(&cpu->watchpoints, watchpoint, entry);
|
||||
|
||||
tlb_flush_page(env, watchpoint->vaddr);
|
||||
tlb_flush_page(cpu, watchpoint->vaddr);
|
||||
|
||||
g_free(watchpoint);
|
||||
}
|
||||
|
||||
/* Remove all matching watchpoints. */
|
||||
void cpu_watchpoint_remove_all(CPUArchState *env, int mask)
|
||||
void cpu_watchpoint_remove_all(CPUState *cpu, int mask)
|
||||
{
|
||||
CPUWatchpoint *wp, *next;
|
||||
|
||||
QTAILQ_FOREACH_SAFE(wp, &env->watchpoints, entry, next) {
|
||||
if (wp->flags & mask)
|
||||
cpu_watchpoint_remove_by_ref(env, wp);
|
||||
QTAILQ_FOREACH_SAFE(wp, &cpu->watchpoints, entry, next) {
|
||||
if (wp->flags & mask) {
|
||||
cpu_watchpoint_remove_by_ref(cpu, wp);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Add a breakpoint. */
|
||||
int cpu_breakpoint_insert(CPUArchState *env, target_ulong pc, int flags,
|
||||
int cpu_breakpoint_insert(CPUState *cpu, vaddr pc, int flags,
|
||||
CPUBreakpoint **breakpoint)
|
||||
{
|
||||
#if defined(TARGET_HAS_ICE)
|
||||
@@ -624,12 +627,12 @@ int cpu_breakpoint_insert(CPUArchState *env, target_ulong pc, int flags,
|
||||
|
||||
/* keep all GDB-injected breakpoints in front */
|
||||
if (flags & BP_GDB) {
|
||||
QTAILQ_INSERT_HEAD(&env->breakpoints, bp, entry);
|
||||
QTAILQ_INSERT_HEAD(&cpu->breakpoints, bp, entry);
|
||||
} else {
|
||||
QTAILQ_INSERT_TAIL(&env->breakpoints, bp, entry);
|
||||
QTAILQ_INSERT_TAIL(&cpu->breakpoints, bp, entry);
|
||||
}
|
||||
|
||||
breakpoint_invalidate(ENV_GET_CPU(env), pc);
|
||||
breakpoint_invalidate(cpu, pc);
|
||||
|
||||
if (breakpoint) {
|
||||
*breakpoint = bp;
|
||||
@@ -641,14 +644,14 @@ int cpu_breakpoint_insert(CPUArchState *env, target_ulong pc, int flags,
|
||||
}
|
||||
|
||||
/* Remove a specific breakpoint. */
|
||||
int cpu_breakpoint_remove(CPUArchState *env, target_ulong pc, int flags)
|
||||
int cpu_breakpoint_remove(CPUState *cpu, vaddr pc, int flags)
|
||||
{
|
||||
#if defined(TARGET_HAS_ICE)
|
||||
CPUBreakpoint *bp;
|
||||
|
||||
QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
|
||||
QTAILQ_FOREACH(bp, &cpu->breakpoints, entry) {
|
||||
if (bp->pc == pc && bp->flags == flags) {
|
||||
cpu_breakpoint_remove_by_ref(env, bp);
|
||||
cpu_breakpoint_remove_by_ref(cpu, bp);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -659,26 +662,27 @@ int cpu_breakpoint_remove(CPUArchState *env, target_ulong pc, int flags)
|
||||
}
|
||||
|
||||
/* Remove a specific breakpoint by reference. */
|
||||
void cpu_breakpoint_remove_by_ref(CPUArchState *env, CPUBreakpoint *breakpoint)
|
||||
void cpu_breakpoint_remove_by_ref(CPUState *cpu, CPUBreakpoint *breakpoint)
|
||||
{
|
||||
#if defined(TARGET_HAS_ICE)
|
||||
QTAILQ_REMOVE(&env->breakpoints, breakpoint, entry);
|
||||
QTAILQ_REMOVE(&cpu->breakpoints, breakpoint, entry);
|
||||
|
||||
breakpoint_invalidate(ENV_GET_CPU(env), breakpoint->pc);
|
||||
breakpoint_invalidate(cpu, breakpoint->pc);
|
||||
|
||||
g_free(breakpoint);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Remove all matching breakpoints. */
|
||||
void cpu_breakpoint_remove_all(CPUArchState *env, int mask)
|
||||
void cpu_breakpoint_remove_all(CPUState *cpu, int mask)
|
||||
{
|
||||
#if defined(TARGET_HAS_ICE)
|
||||
CPUBreakpoint *bp, *next;
|
||||
|
||||
QTAILQ_FOREACH_SAFE(bp, &env->breakpoints, entry, next) {
|
||||
if (bp->flags & mask)
|
||||
cpu_breakpoint_remove_by_ref(env, bp);
|
||||
QTAILQ_FOREACH_SAFE(bp, &cpu->breakpoints, entry, next) {
|
||||
if (bp->flags & mask) {
|
||||
cpu_breakpoint_remove_by_ref(cpu, bp);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -702,9 +706,8 @@ void cpu_single_step(CPUState *cpu, int enabled)
|
||||
#endif
|
||||
}
|
||||
|
||||
void cpu_abort(CPUArchState *env, const char *fmt, ...)
|
||||
void cpu_abort(CPUState *cpu, const char *fmt, ...)
|
||||
{
|
||||
CPUState *cpu = ENV_GET_CPU(env);
|
||||
va_list ap;
|
||||
va_list ap2;
|
||||
|
||||
@@ -792,7 +795,7 @@ static void cpu_physical_memory_set_dirty_tracking(bool enable)
|
||||
in_migration = enable;
|
||||
}
|
||||
|
||||
hwaddr memory_region_section_get_iotlb(CPUArchState *env,
|
||||
hwaddr memory_region_section_get_iotlb(CPUState *cpu,
|
||||
MemoryRegionSection *section,
|
||||
target_ulong vaddr,
|
||||
hwaddr paddr, hwaddr xlat,
|
||||
@@ -818,7 +821,7 @@ hwaddr memory_region_section_get_iotlb(CPUArchState *env,
|
||||
|
||||
/* Make accesses to pages with watchpoints go via the
|
||||
watchpoint trap routines. */
|
||||
QTAILQ_FOREACH(wp, &env->watchpoints, entry) {
|
||||
QTAILQ_FOREACH(wp, &cpu->watchpoints, entry) {
|
||||
if (vaddr == (wp->vaddr & TARGET_PAGE_MASK)) {
|
||||
/* Avoid trapping reads of pages with a write breakpoint. */
|
||||
if ((prot & PAGE_WRITE) || (wp->flags & BP_MEM_READ)) {
|
||||
@@ -1553,7 +1556,7 @@ static void notdirty_mem_write(void *opaque, hwaddr ram_addr,
|
||||
flushed */
|
||||
if (!cpu_physical_memory_is_clean(ram_addr)) {
|
||||
CPUArchState *env = current_cpu->env_ptr;
|
||||
tlb_set_dirty(env, env->mem_io_vaddr);
|
||||
tlb_set_dirty(env, current_cpu->mem_io_vaddr);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1572,34 +1575,35 @@ static const MemoryRegionOps notdirty_mem_ops = {
|
||||
/* Generate a debug exception if a watchpoint has been hit. */
|
||||
static void check_watchpoint(int offset, int len_mask, int flags)
|
||||
{
|
||||
CPUArchState *env = current_cpu->env_ptr;
|
||||
CPUState *cpu = current_cpu;
|
||||
CPUArchState *env = cpu->env_ptr;
|
||||
target_ulong pc, cs_base;
|
||||
target_ulong vaddr;
|
||||
CPUWatchpoint *wp;
|
||||
int cpu_flags;
|
||||
|
||||
if (env->watchpoint_hit) {
|
||||
if (cpu->watchpoint_hit) {
|
||||
/* We re-entered the check after replacing the TB. Now raise
|
||||
* the debug interrupt so that is will trigger after the
|
||||
* current instruction. */
|
||||
cpu_interrupt(ENV_GET_CPU(env), CPU_INTERRUPT_DEBUG);
|
||||
cpu_interrupt(cpu, CPU_INTERRUPT_DEBUG);
|
||||
return;
|
||||
}
|
||||
vaddr = (env->mem_io_vaddr & TARGET_PAGE_MASK) + offset;
|
||||
QTAILQ_FOREACH(wp, &env->watchpoints, entry) {
|
||||
vaddr = (cpu->mem_io_vaddr & TARGET_PAGE_MASK) + offset;
|
||||
QTAILQ_FOREACH(wp, &cpu->watchpoints, entry) {
|
||||
if ((vaddr == (wp->vaddr & len_mask) ||
|
||||
(vaddr & wp->len_mask) == wp->vaddr) && (wp->flags & flags)) {
|
||||
wp->flags |= BP_WATCHPOINT_HIT;
|
||||
if (!env->watchpoint_hit) {
|
||||
env->watchpoint_hit = wp;
|
||||
tb_check_watchpoint(env);
|
||||
if (!cpu->watchpoint_hit) {
|
||||
cpu->watchpoint_hit = wp;
|
||||
tb_check_watchpoint(cpu);
|
||||
if (wp->flags & BP_STOP_BEFORE_ACCESS) {
|
||||
env->exception_index = EXCP_DEBUG;
|
||||
cpu_loop_exit(env);
|
||||
cpu->exception_index = EXCP_DEBUG;
|
||||
cpu_loop_exit(cpu);
|
||||
} else {
|
||||
cpu_get_tb_cpu_state(env, &pc, &cs_base, &cpu_flags);
|
||||
tb_gen_code(env, pc, cs_base, cpu_flags, 1);
|
||||
cpu_resume_from_signal(env, NULL);
|
||||
tb_gen_code(cpu, pc, cs_base, cpu_flags, 1);
|
||||
cpu_resume_from_signal(cpu, NULL);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -1830,14 +1834,12 @@ static void tcg_commit(MemoryListener *listener)
|
||||
reset the modified entries */
|
||||
/* XXX: slow ! */
|
||||
CPU_FOREACH(cpu) {
|
||||
CPUArchState *env = cpu->env_ptr;
|
||||
|
||||
/* FIXME: Disentangle the cpu.h circular files deps so we can
|
||||
directly get the right CPU from listener. */
|
||||
if (cpu->tcg_as_listener != listener) {
|
||||
continue;
|
||||
}
|
||||
tlb_flush(env, 1);
|
||||
tlb_flush(cpu, 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
48
gdbstub.c
48
gdbstub.c
@@ -635,7 +635,6 @@ static const int xlat_gdb_type[] = {
|
||||
static int gdb_breakpoint_insert(target_ulong addr, target_ulong len, int type)
|
||||
{
|
||||
CPUState *cpu;
|
||||
CPUArchState *env;
|
||||
int err = 0;
|
||||
|
||||
if (kvm_enabled()) {
|
||||
@@ -646,10 +645,10 @@ static int gdb_breakpoint_insert(target_ulong addr, target_ulong len, int type)
|
||||
case GDB_BREAKPOINT_SW:
|
||||
case GDB_BREAKPOINT_HW:
|
||||
CPU_FOREACH(cpu) {
|
||||
env = cpu->env_ptr;
|
||||
err = cpu_breakpoint_insert(env, addr, BP_GDB, NULL);
|
||||
if (err)
|
||||
err = cpu_breakpoint_insert(cpu, addr, BP_GDB, NULL);
|
||||
if (err) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return err;
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
@@ -657,8 +656,7 @@ static int gdb_breakpoint_insert(target_ulong addr, target_ulong len, int type)
|
||||
case GDB_WATCHPOINT_READ:
|
||||
case GDB_WATCHPOINT_ACCESS:
|
||||
CPU_FOREACH(cpu) {
|
||||
env = cpu->env_ptr;
|
||||
err = cpu_watchpoint_insert(env, addr, len, xlat_gdb_type[type],
|
||||
err = cpu_watchpoint_insert(cpu, addr, len, xlat_gdb_type[type],
|
||||
NULL);
|
||||
if (err)
|
||||
break;
|
||||
@@ -673,7 +671,6 @@ static int gdb_breakpoint_insert(target_ulong addr, target_ulong len, int type)
|
||||
static int gdb_breakpoint_remove(target_ulong addr, target_ulong len, int type)
|
||||
{
|
||||
CPUState *cpu;
|
||||
CPUArchState *env;
|
||||
int err = 0;
|
||||
|
||||
if (kvm_enabled()) {
|
||||
@@ -684,10 +681,10 @@ static int gdb_breakpoint_remove(target_ulong addr, target_ulong len, int type)
|
||||
case GDB_BREAKPOINT_SW:
|
||||
case GDB_BREAKPOINT_HW:
|
||||
CPU_FOREACH(cpu) {
|
||||
env = cpu->env_ptr;
|
||||
err = cpu_breakpoint_remove(env, addr, BP_GDB);
|
||||
if (err)
|
||||
err = cpu_breakpoint_remove(cpu, addr, BP_GDB);
|
||||
if (err) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return err;
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
@@ -695,8 +692,7 @@ static int gdb_breakpoint_remove(target_ulong addr, target_ulong len, int type)
|
||||
case GDB_WATCHPOINT_READ:
|
||||
case GDB_WATCHPOINT_ACCESS:
|
||||
CPU_FOREACH(cpu) {
|
||||
env = cpu->env_ptr;
|
||||
err = cpu_watchpoint_remove(env, addr, len, xlat_gdb_type[type]);
|
||||
err = cpu_watchpoint_remove(cpu, addr, len, xlat_gdb_type[type]);
|
||||
if (err)
|
||||
break;
|
||||
}
|
||||
@@ -710,7 +706,6 @@ static int gdb_breakpoint_remove(target_ulong addr, target_ulong len, int type)
|
||||
static void gdb_breakpoint_remove_all(void)
|
||||
{
|
||||
CPUState *cpu;
|
||||
CPUArchState *env;
|
||||
|
||||
if (kvm_enabled()) {
|
||||
kvm_remove_all_breakpoints(gdbserver_state->c_cpu);
|
||||
@@ -718,10 +713,9 @@ static void gdb_breakpoint_remove_all(void)
|
||||
}
|
||||
|
||||
CPU_FOREACH(cpu) {
|
||||
env = cpu->env_ptr;
|
||||
cpu_breakpoint_remove_all(env, BP_GDB);
|
||||
cpu_breakpoint_remove_all(cpu, BP_GDB);
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
cpu_watchpoint_remove_all(env, BP_GDB);
|
||||
cpu_watchpoint_remove_all(cpu, BP_GDB);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -1086,8 +1080,7 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
|
||||
}
|
||||
#ifdef CONFIG_USER_ONLY
|
||||
else if (strncmp(p, "Offsets", 7) == 0) {
|
||||
CPUArchState *env = s->c_cpu->env_ptr;
|
||||
TaskState *ts = env->opaque;
|
||||
TaskState *ts = s->c_cpu->opaque;
|
||||
|
||||
snprintf(buf, sizeof(buf),
|
||||
"Text=" TARGET_ABI_FMT_lx ";Data=" TARGET_ABI_FMT_lx
|
||||
@@ -1205,8 +1198,8 @@ static void gdb_vm_state_change(void *opaque, int running, RunState state)
|
||||
}
|
||||
switch (state) {
|
||||
case RUN_STATE_DEBUG:
|
||||
if (env->watchpoint_hit) {
|
||||
switch (env->watchpoint_hit->flags & BP_MEM_ACCESS) {
|
||||
if (cpu->watchpoint_hit) {
|
||||
switch (cpu->watchpoint_hit->flags & BP_MEM_ACCESS) {
|
||||
case BP_MEM_READ:
|
||||
type = "r";
|
||||
break;
|
||||
@@ -1220,8 +1213,8 @@ static void gdb_vm_state_change(void *opaque, int running, RunState state)
|
||||
snprintf(buf, sizeof(buf),
|
||||
"T%02xthread:%02x;%swatch:" TARGET_FMT_lx ";",
|
||||
GDB_SIGNAL_TRAP, cpu_index(cpu), type,
|
||||
env->watchpoint_hit->vaddr);
|
||||
env->watchpoint_hit = NULL;
|
||||
(target_ulong)cpu->watchpoint_hit->vaddr);
|
||||
cpu->watchpoint_hit = NULL;
|
||||
goto send_packet;
|
||||
}
|
||||
tb_flush(env);
|
||||
@@ -1594,13 +1587,16 @@ int gdbserver_start(int port)
|
||||
/* Disable gdb stub for child processes. */
|
||||
void gdbserver_fork(CPUArchState *env)
|
||||
{
|
||||
CPUState *cpu = ENV_GET_CPU(env);
|
||||
GDBState *s = gdbserver_state;
|
||||
if (gdbserver_fd < 0 || s->fd < 0)
|
||||
return;
|
||||
|
||||
if (gdbserver_fd < 0 || s->fd < 0) {
|
||||
return;
|
||||
}
|
||||
close(s->fd);
|
||||
s->fd = -1;
|
||||
cpu_breakpoint_remove_all(env, BP_GDB);
|
||||
cpu_watchpoint_remove_all(env, BP_GDB);
|
||||
cpu_breakpoint_remove_all(cpu, BP_GDB);
|
||||
cpu_watchpoint_remove_all(cpu, BP_GDB);
|
||||
}
|
||||
#else
|
||||
static int gdb_chr_can_receive(void *opaque)
|
||||
|
@@ -658,14 +658,15 @@ static void spitz_adc_temp_on(void *opaque, int line, int level)
|
||||
max111x_set_input(max1111, MAX1111_BATT_TEMP, 0);
|
||||
}
|
||||
|
||||
static int corgi_ssp_init(SSISlave *dev)
|
||||
static int corgi_ssp_init(SSISlave *d)
|
||||
{
|
||||
CorgiSSPState *s = FROM_SSI_SLAVE(CorgiSSPState, dev);
|
||||
DeviceState *dev = DEVICE(d);
|
||||
CorgiSSPState *s = FROM_SSI_SLAVE(CorgiSSPState, d);
|
||||
|
||||
qdev_init_gpio_in(&dev->qdev, corgi_ssp_gpio_cs, 3);
|
||||
s->bus[0] = ssi_create_bus(&dev->qdev, "ssi0");
|
||||
s->bus[1] = ssi_create_bus(&dev->qdev, "ssi1");
|
||||
s->bus[2] = ssi_create_bus(&dev->qdev, "ssi2");
|
||||
qdev_init_gpio_in(dev, corgi_ssp_gpio_cs, 3);
|
||||
s->bus[0] = ssi_create_bus(dev, "ssi0");
|
||||
s->bus[1] = ssi_create_bus(dev, "ssi1");
|
||||
s->bus[2] = ssi_create_bus(dev, "ssi2");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@@ -223,13 +223,13 @@ static void *cur_chip = NULL; /* current chip point */
|
||||
/* static OPLSAMPLE *bufL,*bufR; */
|
||||
static OPL_CH *S_CH;
|
||||
static OPL_CH *E_CH;
|
||||
OPL_SLOT *SLOT7_1,*SLOT7_2,*SLOT8_1,*SLOT8_2;
|
||||
static OPL_SLOT *SLOT7_1, *SLOT7_2, *SLOT8_1, *SLOT8_2;
|
||||
|
||||
static INT32 outd[1];
|
||||
static INT32 ams;
|
||||
static INT32 vib;
|
||||
INT32 *ams_table;
|
||||
INT32 *vib_table;
|
||||
static INT32 *ams_table;
|
||||
static INT32 *vib_table;
|
||||
static INT32 amsIncr;
|
||||
static INT32 vibIncr;
|
||||
static INT32 feedback2; /* connect for SLOT 2 */
|
||||
|
@@ -23,6 +23,7 @@
|
||||
#include "virtio-blk.h"
|
||||
#include "block/aio.h"
|
||||
#include "hw/virtio/virtio-bus.h"
|
||||
#include "monitor/monitor.h" /* for object_add() */
|
||||
|
||||
enum {
|
||||
SEG_MAX = 126, /* maximum number of I/O segments */
|
||||
@@ -44,8 +45,6 @@ struct VirtIOBlockDataPlane {
|
||||
bool started;
|
||||
bool starting;
|
||||
bool stopping;
|
||||
QEMUBH *start_bh;
|
||||
QemuThread thread;
|
||||
|
||||
VirtIOBlkConf *blk;
|
||||
int fd; /* image file descriptor */
|
||||
@@ -59,12 +58,14 @@ struct VirtIOBlockDataPlane {
|
||||
* (because you don't own the file descriptor or handle; you just
|
||||
* use it).
|
||||
*/
|
||||
IOThread *iothread;
|
||||
bool internal_iothread;
|
||||
AioContext *ctx;
|
||||
EventNotifier io_notifier; /* Linux AIO completion */
|
||||
EventNotifier host_notifier; /* doorbell */
|
||||
|
||||
IOQueue ioqueue; /* Linux AIO queue (should really be per
|
||||
dataplane thread) */
|
||||
IOThread) */
|
||||
VirtIOBlockRequest requests[REQ_MAX]; /* pool of requests, managed by the
|
||||
queue */
|
||||
|
||||
@@ -342,26 +343,7 @@ static void handle_io(EventNotifier *e)
|
||||
}
|
||||
}
|
||||
|
||||
static void *data_plane_thread(void *opaque)
|
||||
{
|
||||
VirtIOBlockDataPlane *s = opaque;
|
||||
|
||||
while (!s->stopping || s->num_reqs > 0) {
|
||||
aio_poll(s->ctx, true);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void start_data_plane_bh(void *opaque)
|
||||
{
|
||||
VirtIOBlockDataPlane *s = opaque;
|
||||
|
||||
qemu_bh_delete(s->start_bh);
|
||||
s->start_bh = NULL;
|
||||
qemu_thread_create(&s->thread, "data_plane", data_plane_thread,
|
||||
s, QEMU_THREAD_JOINABLE);
|
||||
}
|
||||
|
||||
/* Context: QEMU global mutex held */
|
||||
void virtio_blk_data_plane_create(VirtIODevice *vdev, VirtIOBlkConf *blk,
|
||||
VirtIOBlockDataPlane **dataplane,
|
||||
Error **errp)
|
||||
@@ -408,12 +390,33 @@ void virtio_blk_data_plane_create(VirtIODevice *vdev, VirtIOBlkConf *blk,
|
||||
s->fd = fd;
|
||||
s->blk = blk;
|
||||
|
||||
if (blk->iothread) {
|
||||
s->internal_iothread = false;
|
||||
s->iothread = blk->iothread;
|
||||
object_ref(OBJECT(s->iothread));
|
||||
} else {
|
||||
/* Create per-device IOThread if none specified */
|
||||
Error *local_err = NULL;
|
||||
|
||||
s->internal_iothread = true;
|
||||
object_add(TYPE_IOTHREAD, vdev->name, NULL, NULL, &local_err);
|
||||
if (error_is_set(&local_err)) {
|
||||
error_propagate(errp, local_err);
|
||||
g_free(s);
|
||||
return;
|
||||
}
|
||||
s->iothread = iothread_find(vdev->name);
|
||||
assert(s->iothread);
|
||||
}
|
||||
s->ctx = iothread_get_aio_context(s->iothread);
|
||||
|
||||
/* Prevent block operations that conflict with data plane thread */
|
||||
bdrv_set_in_use(blk->conf.bs, 1);
|
||||
|
||||
*dataplane = s;
|
||||
}
|
||||
|
||||
/* Context: QEMU global mutex held */
|
||||
void virtio_blk_data_plane_destroy(VirtIOBlockDataPlane *s)
|
||||
{
|
||||
if (!s) {
|
||||
@@ -422,9 +425,14 @@ void virtio_blk_data_plane_destroy(VirtIOBlockDataPlane *s)
|
||||
|
||||
virtio_blk_data_plane_stop(s);
|
||||
bdrv_set_in_use(s->blk->conf.bs, 0);
|
||||
object_unref(OBJECT(s->iothread));
|
||||
if (s->internal_iothread) {
|
||||
object_unparent(OBJECT(s->iothread));
|
||||
}
|
||||
g_free(s);
|
||||
}
|
||||
|
||||
/* Context: QEMU global mutex held */
|
||||
void virtio_blk_data_plane_start(VirtIOBlockDataPlane *s)
|
||||
{
|
||||
BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(s->vdev)));
|
||||
@@ -448,8 +456,6 @@ void virtio_blk_data_plane_start(VirtIOBlockDataPlane *s)
|
||||
return;
|
||||
}
|
||||
|
||||
s->ctx = aio_context_new();
|
||||
|
||||
/* Set up guest notifier (irq) */
|
||||
if (k->set_guest_notifiers(qbus->parent, 1, true) != 0) {
|
||||
fprintf(stderr, "virtio-blk failed to set guest notifier, "
|
||||
@@ -464,7 +470,6 @@ 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);
|
||||
|
||||
/* Set up ioqueue */
|
||||
ioq_init(&s->ioqueue, s->fd, REQ_MAX);
|
||||
@@ -472,7 +477,6 @@ 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);
|
||||
|
||||
s->starting = false;
|
||||
s->started = true;
|
||||
@@ -481,11 +485,14 @@ void virtio_blk_data_plane_start(VirtIOBlockDataPlane *s)
|
||||
/* Kick right away to begin processing requests already in vring */
|
||||
event_notifier_set(virtio_queue_get_host_notifier(vq));
|
||||
|
||||
/* Spawn thread in BH so it inherits iothread cpusets */
|
||||
s->start_bh = qemu_bh_new(start_data_plane_bh, s);
|
||||
qemu_bh_schedule(s->start_bh);
|
||||
/* Get this show started by hooking up our callbacks */
|
||||
aio_context_acquire(s->ctx);
|
||||
aio_set_event_notifier(s->ctx, &s->host_notifier, handle_notify);
|
||||
aio_set_event_notifier(s->ctx, &s->io_notifier, handle_io);
|
||||
aio_context_release(s->ctx);
|
||||
}
|
||||
|
||||
/* Context: QEMU global mutex held */
|
||||
void virtio_blk_data_plane_stop(VirtIOBlockDataPlane *s)
|
||||
{
|
||||
BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(s->vdev)));
|
||||
@@ -496,27 +503,32 @@ void virtio_blk_data_plane_stop(VirtIOBlockDataPlane *s)
|
||||
s->stopping = true;
|
||||
trace_virtio_blk_data_plane_stop(s);
|
||||
|
||||
/* Stop thread or cancel pending thread creation BH */
|
||||
if (s->start_bh) {
|
||||
qemu_bh_delete(s->start_bh);
|
||||
s->start_bh = NULL;
|
||||
} else {
|
||||
aio_notify(s->ctx);
|
||||
qemu_thread_join(&s->thread);
|
||||
aio_context_acquire(s->ctx);
|
||||
|
||||
/* Stop notifications for new requests from guest */
|
||||
aio_set_event_notifier(s->ctx, &s->host_notifier, NULL);
|
||||
|
||||
/* Complete pending requests */
|
||||
while (s->num_reqs > 0) {
|
||||
aio_poll(s->ctx, true);
|
||||
}
|
||||
|
||||
/* Stop ioq callbacks (there are no pending requests left) */
|
||||
aio_set_event_notifier(s->ctx, &s->io_notifier, NULL);
|
||||
|
||||
aio_context_release(s->ctx);
|
||||
|
||||
/* Sync vring state back to virtqueue so that non-dataplane request
|
||||
* processing can continue when we disable the host notifier below.
|
||||
*/
|
||||
vring_teardown(&s->vring, s->vdev, 0);
|
||||
|
||||
ioq_cleanup(&s->ioqueue);
|
||||
|
||||
aio_set_event_notifier(s->ctx, &s->host_notifier, NULL);
|
||||
k->set_host_notifier(qbus->parent, 0, false);
|
||||
|
||||
aio_context_unref(s->ctx);
|
||||
|
||||
/* Clean up guest notifier (irq) */
|
||||
k->set_guest_notifiers(qbus->parent, 1, false);
|
||||
|
||||
vring_teardown(&s->vring, s->vdev, 0);
|
||||
s->started = false;
|
||||
s->stopping = false;
|
||||
}
|
||||
|
@@ -241,7 +241,8 @@ typedef enum {
|
||||
} CMDState;
|
||||
|
||||
typedef struct Flash {
|
||||
SSISlave ssidev;
|
||||
SSISlave parent_obj;
|
||||
|
||||
uint32_t r;
|
||||
|
||||
BlockDriverState *bdrv;
|
||||
@@ -545,7 +546,7 @@ static void decode_new_cmd(Flash *s, uint32_t value)
|
||||
|
||||
static int m25p80_cs(SSISlave *ss, bool select)
|
||||
{
|
||||
Flash *s = FROM_SSI_SLAVE(Flash, ss);
|
||||
Flash *s = M25P80(ss);
|
||||
|
||||
if (select) {
|
||||
s->len = 0;
|
||||
@@ -561,7 +562,7 @@ static int m25p80_cs(SSISlave *ss, bool select)
|
||||
|
||||
static uint32_t m25p80_transfer8(SSISlave *ss, uint32_t tx)
|
||||
{
|
||||
Flash *s = FROM_SSI_SLAVE(Flash, ss);
|
||||
Flash *s = M25P80(ss);
|
||||
uint32_t r = 0;
|
||||
|
||||
switch (s->state) {
|
||||
@@ -610,7 +611,7 @@ static uint32_t m25p80_transfer8(SSISlave *ss, uint32_t tx)
|
||||
static int m25p80_init(SSISlave *ss)
|
||||
{
|
||||
DriveInfo *dinfo;
|
||||
Flash *s = FROM_SSI_SLAVE(Flash, ss);
|
||||
Flash *s = M25P80(ss);
|
||||
M25P80Class *mc = M25P80_GET_CLASS(s);
|
||||
|
||||
s->pi = mc->pi;
|
||||
|
@@ -41,7 +41,6 @@ typedef struct SCLPConsoleLM {
|
||||
uint32_t write_errors; /* errors writing to char layer */
|
||||
uint32_t length; /* length of byte stream in buffer */
|
||||
uint8_t buf[SIZE_CONSOLE_BUFFER];
|
||||
qemu_irq irq_console_read;
|
||||
} SCLPConsoleLM;
|
||||
|
||||
/*
|
||||
@@ -68,13 +67,15 @@ static int chr_can_read(void *opaque)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void receive_from_chr_layer(SCLPConsoleLM *scon, const uint8_t *buf,
|
||||
int size)
|
||||
static void chr_read(void *opaque, const uint8_t *buf, int size)
|
||||
{
|
||||
SCLPConsoleLM *scon = opaque;
|
||||
|
||||
assert(size == 1);
|
||||
|
||||
if (*buf == '\r' || *buf == '\n') {
|
||||
scon->event.event_pending = true;
|
||||
sclp_service_interrupt(0);
|
||||
return;
|
||||
}
|
||||
scon->buf[scon->length] = *buf;
|
||||
@@ -84,20 +85,6 @@ static void receive_from_chr_layer(SCLPConsoleLM *scon, const uint8_t *buf,
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Send data from a char device over to the guest
|
||||
*/
|
||||
static void chr_read(void *opaque, const uint8_t *buf, int size)
|
||||
{
|
||||
SCLPConsoleLM *scon = opaque;
|
||||
|
||||
receive_from_chr_layer(scon, buf, size);
|
||||
if (scon->event.event_pending) {
|
||||
/* trigger SCLP read operation */
|
||||
qemu_irq_raise(scon->irq_console_read);
|
||||
}
|
||||
}
|
||||
|
||||
/* functions to be called by event facility */
|
||||
|
||||
static bool can_handle_event(uint8_t type)
|
||||
@@ -298,11 +285,6 @@ static int write_event_data(SCLPEvent *event, EventBufferHeader *ebh)
|
||||
return SCLP_RC_NORMAL_COMPLETION;
|
||||
}
|
||||
|
||||
static void trigger_console_data(void *opaque, int n, int level)
|
||||
{
|
||||
sclp_service_interrupt(0);
|
||||
}
|
||||
|
||||
/* functions for live migration */
|
||||
|
||||
static const VMStateDescription vmstate_sclplmconsole = {
|
||||
@@ -338,7 +320,6 @@ static int console_init(SCLPEvent *event)
|
||||
if (scon->chr) {
|
||||
qemu_chr_add_handlers(scon->chr, chr_can_read, chr_read, NULL, scon);
|
||||
}
|
||||
scon->irq_console_read = *qemu_allocate_irqs(trigger_console_data, NULL, 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@@ -36,7 +36,6 @@ typedef struct SCLPConsole {
|
||||
uint32_t iov_bs; /* offset in buf for char layer read operation */
|
||||
uint32_t iov_data_len; /* length of byte stream in buffer */
|
||||
uint32_t iov_sclp_rest; /* length of byte stream not read via SCLP */
|
||||
qemu_irq irq_read_vt220;
|
||||
} SCLPConsole;
|
||||
|
||||
/* character layer call-back functions */
|
||||
@@ -49,11 +48,12 @@ static int chr_can_read(void *opaque)
|
||||
return SIZE_BUFFER_VT220 - scon->iov_data_len;
|
||||
}
|
||||
|
||||
/* Receive n bytes from character layer, save in iov buffer,
|
||||
* and set event pending */
|
||||
static void receive_from_chr_layer(SCLPConsole *scon, const uint8_t *buf,
|
||||
int size)
|
||||
/* Send data from a char device over to the guest */
|
||||
static void chr_read(void *opaque, const uint8_t *buf, int size)
|
||||
{
|
||||
SCLPConsole *scon = opaque;
|
||||
|
||||
assert(scon);
|
||||
/* read data must fit into current buffer */
|
||||
assert(size <= SIZE_BUFFER_VT220 - scon->iov_data_len);
|
||||
|
||||
@@ -63,18 +63,7 @@ static void receive_from_chr_layer(SCLPConsole *scon, const uint8_t *buf,
|
||||
scon->iov_sclp_rest += size;
|
||||
scon->iov_bs += size;
|
||||
scon->event.event_pending = true;
|
||||
}
|
||||
|
||||
/* Send data from a char device over to the guest */
|
||||
static void chr_read(void *opaque, const uint8_t *buf, int size)
|
||||
{
|
||||
SCLPConsole *scon = opaque;
|
||||
|
||||
assert(scon);
|
||||
|
||||
receive_from_chr_layer(scon, buf, size);
|
||||
/* trigger SCLP read operation */
|
||||
qemu_irq_raise(scon->irq_read_vt220);
|
||||
sclp_service_interrupt(0);
|
||||
}
|
||||
|
||||
/* functions to be called by event facility */
|
||||
@@ -192,11 +181,6 @@ static int write_event_data(SCLPEvent *event, EventBufferHeader *evt_buf_hdr)
|
||||
return rc;
|
||||
}
|
||||
|
||||
static void trigger_ascii_console_data(void *opaque, int n, int level)
|
||||
{
|
||||
sclp_service_interrupt(0);
|
||||
}
|
||||
|
||||
static const VMStateDescription vmstate_sclpconsole = {
|
||||
.name = "sclpconsole",
|
||||
.version_id = 0,
|
||||
@@ -232,8 +216,6 @@ static int console_init(SCLPEvent *event)
|
||||
qemu_chr_add_handlers(scon->chr, chr_can_read,
|
||||
chr_read, NULL, scon);
|
||||
}
|
||||
scon->irq_read_vt220 = *qemu_allocate_irqs(trigger_ascii_console_data,
|
||||
NULL, 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@@ -15,8 +15,13 @@
|
||||
#include "trace.h"
|
||||
#include "hw/virtio/virtio-serial.h"
|
||||
|
||||
#define TYPE_VIRTIO_CONSOLE_SERIAL_PORT "virtserialport"
|
||||
#define VIRTIO_CONSOLE(obj) \
|
||||
OBJECT_CHECK(VirtConsole, (obj), TYPE_VIRTIO_CONSOLE_SERIAL_PORT)
|
||||
|
||||
typedef struct VirtConsole {
|
||||
VirtIOSerialPort port;
|
||||
VirtIOSerialPort parent_obj;
|
||||
|
||||
CharDriverState *chr;
|
||||
guint watch;
|
||||
} VirtConsole;
|
||||
@@ -31,7 +36,7 @@ static gboolean chr_write_unblocked(GIOChannel *chan, GIOCondition cond,
|
||||
VirtConsole *vcon = opaque;
|
||||
|
||||
vcon->watch = 0;
|
||||
virtio_serial_throttle_port(&vcon->port, false);
|
||||
virtio_serial_throttle_port(VIRTIO_SERIAL_PORT(vcon), false);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -39,7 +44,7 @@ static gboolean chr_write_unblocked(GIOChannel *chan, GIOCondition cond,
|
||||
static ssize_t flush_buf(VirtIOSerialPort *port,
|
||||
const uint8_t *buf, ssize_t len)
|
||||
{
|
||||
VirtConsole *vcon = DO_UPCAST(VirtConsole, port, port);
|
||||
VirtConsole *vcon = VIRTIO_CONSOLE(port);
|
||||
ssize_t ret;
|
||||
|
||||
if (!vcon->chr) {
|
||||
@@ -75,7 +80,7 @@ static ssize_t flush_buf(VirtIOSerialPort *port,
|
||||
/* Callback function that's called when the guest opens/closes the port */
|
||||
static void set_guest_connected(VirtIOSerialPort *port, int guest_connected)
|
||||
{
|
||||
VirtConsole *vcon = DO_UPCAST(VirtConsole, port, port);
|
||||
VirtConsole *vcon = VIRTIO_CONSOLE(port);
|
||||
|
||||
if (!vcon->chr) {
|
||||
return;
|
||||
@@ -88,45 +93,49 @@ static int chr_can_read(void *opaque)
|
||||
{
|
||||
VirtConsole *vcon = opaque;
|
||||
|
||||
return virtio_serial_guest_ready(&vcon->port);
|
||||
return virtio_serial_guest_ready(VIRTIO_SERIAL_PORT(vcon));
|
||||
}
|
||||
|
||||
/* Send data from a char device over to the guest */
|
||||
static void chr_read(void *opaque, const uint8_t *buf, int size)
|
||||
{
|
||||
VirtConsole *vcon = opaque;
|
||||
VirtIOSerialPort *port = VIRTIO_SERIAL_PORT(vcon);
|
||||
|
||||
trace_virtio_console_chr_read(vcon->port.id, size);
|
||||
virtio_serial_write(&vcon->port, buf, size);
|
||||
trace_virtio_console_chr_read(port->id, size);
|
||||
virtio_serial_write(port, buf, size);
|
||||
}
|
||||
|
||||
static void chr_event(void *opaque, int event)
|
||||
{
|
||||
VirtConsole *vcon = opaque;
|
||||
VirtIOSerialPort *port = VIRTIO_SERIAL_PORT(vcon);
|
||||
|
||||
trace_virtio_console_chr_event(vcon->port.id, event);
|
||||
trace_virtio_console_chr_event(port->id, event);
|
||||
switch (event) {
|
||||
case CHR_EVENT_OPENED:
|
||||
virtio_serial_open(&vcon->port);
|
||||
virtio_serial_open(port);
|
||||
break;
|
||||
case CHR_EVENT_CLOSED:
|
||||
if (vcon->watch) {
|
||||
g_source_remove(vcon->watch);
|
||||
vcon->watch = 0;
|
||||
}
|
||||
virtio_serial_close(&vcon->port);
|
||||
virtio_serial_close(port);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static int virtconsole_initfn(VirtIOSerialPort *port)
|
||||
static void virtconsole_realize(DeviceState *dev, Error **errp)
|
||||
{
|
||||
VirtConsole *vcon = DO_UPCAST(VirtConsole, port, port);
|
||||
VirtIOSerialPortClass *k = VIRTIO_SERIAL_PORT_GET_CLASS(port);
|
||||
VirtIOSerialPort *port = VIRTIO_SERIAL_PORT(dev);
|
||||
VirtConsole *vcon = VIRTIO_CONSOLE(dev);
|
||||
VirtIOSerialPortClass *k = VIRTIO_SERIAL_PORT_GET_CLASS(dev);
|
||||
|
||||
if (port->id == 0 && !k->is_console) {
|
||||
error_report("Port number 0 on virtio-serial devices reserved for virtconsole devices for backward compatibility.");
|
||||
return -1;
|
||||
error_setg(errp, "Port number 0 on virtio-serial devices reserved "
|
||||
"for virtconsole devices for backward compatibility.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (vcon->chr) {
|
||||
@@ -134,43 +143,27 @@ static int virtconsole_initfn(VirtIOSerialPort *port)
|
||||
qemu_chr_add_handlers(vcon->chr, chr_can_read, chr_read, chr_event,
|
||||
vcon);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int virtconsole_exitfn(VirtIOSerialPort *port)
|
||||
static void virtconsole_unrealize(DeviceState *dev, Error **errp)
|
||||
{
|
||||
VirtConsole *vcon = DO_UPCAST(VirtConsole, port, port);
|
||||
VirtConsole *vcon = VIRTIO_CONSOLE(dev);
|
||||
|
||||
if (vcon->watch) {
|
||||
g_source_remove(vcon->watch);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static Property virtconsole_properties[] = {
|
||||
DEFINE_PROP_CHR("chardev", VirtConsole, chr),
|
||||
DEFINE_PROP_END_OF_LIST(),
|
||||
};
|
||||
|
||||
static void virtconsole_class_init(ObjectClass *klass, void *data)
|
||||
{
|
||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||
VirtIOSerialPortClass *k = VIRTIO_SERIAL_PORT_CLASS(klass);
|
||||
|
||||
k->is_console = true;
|
||||
k->init = virtconsole_initfn;
|
||||
k->exit = virtconsole_exitfn;
|
||||
k->have_data = flush_buf;
|
||||
k->set_guest_connected = set_guest_connected;
|
||||
dc->props = virtconsole_properties;
|
||||
}
|
||||
|
||||
static const TypeInfo virtconsole_info = {
|
||||
.name = "virtconsole",
|
||||
.parent = TYPE_VIRTIO_SERIAL_PORT,
|
||||
.instance_size = sizeof(VirtConsole),
|
||||
.parent = TYPE_VIRTIO_CONSOLE_SERIAL_PORT,
|
||||
.class_init = virtconsole_class_init,
|
||||
};
|
||||
|
||||
@@ -184,15 +177,15 @@ static void virtserialport_class_init(ObjectClass *klass, void *data)
|
||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||
VirtIOSerialPortClass *k = VIRTIO_SERIAL_PORT_CLASS(klass);
|
||||
|
||||
k->init = virtconsole_initfn;
|
||||
k->exit = virtconsole_exitfn;
|
||||
k->realize = virtconsole_realize;
|
||||
k->unrealize = virtconsole_unrealize;
|
||||
k->have_data = flush_buf;
|
||||
k->set_guest_connected = set_guest_connected;
|
||||
dc->props = virtserialport_properties;
|
||||
}
|
||||
|
||||
static const TypeInfo virtserialport_info = {
|
||||
.name = "virtserialport",
|
||||
.name = TYPE_VIRTIO_CONSOLE_SERIAL_PORT,
|
||||
.parent = TYPE_VIRTIO_SERIAL_PORT,
|
||||
.instance_size = sizeof(VirtConsole),
|
||||
.class_init = virtserialport_class_init,
|
||||
@@ -200,8 +193,8 @@ static const TypeInfo virtserialport_info = {
|
||||
|
||||
static void virtconsole_register_types(void)
|
||||
{
|
||||
type_register_static(&virtconsole_info);
|
||||
type_register_static(&virtserialport_info);
|
||||
type_register_static(&virtconsole_info);
|
||||
}
|
||||
|
||||
type_init(virtconsole_register_types)
|
||||
|
@@ -808,13 +808,14 @@ static void remove_port(VirtIOSerial *vser, uint32_t port_id)
|
||||
send_control_event(vser, port->id, VIRTIO_CONSOLE_PORT_REMOVE, 1);
|
||||
}
|
||||
|
||||
static int virtser_port_qdev_init(DeviceState *qdev)
|
||||
static void virtser_port_device_realize(DeviceState *dev, Error **errp)
|
||||
{
|
||||
VirtIOSerialPort *port = DO_UPCAST(VirtIOSerialPort, dev, qdev);
|
||||
VirtIOSerialPort *port = VIRTIO_SERIAL_PORT(dev);
|
||||
VirtIOSerialPortClass *vsc = VIRTIO_SERIAL_PORT_GET_CLASS(port);
|
||||
VirtIOSerialBus *bus = DO_UPCAST(VirtIOSerialBus, qbus, qdev->parent_bus);
|
||||
int ret, max_nr_ports;
|
||||
VirtIOSerialBus *bus = VIRTIO_SERIAL_BUS(qdev_get_parent_bus(dev));
|
||||
int max_nr_ports;
|
||||
bool plugging_port0;
|
||||
Error *err = NULL;
|
||||
|
||||
port->vser = bus->vser;
|
||||
port->bh = qemu_bh_new(flush_queued_data_bh, port);
|
||||
@@ -829,9 +830,9 @@ static int virtser_port_qdev_init(DeviceState *qdev)
|
||||
plugging_port0 = vsc->is_console && !find_port_by_id(port->vser, 0);
|
||||
|
||||
if (find_port_by_id(port->vser, port->id)) {
|
||||
error_report("virtio-serial-bus: A port already exists at id %u",
|
||||
port->id);
|
||||
return -1;
|
||||
error_setg(errp, "virtio-serial-bus: A port already exists at id %u",
|
||||
port->id);
|
||||
return;
|
||||
}
|
||||
|
||||
if (port->id == VIRTIO_CONSOLE_BAD_ID) {
|
||||
@@ -840,22 +841,24 @@ static int virtser_port_qdev_init(DeviceState *qdev)
|
||||
} else {
|
||||
port->id = find_free_port_id(port->vser);
|
||||
if (port->id == VIRTIO_CONSOLE_BAD_ID) {
|
||||
error_report("virtio-serial-bus: Maximum port limit for this device reached");
|
||||
return -1;
|
||||
error_setg(errp, "virtio-serial-bus: Maximum port limit for "
|
||||
"this device reached");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
max_nr_ports = tswap32(port->vser->config.max_nr_ports);
|
||||
if (port->id >= max_nr_ports) {
|
||||
error_report("virtio-serial-bus: Out-of-range port id specified, max. allowed: %u",
|
||||
max_nr_ports - 1);
|
||||
return -1;
|
||||
error_setg(errp, "virtio-serial-bus: Out-of-range port id specified, "
|
||||
"max. allowed: %u", max_nr_ports - 1);
|
||||
return;
|
||||
}
|
||||
|
||||
ret = vsc->init(port);
|
||||
if (ret) {
|
||||
return ret;
|
||||
vsc->realize(dev, &err);
|
||||
if (err != NULL) {
|
||||
error_propagate(errp, err);
|
||||
return;
|
||||
}
|
||||
|
||||
port->elem.out_num = 0;
|
||||
@@ -868,14 +871,12 @@ static int virtser_port_qdev_init(DeviceState *qdev)
|
||||
|
||||
/* Send an update to the guest about this new port added */
|
||||
virtio_notify_config(VIRTIO_DEVICE(port->vser));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int virtser_port_qdev_exit(DeviceState *qdev)
|
||||
static void virtser_port_device_unrealize(DeviceState *dev, Error **errp)
|
||||
{
|
||||
VirtIOSerialPort *port = DO_UPCAST(VirtIOSerialPort, dev, qdev);
|
||||
VirtIOSerialPortClass *vsc = VIRTIO_SERIAL_PORT_GET_CLASS(port);
|
||||
VirtIOSerialPort *port = VIRTIO_SERIAL_PORT(dev);
|
||||
VirtIOSerialPortClass *vsc = VIRTIO_SERIAL_PORT_GET_CLASS(dev);
|
||||
VirtIOSerial *vser = port->vser;
|
||||
|
||||
qemu_bh_delete(port->bh);
|
||||
@@ -883,10 +884,9 @@ static int virtser_port_qdev_exit(DeviceState *qdev)
|
||||
|
||||
QTAILQ_REMOVE(&vser->ports, port, next);
|
||||
|
||||
if (vsc->exit) {
|
||||
vsc->exit(port);
|
||||
if (vsc->unrealize) {
|
||||
vsc->unrealize(dev, errp);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void virtio_serial_device_realize(DeviceState *dev, Error **errp)
|
||||
@@ -971,10 +971,11 @@ static void virtio_serial_device_realize(DeviceState *dev, Error **errp)
|
||||
static void virtio_serial_port_class_init(ObjectClass *klass, void *data)
|
||||
{
|
||||
DeviceClass *k = DEVICE_CLASS(klass);
|
||||
k->init = virtser_port_qdev_init;
|
||||
|
||||
set_bit(DEVICE_CATEGORY_INPUT, k->categories);
|
||||
k->bus_type = TYPE_VIRTIO_SERIAL_BUS;
|
||||
k->exit = virtser_port_qdev_exit;
|
||||
k->realize = virtser_port_device_realize;
|
||||
k->unrealize = virtser_port_device_unrealize;
|
||||
k->unplug = qdev_simple_unplug_cb;
|
||||
k->props = virtser_props;
|
||||
}
|
||||
|
@@ -8,7 +8,7 @@ common-obj-$(CONFIG_EMPTY_SLOT) += empty_slot.o
|
||||
common-obj-$(CONFIG_XILINX_AXI) += stream.o
|
||||
common-obj-$(CONFIG_PTIMER) += ptimer.o
|
||||
common-obj-$(CONFIG_SOFTMMU) += sysbus.o
|
||||
common-obj-$(CONFIG_SOFTMMU) += machine.o
|
||||
common-obj-$(CONFIG_SOFTMMU) += null-machine.o
|
||||
common-obj-$(CONFIG_SOFTMMU) += loader.o
|
||||
common-obj-$(CONFIG_SOFTMMU) += qdev-properties-system.o
|
||||
|
||||
|
@@ -54,7 +54,8 @@
|
||||
|
||||
#include <zlib.h>
|
||||
|
||||
bool rom_file_in_ram = true;
|
||||
bool option_rom_has_mr = false;
|
||||
bool rom_file_has_mr = true;
|
||||
|
||||
static int roms_loaded;
|
||||
|
||||
@@ -642,7 +643,8 @@ static void *rom_set_mr(Rom *rom, Object *owner, const char *name)
|
||||
}
|
||||
|
||||
int rom_add_file(const char *file, const char *fw_dir,
|
||||
hwaddr addr, int32_t bootindex)
|
||||
hwaddr addr, int32_t bootindex,
|
||||
bool option_rom)
|
||||
{
|
||||
Rom *rom;
|
||||
int rc, fd = -1;
|
||||
@@ -694,7 +696,7 @@ int rom_add_file(const char *file, const char *fw_dir,
|
||||
basename);
|
||||
snprintf(devpath, sizeof(devpath), "/rom@%s", fw_file_name);
|
||||
|
||||
if (rom_file_in_ram) {
|
||||
if ((!option_rom || option_rom_has_mr) && rom_file_has_mr) {
|
||||
data = rom_set_mr(rom, OBJECT(fw_cfg), devpath);
|
||||
} else {
|
||||
data = rom->data;
|
||||
@@ -738,7 +740,7 @@ void *rom_add_blob(const char *name, const void *blob, size_t len,
|
||||
|
||||
snprintf(devpath, sizeof(devpath), "/rom@%s", fw_file_name);
|
||||
|
||||
if (rom_file_in_ram) {
|
||||
if (rom_file_has_mr) {
|
||||
data = rom_set_mr(rom, OBJECT(fw_cfg), devpath);
|
||||
} else {
|
||||
data = rom->data;
|
||||
@@ -773,12 +775,12 @@ int rom_add_elf_program(const char *name, void *data, size_t datasize,
|
||||
|
||||
int rom_add_vga(const char *file)
|
||||
{
|
||||
return rom_add_file(file, "vgaroms", 0, -1);
|
||||
return rom_add_file(file, "vgaroms", 0, -1, true);
|
||||
}
|
||||
|
||||
int rom_add_option(const char *file, int32_t bootindex)
|
||||
{
|
||||
return rom_add_file(file, "genroms", 0, bootindex);
|
||||
return rom_add_file(file, "genroms", 0, bootindex, true);
|
||||
}
|
||||
|
||||
static void rom_reset(void *unused)
|
||||
|
28
hw/core/machine.c
Normal file
28
hw/core/machine.c
Normal file
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* QEMU Machine
|
||||
*
|
||||
* Copyright (C) 2014 Red Hat Inc
|
||||
*
|
||||
* Authors:
|
||||
* Marcel Apfelbaum <marcel.a@redhat.com>
|
||||
*
|
||||
* This work is licensed under the terms of the GNU GPL, version 2 or later.
|
||||
* See the COPYING file in the top-level directory.
|
||||
*/
|
||||
|
||||
#include "hw/boards.h"
|
||||
|
||||
static const TypeInfo machine_info = {
|
||||
.name = TYPE_MACHINE,
|
||||
.parent = TYPE_OBJECT,
|
||||
.abstract = true,
|
||||
.class_size = sizeof(MachineClass),
|
||||
.instance_size = sizeof(MachineState),
|
||||
};
|
||||
|
||||
static void machine_register_types(void)
|
||||
{
|
||||
type_register_static(&machine_info);
|
||||
}
|
||||
|
||||
type_init(machine_register_types)
|
@@ -18,17 +18,19 @@
|
||||
#include "net/hub.h"
|
||||
#include "qapi/visitor.h"
|
||||
#include "sysemu/char.h"
|
||||
#include "sysemu/iothread.h"
|
||||
|
||||
static void get_pointer(Object *obj, Visitor *v, Property *prop,
|
||||
const char *(*print)(void *ptr),
|
||||
char *(*print)(void *ptr),
|
||||
const char *name, Error **errp)
|
||||
{
|
||||
DeviceState *dev = DEVICE(obj);
|
||||
void **ptr = qdev_get_prop_ptr(dev, prop);
|
||||
char *p;
|
||||
|
||||
p = (char *) (*ptr ? print(*ptr) : "");
|
||||
p = *ptr ? print(*ptr) : g_strdup("");
|
||||
visit_type_str(v, &p, name, errp);
|
||||
g_free(p);
|
||||
}
|
||||
|
||||
static void set_pointer(Object *obj, Visitor *v, Property *prop,
|
||||
@@ -91,9 +93,9 @@ static void release_drive(Object *obj, const char *name, void *opaque)
|
||||
}
|
||||
}
|
||||
|
||||
static const char *print_drive(void *ptr)
|
||||
static char *print_drive(void *ptr)
|
||||
{
|
||||
return bdrv_get_device_name(ptr);
|
||||
return g_strdup(bdrv_get_device_name(ptr));
|
||||
}
|
||||
|
||||
static void get_drive(Object *obj, Visitor *v, void *opaque,
|
||||
@@ -145,11 +147,12 @@ static void release_chr(Object *obj, const char *name, void *opaque)
|
||||
}
|
||||
|
||||
|
||||
static const char *print_chr(void *ptr)
|
||||
static char *print_chr(void *ptr)
|
||||
{
|
||||
CharDriverState *chr = ptr;
|
||||
const char *val = chr->label ? chr->label : "";
|
||||
|
||||
return chr->label ? chr->label : "";
|
||||
return g_strdup(val);
|
||||
}
|
||||
|
||||
static void get_chr(Object *obj, Visitor *v, void *opaque,
|
||||
@@ -224,11 +227,12 @@ err:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const char *print_netdev(void *ptr)
|
||||
static char *print_netdev(void *ptr)
|
||||
{
|
||||
NetClientState *netdev = ptr;
|
||||
const char *val = netdev->name ? netdev->name : "";
|
||||
|
||||
return netdev->name ? netdev->name : "";
|
||||
return g_strdup(val);
|
||||
}
|
||||
|
||||
static void get_netdev(Object *obj, Visitor *v, void *opaque,
|
||||
@@ -382,6 +386,56 @@ void qdev_set_nic_properties(DeviceState *dev, NICInfo *nd)
|
||||
nd->instantiated = 1;
|
||||
}
|
||||
|
||||
/* --- iothread --- */
|
||||
|
||||
static char *print_iothread(void *ptr)
|
||||
{
|
||||
return iothread_get_id(ptr);
|
||||
}
|
||||
|
||||
static int parse_iothread(DeviceState *dev, const char *str, void **ptr)
|
||||
{
|
||||
IOThread *iothread;
|
||||
|
||||
iothread = iothread_find(str);
|
||||
if (!iothread) {
|
||||
return -ENOENT;
|
||||
}
|
||||
object_ref(OBJECT(iothread));
|
||||
*ptr = iothread;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void get_iothread(Object *obj, struct Visitor *v, void *opaque,
|
||||
const char *name, Error **errp)
|
||||
{
|
||||
get_pointer(obj, v, opaque, print_iothread, name, errp);
|
||||
}
|
||||
|
||||
static void set_iothread(Object *obj, struct Visitor *v, void *opaque,
|
||||
const char *name, Error **errp)
|
||||
{
|
||||
set_pointer(obj, v, opaque, parse_iothread, name, errp);
|
||||
}
|
||||
|
||||
static void release_iothread(Object *obj, const char *name, void *opaque)
|
||||
{
|
||||
DeviceState *dev = DEVICE(obj);
|
||||
Property *prop = opaque;
|
||||
IOThread **ptr = qdev_get_prop_ptr(dev, prop);
|
||||
|
||||
if (*ptr) {
|
||||
object_unref(OBJECT(*ptr));
|
||||
}
|
||||
}
|
||||
|
||||
PropertyInfo qdev_prop_iothread = {
|
||||
.name = "iothread",
|
||||
.get = get_iothread,
|
||||
.set = set_iothread,
|
||||
.release = release_iothread,
|
||||
};
|
||||
|
||||
static int qdev_add_one_global(QemuOpts *opts, void *opaque)
|
||||
{
|
||||
GlobalProperty *g;
|
||||
|
@@ -501,6 +501,45 @@ static void bus_unparent(Object *obj)
|
||||
}
|
||||
}
|
||||
|
||||
static bool bus_get_realized(Object *obj, Error **err)
|
||||
{
|
||||
BusState *bus = BUS(obj);
|
||||
|
||||
return bus->realized;
|
||||
}
|
||||
|
||||
static void bus_set_realized(Object *obj, bool value, Error **err)
|
||||
{
|
||||
BusState *bus = BUS(obj);
|
||||
BusClass *bc = BUS_GET_CLASS(bus);
|
||||
Error *local_err = NULL;
|
||||
|
||||
if (value && !bus->realized) {
|
||||
if (bc->realize) {
|
||||
bc->realize(bus, &local_err);
|
||||
|
||||
if (local_err != NULL) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
}
|
||||
} else if (!value && bus->realized) {
|
||||
if (bc->unrealize) {
|
||||
bc->unrealize(bus, &local_err);
|
||||
|
||||
if (local_err != NULL) {
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bus->realized = value;
|
||||
return;
|
||||
|
||||
error:
|
||||
error_propagate(err, local_err);
|
||||
}
|
||||
|
||||
void qbus_create_inplace(void *bus, size_t size, const char *typename,
|
||||
DeviceState *parent, const char *name)
|
||||
{
|
||||
@@ -677,6 +716,7 @@ static void device_set_realized(Object *obj, bool value, Error **err)
|
||||
{
|
||||
DeviceState *dev = DEVICE(obj);
|
||||
DeviceClass *dc = DEVICE_GET_CLASS(dev);
|
||||
BusState *bus;
|
||||
Error *local_err = NULL;
|
||||
|
||||
if (dev->hotplugged && !dc->hotpluggable) {
|
||||
@@ -710,14 +750,30 @@ static void device_set_realized(Object *obj, bool value, Error **err)
|
||||
dev->instance_id_alias,
|
||||
dev->alias_required_for_version);
|
||||
}
|
||||
if (local_err == NULL) {
|
||||
QLIST_FOREACH(bus, &dev->child_bus, sibling) {
|
||||
object_property_set_bool(OBJECT(bus), true, "realized",
|
||||
&local_err);
|
||||
if (local_err != NULL) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (dev->hotplugged && local_err == NULL) {
|
||||
device_reset(dev);
|
||||
}
|
||||
} else if (!value && dev->realized) {
|
||||
if (qdev_get_vmsd(dev)) {
|
||||
QLIST_FOREACH(bus, &dev->child_bus, sibling) {
|
||||
object_property_set_bool(OBJECT(bus), false, "realized",
|
||||
&local_err);
|
||||
if (local_err != NULL) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (qdev_get_vmsd(dev) && local_err == NULL) {
|
||||
vmstate_unregister(dev, qdev_get_vmsd(dev), dev);
|
||||
}
|
||||
if (dc->unrealize) {
|
||||
if (dc->unrealize && local_err == NULL) {
|
||||
dc->unrealize(dev, &local_err);
|
||||
}
|
||||
}
|
||||
@@ -735,7 +791,8 @@ static bool device_get_hotpluggable(Object *obj, Error **err)
|
||||
DeviceClass *dc = DEVICE_GET_CLASS(obj);
|
||||
DeviceState *dev = DEVICE(obj);
|
||||
|
||||
return dc->hotpluggable && dev->parent_bus->allow_hotplug;
|
||||
return dc->hotpluggable && (dev->parent_bus == NULL ||
|
||||
dev->parent_bus->allow_hotplug);
|
||||
}
|
||||
|
||||
static void device_initfn(Object *obj)
|
||||
@@ -792,14 +849,6 @@ static void device_class_base_init(ObjectClass *class, void *data)
|
||||
* so do not propagate them to the subclasses.
|
||||
*/
|
||||
klass->props = NULL;
|
||||
|
||||
/* by default all devices were considered as hotpluggable,
|
||||
* so with intent to check it in generic qdev_unplug() /
|
||||
* device_set_realized() functions make every device
|
||||
* hotpluggable. Devices that shouldn't be hotpluggable,
|
||||
* should override it in their class_init()
|
||||
*/
|
||||
klass->hotpluggable = true;
|
||||
}
|
||||
|
||||
static void device_unparent(Object *obj)
|
||||
@@ -809,13 +858,13 @@ static void device_unparent(Object *obj)
|
||||
QObject *event_data;
|
||||
bool have_realized = dev->realized;
|
||||
|
||||
if (dev->realized) {
|
||||
object_property_set_bool(obj, false, "realized", NULL);
|
||||
}
|
||||
while (dev->num_child_bus) {
|
||||
bus = QLIST_FIRST(&dev->child_bus);
|
||||
object_unparent(OBJECT(bus));
|
||||
}
|
||||
if (dev->realized) {
|
||||
object_property_set_bool(obj, false, "realized", NULL);
|
||||
}
|
||||
if (dev->parent_bus) {
|
||||
bus_remove_child(dev->parent_bus, dev);
|
||||
object_unref(OBJECT(dev->parent_bus));
|
||||
@@ -845,6 +894,14 @@ static void device_class_init(ObjectClass *class, void *data)
|
||||
class->unparent = device_unparent;
|
||||
dc->realize = device_realize;
|
||||
dc->unrealize = device_unrealize;
|
||||
|
||||
/* by default all devices were considered as hotpluggable,
|
||||
* so with intent to check it in generic qdev_unplug() /
|
||||
* device_set_realized() functions make every device
|
||||
* hotpluggable. Devices that shouldn't be hotpluggable,
|
||||
* should override it in their class_init()
|
||||
*/
|
||||
dc->hotpluggable = true;
|
||||
}
|
||||
|
||||
void device_reset(DeviceState *dev)
|
||||
@@ -888,6 +945,8 @@ static void qbus_initfn(Object *obj)
|
||||
object_property_add_link(obj, QDEV_HOTPLUG_HANDLER_PROPERTY,
|
||||
TYPE_HOTPLUG_HANDLER,
|
||||
(Object **)&bus->hotplug_handler, NULL);
|
||||
object_property_add_bool(obj, "realized",
|
||||
bus_get_realized, bus_set_realized, NULL);
|
||||
}
|
||||
|
||||
static char *default_bus_get_fw_dev_path(DeviceState *dev)
|
||||
|
@@ -133,11 +133,12 @@ static const VMStateDescription vmstate_ads7846 = {
|
||||
}
|
||||
};
|
||||
|
||||
static int ads7846_init(SSISlave *dev)
|
||||
static int ads7846_init(SSISlave *d)
|
||||
{
|
||||
ADS7846State *s = FROM_SSI_SLAVE(ADS7846State, dev);
|
||||
DeviceState *dev = DEVICE(d);
|
||||
ADS7846State *s = FROM_SSI_SLAVE(ADS7846State, d);
|
||||
|
||||
qdev_init_gpio_out(&dev->qdev, &s->interrupt, 1);
|
||||
qdev_init_gpio_out(dev, &s->interrupt, 1);
|
||||
|
||||
s->input[0] = ADS_TEMP0; /* TEMP0 */
|
||||
s->input[2] = ADS_VBAT; /* VBAT */
|
||||
|
@@ -336,18 +336,19 @@ static const GraphicHwOps ssd0323_ops = {
|
||||
.gfx_update = ssd0323_update_display,
|
||||
};
|
||||
|
||||
static int ssd0323_init(SSISlave *dev)
|
||||
static int ssd0323_init(SSISlave *d)
|
||||
{
|
||||
ssd0323_state *s = FROM_SSI_SLAVE(ssd0323_state, dev);
|
||||
DeviceState *dev = DEVICE(d);
|
||||
ssd0323_state *s = FROM_SSI_SLAVE(ssd0323_state, d);
|
||||
|
||||
s->col_end = 63;
|
||||
s->row_end = 79;
|
||||
s->con = graphic_console_init(DEVICE(dev), 0, &ssd0323_ops, s);
|
||||
s->con = graphic_console_init(dev, 0, &ssd0323_ops, s);
|
||||
qemu_console_resize(s->con, 128 * MAGNIFY, 64 * MAGNIFY);
|
||||
|
||||
qdev_init_gpio_in(&dev->qdev, ssd0323_cd, 1);
|
||||
qdev_init_gpio_in(dev, ssd0323_cd, 1);
|
||||
|
||||
register_savevm(&dev->qdev, "ssd0323_oled", -1, 1,
|
||||
register_savevm(dev, "ssd0323_oled", -1, 1,
|
||||
ssd0323_save, ssd0323_load, s);
|
||||
return 0;
|
||||
}
|
||||
|
@@ -25,6 +25,7 @@
|
||||
#include "hw/loader.h"
|
||||
#include "trace.h"
|
||||
#include "ui/console.h"
|
||||
#include "ui/vnc.h"
|
||||
#include "hw/pci/pci.h"
|
||||
|
||||
#undef VERBOSE
|
||||
@@ -218,7 +219,7 @@ enum {
|
||||
|
||||
/* These values can probably be changed arbitrarily. */
|
||||
#define SVGA_SCRATCH_SIZE 0x8000
|
||||
#define SVGA_MAX_WIDTH 2360
|
||||
#define SVGA_MAX_WIDTH ROUND_UP(2360, VNC_DIRTY_PIXELS_PER_BIT)
|
||||
#define SVGA_MAX_HEIGHT 1770
|
||||
|
||||
#ifdef VERBOSE
|
||||
|
@@ -466,9 +466,15 @@ static void acpi_align_size(GArray *blob, unsigned align)
|
||||
g_array_set_size(blob, ROUND_UP(acpi_data_len(blob), align));
|
||||
}
|
||||
|
||||
/* Get pointer within table in a safe manner */
|
||||
#define ACPI_BUILD_PTR(table, size, off, type) \
|
||||
((type *)(acpi_data_get_ptr(table, size, off, sizeof(type))))
|
||||
/* Set a value within table in a safe manner */
|
||||
#define ACPI_BUILD_SET_LE(table, size, off, bits, val) \
|
||||
do { \
|
||||
uint64_t ACPI_BUILD_SET_LE_val = cpu_to_le64(val); \
|
||||
memcpy(acpi_data_get_ptr(table, size, off, \
|
||||
(bits) / BITS_PER_BYTE), \
|
||||
&ACPI_BUILD_SET_LE_val, \
|
||||
(bits) / BITS_PER_BYTE); \
|
||||
} while (0)
|
||||
|
||||
static inline void *acpi_data_get_ptr(uint8_t *table_data, unsigned table_size,
|
||||
unsigned off, unsigned size)
|
||||
@@ -974,22 +980,17 @@ static void build_pci_bus_end(PCIBus *bus, void *bus_state)
|
||||
|
||||
static void patch_pci_windows(PcPciInfo *pci, uint8_t *start, unsigned size)
|
||||
{
|
||||
*ACPI_BUILD_PTR(start, size, acpi_pci32_start[0], uint32_t) =
|
||||
cpu_to_le32(pci->w32.begin);
|
||||
ACPI_BUILD_SET_LE(start, size, acpi_pci32_start[0], 32, pci->w32.begin);
|
||||
|
||||
*ACPI_BUILD_PTR(start, size, acpi_pci32_end[0], uint32_t) =
|
||||
cpu_to_le32(pci->w32.end - 1);
|
||||
ACPI_BUILD_SET_LE(start, size, acpi_pci32_end[0], 32, pci->w32.end - 1);
|
||||
|
||||
if (pci->w64.end || pci->w64.begin) {
|
||||
*ACPI_BUILD_PTR(start, size, acpi_pci64_valid[0], uint8_t) = 1;
|
||||
*ACPI_BUILD_PTR(start, size, acpi_pci64_start[0], uint64_t) =
|
||||
cpu_to_le64(pci->w64.begin);
|
||||
*ACPI_BUILD_PTR(start, size, acpi_pci64_end[0], uint64_t) =
|
||||
cpu_to_le64(pci->w64.end - 1);
|
||||
*ACPI_BUILD_PTR(start, size, acpi_pci64_length[0], uint64_t) =
|
||||
cpu_to_le64(pci->w64.end - pci->w64.begin);
|
||||
ACPI_BUILD_SET_LE(start, size, acpi_pci64_valid[0], 8, 1);
|
||||
ACPI_BUILD_SET_LE(start, size, acpi_pci64_start[0], 64, pci->w64.begin);
|
||||
ACPI_BUILD_SET_LE(start, size, acpi_pci64_end[0], 64, pci->w64.end - 1);
|
||||
ACPI_BUILD_SET_LE(start, size, acpi_pci64_length[0], 64, pci->w64.end - pci->w64.begin);
|
||||
} else {
|
||||
*ACPI_BUILD_PTR(start, size, acpi_pci64_valid[0], uint8_t) = 0;
|
||||
ACPI_BUILD_SET_LE(start, size, acpi_pci64_valid[0], 8, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -406,7 +406,7 @@ static void patch_instruction(VAPICROMState *s, X86CPU *cpu, target_ulong ip)
|
||||
}
|
||||
|
||||
if (!kvm_enabled()) {
|
||||
cpu_restore_state(env, env->mem_io_pc);
|
||||
cpu_restore_state(cs, cs->mem_io_pc);
|
||||
cpu_get_tb_cpu_state(env, ¤t_pc, ¤t_cs_base,
|
||||
¤t_flags);
|
||||
}
|
||||
@@ -448,8 +448,8 @@ static void patch_instruction(VAPICROMState *s, X86CPU *cpu, target_ulong ip)
|
||||
|
||||
if (!kvm_enabled()) {
|
||||
cs->current_tb = NULL;
|
||||
tb_gen_code(env, current_pc, current_cs_base, current_flags, 1);
|
||||
cpu_resume_from_signal(env, NULL);
|
||||
tb_gen_code(cs, current_pc, current_cs_base, current_flags, 1);
|
||||
cpu_resume_from_signal(cs, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -266,13 +266,15 @@ static void pc_compat_1_7(QEMUMachineInitArgs *args)
|
||||
{
|
||||
smbios_type1_defaults = false;
|
||||
gigabyte_align = false;
|
||||
option_rom_has_mr = true;
|
||||
x86_cpu_compat_disable_kvm_features(FEAT_1_ECX, CPUID_EXT_X2APIC);
|
||||
}
|
||||
|
||||
static void pc_compat_1_6(QEMUMachineInitArgs *args)
|
||||
{
|
||||
pc_compat_1_7(args);
|
||||
has_pci_info = false;
|
||||
rom_file_in_ram = false;
|
||||
rom_file_has_mr = false;
|
||||
has_acpi_build = false;
|
||||
}
|
||||
|
||||
@@ -298,7 +300,7 @@ static void pc_compat_1_3(QEMUMachineInitArgs *args)
|
||||
static void pc_compat_1_2(QEMUMachineInitArgs *args)
|
||||
{
|
||||
pc_compat_1_3(args);
|
||||
disable_kvm_pv_eoi();
|
||||
x86_cpu_compat_disable_kvm_features(FEAT_KVM, KVM_FEATURE_PV_EOI);
|
||||
}
|
||||
|
||||
static void pc_init_pci_1_7(QEMUMachineInitArgs *args)
|
||||
@@ -344,7 +346,7 @@ static void pc_init_pci_no_kvmclock(QEMUMachineInitArgs *args)
|
||||
has_pci_info = false;
|
||||
has_acpi_build = false;
|
||||
smbios_type1_defaults = false;
|
||||
disable_kvm_pv_eoi();
|
||||
x86_cpu_compat_disable_kvm_features(FEAT_KVM, KVM_FEATURE_PV_EOI);
|
||||
enable_compat_apic_id_mode();
|
||||
pc_init1(args, 1, 0);
|
||||
}
|
||||
@@ -357,7 +359,7 @@ static void pc_init_isa(QEMUMachineInitArgs *args)
|
||||
if (!args->cpu_model) {
|
||||
args->cpu_model = "486";
|
||||
}
|
||||
disable_kvm_pv_eoi();
|
||||
x86_cpu_compat_disable_kvm_features(FEAT_KVM, KVM_FEATURE_PV_EOI);
|
||||
enable_compat_apic_id_mode();
|
||||
pc_init1(args, 0, 1);
|
||||
}
|
||||
|
@@ -244,13 +244,15 @@ static void pc_compat_1_7(QEMUMachineInitArgs *args)
|
||||
{
|
||||
smbios_type1_defaults = false;
|
||||
gigabyte_align = false;
|
||||
option_rom_has_mr = true;
|
||||
x86_cpu_compat_disable_kvm_features(FEAT_1_ECX, CPUID_EXT_X2APIC);
|
||||
}
|
||||
|
||||
static void pc_compat_1_6(QEMUMachineInitArgs *args)
|
||||
{
|
||||
pc_compat_1_7(args);
|
||||
has_pci_info = false;
|
||||
rom_file_in_ram = false;
|
||||
rom_file_has_mr = false;
|
||||
has_acpi_build = false;
|
||||
}
|
||||
|
||||
|
@@ -148,7 +148,7 @@ typedef void (*vgic_translate_fn)(GICState *s, int irq, int cpu,
|
||||
uint32_t *field, bool to_kernel);
|
||||
|
||||
/* synthetic translate function used for clear/set registers to completely
|
||||
* clear a setting using a clear-register before setting the remaing bits
|
||||
* clear a setting using a clear-register before setting the remaining bits
|
||||
* using a set-register */
|
||||
static void translate_clear(GICState *s, int irq, int cpu,
|
||||
uint32_t *field, bool to_kernel)
|
||||
|
@@ -269,7 +269,16 @@ static void ics_kvm_set_irq(void *opaque, int srcno, int val)
|
||||
|
||||
static void ics_kvm_reset(DeviceState *dev)
|
||||
{
|
||||
ics_set_kvm_state(ICS(dev), 1);
|
||||
ICSState *ics = ICS(dev);
|
||||
int i;
|
||||
|
||||
memset(ics->irqs, 0, sizeof(ICSIRQState) * ics->nr_irqs);
|
||||
for (i = 0; i < ics->nr_irqs; i++) {
|
||||
ics->irqs[i].priority = 0xff;
|
||||
ics->irqs[i].saved_priority = 0xff;
|
||||
}
|
||||
|
||||
ics_set_kvm_state(ics, 1);
|
||||
}
|
||||
|
||||
static void ics_kvm_realize(DeviceState *dev, Error **errp)
|
||||
|
@@ -13,7 +13,8 @@
|
||||
#include "hw/ssi.h"
|
||||
|
||||
typedef struct {
|
||||
SSISlave ssidev;
|
||||
SSISlave parent_obj;
|
||||
|
||||
qemu_irq interrupt;
|
||||
uint8_t tb1, rb2, rb3;
|
||||
int cycle;
|
||||
@@ -22,6 +23,14 @@ typedef struct {
|
||||
int inputs, com;
|
||||
} MAX111xState;
|
||||
|
||||
#define TYPE_MAX_111X "max111x"
|
||||
|
||||
#define MAX_111X(obj) \
|
||||
OBJECT_CHECK(MAX111xState, (obj), TYPE_MAX_111X)
|
||||
|
||||
#define TYPE_MAX_1110 "max1110"
|
||||
#define TYPE_MAX_1111 "max1111"
|
||||
|
||||
/* Control-byte bitfields */
|
||||
#define CB_PD0 (1 << 0)
|
||||
#define CB_PD1 (1 << 1)
|
||||
@@ -92,7 +101,7 @@ static void max111x_write(MAX111xState *s, uint32_t value)
|
||||
|
||||
static uint32_t max111x_transfer(SSISlave *dev, uint32_t value)
|
||||
{
|
||||
MAX111xState *s = FROM_SSI_SLAVE(MAX111xState, dev);
|
||||
MAX111xState *s = MAX_111X(dev);
|
||||
max111x_write(s, value);
|
||||
return max111x_read(s);
|
||||
}
|
||||
@@ -103,7 +112,7 @@ static const VMStateDescription vmstate_max111x = {
|
||||
.minimum_version_id = 1,
|
||||
.minimum_version_id_old = 1,
|
||||
.fields = (VMStateField[]) {
|
||||
VMSTATE_SSI_SLAVE(ssidev, MAX111xState),
|
||||
VMSTATE_SSI_SLAVE(parent_obj, MAX111xState),
|
||||
VMSTATE_UINT8(tb1, MAX111xState),
|
||||
VMSTATE_UINT8(rb2, MAX111xState),
|
||||
VMSTATE_UINT8(rb3, MAX111xState),
|
||||
@@ -115,11 +124,12 @@ static const VMStateDescription vmstate_max111x = {
|
||||
}
|
||||
};
|
||||
|
||||
static int max111x_init(SSISlave *dev, int inputs)
|
||||
static int max111x_init(SSISlave *d, int inputs)
|
||||
{
|
||||
MAX111xState *s = FROM_SSI_SLAVE(MAX111xState, dev);
|
||||
DeviceState *dev = DEVICE(d);
|
||||
MAX111xState *s = MAX_111X(dev);
|
||||
|
||||
qdev_init_gpio_out(&dev->qdev, &s->interrupt, 1);
|
||||
qdev_init_gpio_out(dev, &s->interrupt, 1);
|
||||
|
||||
s->inputs = inputs;
|
||||
/* TODO: add a user interface for setting these */
|
||||
@@ -133,7 +143,7 @@ static int max111x_init(SSISlave *dev, int inputs)
|
||||
s->input[7] = 0x80;
|
||||
s->com = 0;
|
||||
|
||||
vmstate_register(&dev->qdev, -1, &vmstate_max111x, s);
|
||||
vmstate_register(dev, -1, &vmstate_max111x, s);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -149,23 +159,36 @@ static int max1111_init(SSISlave *dev)
|
||||
|
||||
void max111x_set_input(DeviceState *dev, int line, uint8_t value)
|
||||
{
|
||||
MAX111xState *s = FROM_SSI_SLAVE(MAX111xState, SSI_SLAVE_FROM_QDEV(dev));
|
||||
MAX111xState *s = MAX_111X(dev);
|
||||
assert(line >= 0 && line < s->inputs);
|
||||
s->input[line] = value;
|
||||
}
|
||||
|
||||
static void max111x_class_init(ObjectClass *klass, void *data)
|
||||
{
|
||||
SSISlaveClass *k = SSI_SLAVE_CLASS(klass);
|
||||
|
||||
k->transfer = max111x_transfer;
|
||||
}
|
||||
|
||||
static const TypeInfo max111x_info = {
|
||||
.name = TYPE_MAX_111X,
|
||||
.parent = TYPE_SSI_SLAVE,
|
||||
.instance_size = sizeof(MAX111xState),
|
||||
.class_init = max111x_class_init,
|
||||
.abstract = true,
|
||||
};
|
||||
|
||||
static void max1110_class_init(ObjectClass *klass, void *data)
|
||||
{
|
||||
SSISlaveClass *k = SSI_SLAVE_CLASS(klass);
|
||||
|
||||
k->init = max1110_init;
|
||||
k->transfer = max111x_transfer;
|
||||
}
|
||||
|
||||
static const TypeInfo max1110_info = {
|
||||
.name = "max1110",
|
||||
.parent = TYPE_SSI_SLAVE,
|
||||
.instance_size = sizeof(MAX111xState),
|
||||
.name = TYPE_MAX_1110,
|
||||
.parent = TYPE_MAX_111X,
|
||||
.class_init = max1110_class_init,
|
||||
};
|
||||
|
||||
@@ -174,18 +197,17 @@ static void max1111_class_init(ObjectClass *klass, void *data)
|
||||
SSISlaveClass *k = SSI_SLAVE_CLASS(klass);
|
||||
|
||||
k->init = max1111_init;
|
||||
k->transfer = max111x_transfer;
|
||||
}
|
||||
|
||||
static const TypeInfo max1111_info = {
|
||||
.name = "max1111",
|
||||
.parent = TYPE_SSI_SLAVE,
|
||||
.instance_size = sizeof(MAX111xState),
|
||||
.name = TYPE_MAX_1111,
|
||||
.parent = TYPE_MAX_111X,
|
||||
.class_init = max1111_class_init,
|
||||
};
|
||||
|
||||
static void max111x_register_types(void)
|
||||
{
|
||||
type_register_static(&max111x_info);
|
||||
type_register_static(&max1110_info);
|
||||
type_register_static(&max1111_info);
|
||||
}
|
||||
|
@@ -195,8 +195,8 @@ static void process_tx_fcb(eTSEC *etsec)
|
||||
|
||||
/* if packet is IP4 and IP checksum is requested */
|
||||
if (flags & FCB_TX_IP && flags & FCB_TX_CIP) {
|
||||
/* do IP4 checksum (TODO This funtion does TCP/UDP checksum but not sure
|
||||
* if it also does IP4 checksum. */
|
||||
/* do IP4 checksum (TODO This function does TCP/UDP checksum
|
||||
* but not sure if it also does IP4 checksum.) */
|
||||
net_checksum_calculate(etsec->tx_buffer + 8,
|
||||
etsec->tx_buffer_len - 8);
|
||||
}
|
||||
@@ -592,7 +592,7 @@ void etsec_walk_rx_ring(eTSEC *etsec, int ring_nbr)
|
||||
|
||||
/* TODO: Broadcast and Multicast */
|
||||
|
||||
if (bd.flags | BD_INTERRUPT) {
|
||||
if (bd.flags & BD_INTERRUPT) {
|
||||
/* Set RXFx */
|
||||
etsec->regs[RSTAT].value |= 1 << (7 - ring_nbr);
|
||||
|
||||
@@ -601,7 +601,7 @@ void etsec_walk_rx_ring(eTSEC *etsec, int ring_nbr)
|
||||
}
|
||||
|
||||
} else {
|
||||
if (bd.flags | BD_INTERRUPT) {
|
||||
if (bd.flags & BD_INTERRUPT) {
|
||||
/* Set IEVENT */
|
||||
ievent_set(etsec, IEVENT_RXB);
|
||||
}
|
||||
|
@@ -28,7 +28,9 @@
|
||||
#include "hw/pci/pci_bus.h"
|
||||
#include "hw/pci/pci_host.h"
|
||||
#include "hw/i386/pc.h"
|
||||
#include "hw/loader.h"
|
||||
#include "exec/address-spaces.h"
|
||||
#include "elf.h"
|
||||
|
||||
#define TYPE_RAVEN_PCI_DEVICE "raven"
|
||||
#define TYPE_RAVEN_PCI_HOST_BRIDGE "raven-pcihost"
|
||||
@@ -38,6 +40,10 @@
|
||||
|
||||
typedef struct RavenPCIState {
|
||||
PCIDevice dev;
|
||||
|
||||
uint32_t elf_machine;
|
||||
char *bios_name;
|
||||
MemoryRegion bios;
|
||||
} RavenPCIState;
|
||||
|
||||
#define RAVEN_PCI_HOST_BRIDGE(obj) \
|
||||
@@ -52,6 +58,8 @@ typedef struct PRePPCIState {
|
||||
RavenPCIState pci_dev;
|
||||
} PREPPCIState;
|
||||
|
||||
#define BIOS_SIZE (1024 * 1024)
|
||||
|
||||
static inline uint32_t PPC_PCIIO_config(hwaddr addr)
|
||||
{
|
||||
int i;
|
||||
@@ -169,10 +177,45 @@ static void raven_pcihost_initfn(Object *obj)
|
||||
|
||||
static int raven_init(PCIDevice *d)
|
||||
{
|
||||
RavenPCIState *s = RAVEN_PCI_DEVICE(d);
|
||||
char *filename;
|
||||
int bios_size = -1;
|
||||
|
||||
d->config[0x0C] = 0x08; // cache_line_size
|
||||
d->config[0x0D] = 0x10; // latency_timer
|
||||
d->config[0x34] = 0x00; // capabilities_pointer
|
||||
|
||||
memory_region_init_ram(&s->bios, OBJECT(s), "bios", BIOS_SIZE);
|
||||
memory_region_set_readonly(&s->bios, true);
|
||||
memory_region_add_subregion(get_system_memory(), (uint32_t)(-BIOS_SIZE),
|
||||
&s->bios);
|
||||
vmstate_register_ram_global(&s->bios);
|
||||
if (s->bios_name) {
|
||||
filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, s->bios_name);
|
||||
if (filename) {
|
||||
if (s->elf_machine != EM_NONE) {
|
||||
bios_size = load_elf(filename, NULL, NULL, NULL,
|
||||
NULL, NULL, 1, s->elf_machine, 0);
|
||||
}
|
||||
if (bios_size < 0) {
|
||||
bios_size = get_image_size(filename);
|
||||
if (bios_size > 0 && bios_size <= BIOS_SIZE) {
|
||||
hwaddr bios_addr;
|
||||
bios_size = (bios_size + 0xfff) & ~0xfff;
|
||||
bios_addr = (uint32_t)(-BIOS_SIZE);
|
||||
bios_size = load_image_targphys(filename, bios_addr,
|
||||
bios_size);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (bios_size < 0 || bios_size > BIOS_SIZE) {
|
||||
hw_error("qemu: could not load bios image '%s'\n", s->bios_name);
|
||||
}
|
||||
if (filename) {
|
||||
g_free(filename);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -212,12 +255,20 @@ static const TypeInfo raven_info = {
|
||||
.class_init = raven_class_init,
|
||||
};
|
||||
|
||||
static Property raven_pcihost_properties[] = {
|
||||
DEFINE_PROP_UINT32("elf-machine", PREPPCIState, pci_dev.elf_machine,
|
||||
EM_NONE),
|
||||
DEFINE_PROP_STRING("bios-name", PREPPCIState, pci_dev.bios_name),
|
||||
DEFINE_PROP_END_OF_LIST()
|
||||
};
|
||||
|
||||
static void raven_pcihost_class_init(ObjectClass *klass, void *data)
|
||||
{
|
||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||
|
||||
set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
|
||||
dc->realize = raven_pcihost_realizefn;
|
||||
dc->props = raven_pcihost_properties;
|
||||
dc->fw_name = "pci";
|
||||
}
|
||||
|
||||
|
@@ -272,7 +272,7 @@ static void mch_update_smram(MCHPCIState *mch)
|
||||
PCIDevice *pd = PCI_DEVICE(mch);
|
||||
|
||||
memory_region_transaction_begin();
|
||||
smram_update(&mch->smram_region, pd->config[MCH_HOST_BRDIGE_SMRAM],
|
||||
smram_update(&mch->smram_region, pd->config[MCH_HOST_BRIDGE_SMRAM],
|
||||
mch->smm_enabled);
|
||||
memory_region_transaction_commit();
|
||||
}
|
||||
@@ -283,7 +283,7 @@ static void mch_set_smm(int smm, void *arg)
|
||||
PCIDevice *pd = PCI_DEVICE(mch);
|
||||
|
||||
memory_region_transaction_begin();
|
||||
smram_set_smm(&mch->smm_enabled, smm, pd->config[MCH_HOST_BRDIGE_SMRAM],
|
||||
smram_set_smm(&mch->smm_enabled, smm, pd->config[MCH_HOST_BRIDGE_SMRAM],
|
||||
&mch->smram_region);
|
||||
memory_region_transaction_commit();
|
||||
}
|
||||
@@ -306,8 +306,8 @@ static void mch_write_config(PCIDevice *d,
|
||||
mch_update_pciexbar(mch);
|
||||
}
|
||||
|
||||
if (ranges_overlap(address, len, MCH_HOST_BRDIGE_SMRAM,
|
||||
MCH_HOST_BRDIGE_SMRAM_SIZE)) {
|
||||
if (ranges_overlap(address, len, MCH_HOST_BRIDGE_SMRAM,
|
||||
MCH_HOST_BRIDGE_SMRAM_SIZE)) {
|
||||
mch_update_smram(mch);
|
||||
}
|
||||
}
|
||||
@@ -347,7 +347,7 @@ static void mch_reset(DeviceState *qdev)
|
||||
pci_set_quad(d->config + MCH_HOST_BRIDGE_PCIEXBAR,
|
||||
MCH_HOST_BRIDGE_PCIEXBAR_DEFAULT);
|
||||
|
||||
d->config[MCH_HOST_BRDIGE_SMRAM] = MCH_HOST_BRIDGE_SMRAM_DEFAULT;
|
||||
d->config[MCH_HOST_BRIDGE_SMRAM] = MCH_HOST_BRIDGE_SMRAM_DEFAULT;
|
||||
|
||||
mch_update(mch);
|
||||
}
|
||||
|
51
hw/pci/pci.c
51
hw/pci/pci.c
@@ -48,7 +48,6 @@ static void pcibus_dev_print(Monitor *mon, DeviceState *dev, int indent);
|
||||
static char *pcibus_get_dev_path(DeviceState *dev);
|
||||
static char *pcibus_get_fw_dev_path(DeviceState *dev);
|
||||
static void pcibus_reset(BusState *qbus);
|
||||
static void pci_bus_finalize(Object *obj);
|
||||
|
||||
static Property pci_props[] = {
|
||||
DEFINE_PROP_PCI_DEVFN("addr", PCIDevice, devfn, -1),
|
||||
@@ -61,6 +60,34 @@ static Property pci_props[] = {
|
||||
DEFINE_PROP_END_OF_LIST()
|
||||
};
|
||||
|
||||
static const VMStateDescription vmstate_pcibus = {
|
||||
.name = "PCIBUS",
|
||||
.version_id = 1,
|
||||
.minimum_version_id = 1,
|
||||
.minimum_version_id_old = 1,
|
||||
.fields = (VMStateField[]) {
|
||||
VMSTATE_INT32_EQUAL(nirq, PCIBus),
|
||||
VMSTATE_VARRAY_INT32(irq_count, PCIBus,
|
||||
nirq, 0, vmstate_info_int32,
|
||||
int32_t),
|
||||
VMSTATE_END_OF_LIST()
|
||||
}
|
||||
};
|
||||
|
||||
static void pci_bus_realize(BusState *qbus, Error **errp)
|
||||
{
|
||||
PCIBus *bus = PCI_BUS(qbus);
|
||||
|
||||
vmstate_register(NULL, -1, &vmstate_pcibus, bus);
|
||||
}
|
||||
|
||||
static void pci_bus_unrealize(BusState *qbus, Error **errp)
|
||||
{
|
||||
PCIBus *bus = PCI_BUS(qbus);
|
||||
|
||||
vmstate_unregister(NULL, &vmstate_pcibus, bus);
|
||||
}
|
||||
|
||||
static void pci_bus_class_init(ObjectClass *klass, void *data)
|
||||
{
|
||||
BusClass *k = BUS_CLASS(klass);
|
||||
@@ -68,6 +95,8 @@ static void pci_bus_class_init(ObjectClass *klass, void *data)
|
||||
k->print_dev = pcibus_dev_print;
|
||||
k->get_dev_path = pcibus_get_dev_path;
|
||||
k->get_fw_dev_path = pcibus_get_fw_dev_path;
|
||||
k->realize = pci_bus_realize;
|
||||
k->unrealize = pci_bus_unrealize;
|
||||
k->reset = pcibus_reset;
|
||||
}
|
||||
|
||||
@@ -75,7 +104,6 @@ static const TypeInfo pci_bus_info = {
|
||||
.name = TYPE_PCI_BUS,
|
||||
.parent = TYPE_BUS,
|
||||
.instance_size = sizeof(PCIBus),
|
||||
.instance_finalize = pci_bus_finalize,
|
||||
.class_init = pci_bus_class_init,
|
||||
};
|
||||
|
||||
@@ -95,17 +123,6 @@ static uint16_t pci_default_sub_device_id = PCI_SUBDEVICE_ID_QEMU;
|
||||
|
||||
static QLIST_HEAD(, PCIHostState) pci_host_bridges;
|
||||
|
||||
static const VMStateDescription vmstate_pcibus = {
|
||||
.name = "PCIBUS",
|
||||
.version_id = 1,
|
||||
.minimum_version_id = 1,
|
||||
.minimum_version_id_old = 1,
|
||||
.fields = (VMStateField []) {
|
||||
VMSTATE_INT32_EQUAL(nirq, PCIBus),
|
||||
VMSTATE_VARRAY_INT32(irq_count, PCIBus, nirq, 0, vmstate_info_int32, int32_t),
|
||||
VMSTATE_END_OF_LIST()
|
||||
}
|
||||
};
|
||||
static int pci_bar(PCIDevice *d, int reg)
|
||||
{
|
||||
uint8_t type;
|
||||
@@ -299,8 +316,6 @@ static void pci_bus_init(PCIBus *bus, DeviceState *parent,
|
||||
QLIST_INIT(&bus->child);
|
||||
|
||||
pci_host_bus_register(bus, parent);
|
||||
|
||||
vmstate_register(NULL, -1, &vmstate_pcibus, bus);
|
||||
}
|
||||
|
||||
bool pci_bus_is_express(PCIBus *bus)
|
||||
@@ -369,12 +384,6 @@ int pci_bus_num(PCIBus *s)
|
||||
return s->parent_dev->config[PCI_SECONDARY_BUS];
|
||||
}
|
||||
|
||||
static void pci_bus_finalize(Object *obj)
|
||||
{
|
||||
PCIBus *bus = PCI_BUS(obj);
|
||||
vmstate_unregister(NULL, &vmstate_pcibus, bus);
|
||||
}
|
||||
|
||||
static int get_pci_config_device(QEMUFile *f, void *pv, size_t size)
|
||||
{
|
||||
PCIDevice *s = container_of(pv, PCIDevice, config);
|
||||
|
@@ -472,14 +472,13 @@ static void ppce500_cpu_reset_sec(void *opaque)
|
||||
{
|
||||
PowerPCCPU *cpu = opaque;
|
||||
CPUState *cs = CPU(cpu);
|
||||
CPUPPCState *env = &cpu->env;
|
||||
|
||||
cpu_reset(cs);
|
||||
|
||||
/* Secondary CPU starts in halted state for now. Needs to change when
|
||||
implementing non-kernel boot. */
|
||||
cs->halted = 1;
|
||||
env->exception_index = EXCP_HLT;
|
||||
cs->exception_index = EXCP_HLT;
|
||||
}
|
||||
|
||||
static void ppce500_cpu_reset(void *opaque)
|
||||
|
@@ -44,7 +44,7 @@
|
||||
ram_addr_t ppc405_set_bootinfo (CPUPPCState *env, ppc4xx_bd_info_t *bd,
|
||||
uint32_t flags)
|
||||
{
|
||||
CPUState *cs = ENV_GET_CPU(env);
|
||||
CPUState *cs = CPU(ppc_env_get_cpu(env));
|
||||
ram_addr_t bdloc;
|
||||
int i, n;
|
||||
|
||||
|
@@ -117,7 +117,7 @@ static void spin_kick(void *data)
|
||||
mmubooke_create_initial_mapping(env, 0, map_start, map_size);
|
||||
|
||||
cpu->halted = 0;
|
||||
env->exception_index = -1;
|
||||
cpu->exception_index = -1;
|
||||
cpu->stopped = false;
|
||||
qemu_cpu_kick(cpu);
|
||||
}
|
||||
|
@@ -456,7 +456,6 @@ static void ppc_prep_init(QEMUMachineInitArgs *args)
|
||||
MemoryRegion *sysmem = get_system_memory();
|
||||
PowerPCCPU *cpu = NULL;
|
||||
CPUPPCState *env = NULL;
|
||||
char *filename;
|
||||
nvram_t nvram;
|
||||
M48t59State *m48t59;
|
||||
MemoryRegion *PPC_io_memory = g_new(MemoryRegion, 1);
|
||||
@@ -464,9 +463,8 @@ static void ppc_prep_init(QEMUMachineInitArgs *args)
|
||||
#if 0
|
||||
MemoryRegion *xcsr = g_new(MemoryRegion, 1);
|
||||
#endif
|
||||
int linux_boot, i, nb_nics1, bios_size;
|
||||
int linux_boot, i, nb_nics1;
|
||||
MemoryRegion *ram = g_new(MemoryRegion, 1);
|
||||
MemoryRegion *bios = g_new(MemoryRegion, 1);
|
||||
uint32_t kernel_base, initrd_base;
|
||||
long kernel_size, initrd_size;
|
||||
DeviceState *dev;
|
||||
@@ -509,43 +507,6 @@ static void ppc_prep_init(QEMUMachineInitArgs *args)
|
||||
vmstate_register_ram_global(ram);
|
||||
memory_region_add_subregion(sysmem, 0, ram);
|
||||
|
||||
/* allocate and load BIOS */
|
||||
memory_region_init_ram(bios, NULL, "ppc_prep.bios", BIOS_SIZE);
|
||||
memory_region_set_readonly(bios, true);
|
||||
memory_region_add_subregion(sysmem, (uint32_t)(-BIOS_SIZE), bios);
|
||||
vmstate_register_ram_global(bios);
|
||||
if (bios_name == NULL)
|
||||
bios_name = BIOS_FILENAME;
|
||||
filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
|
||||
if (filename) {
|
||||
bios_size = load_elf(filename, NULL, NULL, NULL,
|
||||
NULL, NULL, 1, ELF_MACHINE, 0);
|
||||
if (bios_size < 0) {
|
||||
bios_size = get_image_size(filename);
|
||||
if (bios_size > 0 && bios_size <= BIOS_SIZE) {
|
||||
hwaddr bios_addr;
|
||||
bios_size = (bios_size + 0xfff) & ~0xfff;
|
||||
bios_addr = (uint32_t)(-bios_size);
|
||||
bios_size = load_image_targphys(filename, bios_addr, bios_size);
|
||||
}
|
||||
if (bios_size > BIOS_SIZE) {
|
||||
fprintf(stderr, "qemu: PReP bios '%s' is too large (0x%x)\n",
|
||||
bios_name, bios_size);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
bios_size = -1;
|
||||
}
|
||||
if (bios_size < 0 && !qtest_enabled()) {
|
||||
fprintf(stderr, "qemu: could not load PPC PReP bios '%s'\n",
|
||||
bios_name);
|
||||
exit(1);
|
||||
}
|
||||
if (filename) {
|
||||
g_free(filename);
|
||||
}
|
||||
|
||||
if (linux_boot) {
|
||||
kernel_base = KERNEL_LOAD_ADDR;
|
||||
/* now we can load the kernel */
|
||||
@@ -593,6 +554,11 @@ static void ppc_prep_init(QEMUMachineInitArgs *args)
|
||||
}
|
||||
|
||||
dev = qdev_create(NULL, "raven-pcihost");
|
||||
if (bios_name == NULL) {
|
||||
bios_name = BIOS_FILENAME;
|
||||
}
|
||||
qdev_prop_set_string(dev, "bios-name", bios_name);
|
||||
qdev_prop_set_uint32(dev, "elf-machine", ELF_MACHINE);
|
||||
pcihost = PCI_HOST_BRIDGE(dev);
|
||||
object_property_add_child(qdev_get_machine(), "raven", OBJECT(dev), NULL);
|
||||
qdev_init_nofail(dev);
|
||||
|
@@ -781,13 +781,15 @@ static int spapr_vga_init(PCIBus *pci_bus)
|
||||
{
|
||||
switch (vga_interface_type) {
|
||||
case VGA_NONE:
|
||||
return false;
|
||||
case VGA_DEVICE:
|
||||
return true;
|
||||
case VGA_STD:
|
||||
return pci_vga_init(pci_bus) != NULL;
|
||||
default:
|
||||
fprintf(stderr, "This vga model is not supported,"
|
||||
"currently it only supports -vga std\n");
|
||||
exit(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -356,7 +356,7 @@ static target_ulong h_set_dabr(PowerPCCPU *cpu, sPAPREnvironment *spapr,
|
||||
|
||||
static target_ulong register_vpa(CPUPPCState *env, target_ulong vpa)
|
||||
{
|
||||
CPUState *cs = ENV_GET_CPU(env);
|
||||
CPUState *cs = CPU(ppc_env_get_cpu(env));
|
||||
uint16_t size;
|
||||
uint8_t tmp;
|
||||
|
||||
@@ -406,7 +406,7 @@ static target_ulong deregister_vpa(CPUPPCState *env, target_ulong vpa)
|
||||
|
||||
static target_ulong register_slb_shadow(CPUPPCState *env, target_ulong addr)
|
||||
{
|
||||
CPUState *cs = ENV_GET_CPU(env);
|
||||
CPUState *cs = CPU(ppc_env_get_cpu(env));
|
||||
uint32_t size;
|
||||
|
||||
if (addr == 0) {
|
||||
@@ -442,7 +442,7 @@ static target_ulong deregister_slb_shadow(CPUPPCState *env, target_ulong addr)
|
||||
|
||||
static target_ulong register_dtl(CPUPPCState *env, target_ulong addr)
|
||||
{
|
||||
CPUState *cs = ENV_GET_CPU(env);
|
||||
CPUState *cs = CPU(ppc_env_get_cpu(env));
|
||||
uint32_t size;
|
||||
|
||||
if (addr == 0) {
|
||||
@@ -529,7 +529,7 @@ static target_ulong h_cede(PowerPCCPU *cpu, sPAPREnvironment *spapr,
|
||||
hreg_compute_hflags(env);
|
||||
if (!cpu_has_work(cs)) {
|
||||
cs->halted = 1;
|
||||
env->exception_index = EXCP_HLT;
|
||||
cs->exception_index = EXCP_HLT;
|
||||
cs->exit_request = 1;
|
||||
}
|
||||
return H_SUCCESS;
|
||||
|
@@ -32,6 +32,7 @@
|
||||
#include "exec/address-spaces.h"
|
||||
#include <libfdt.h>
|
||||
#include "trace.h"
|
||||
#include "qemu/error-report.h"
|
||||
|
||||
#include "hw/pci/pci_bus.h"
|
||||
|
||||
@@ -292,7 +293,7 @@ static void rtas_ibm_change_msi(PowerPCCPU *cpu, sPAPREnvironment *spapr,
|
||||
ret_intr_type = RTAS_TYPE_MSIX;
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "rtas_ibm_change_msi(%u) is not implemented\n", func);
|
||||
error_report("rtas_ibm_change_msi(%u) is not implemented", func);
|
||||
rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
|
||||
return;
|
||||
}
|
||||
@@ -326,7 +327,7 @@ static void rtas_ibm_change_msi(PowerPCCPU *cpu, sPAPREnvironment *spapr,
|
||||
/* Find a device number in the map to add or reuse the existing one */
|
||||
ndev = spapr_msicfg_find(phb, config_addr, true);
|
||||
if (ndev >= SPAPR_MSIX_MAX_DEVS || ndev < 0) {
|
||||
fprintf(stderr, "No free entry for a new MSI device\n");
|
||||
error_report("No free entry for a new MSI device");
|
||||
rtas_st(rets, 0, RTAS_OUT_HW_ERROR);
|
||||
return;
|
||||
}
|
||||
@@ -335,7 +336,7 @@ static void rtas_ibm_change_msi(PowerPCCPU *cpu, sPAPREnvironment *spapr,
|
||||
/* Check if there is an old config and MSI number has not changed */
|
||||
if (phb->msi_table[ndev].nvec && (req_num != phb->msi_table[ndev].nvec)) {
|
||||
/* Unexpected behaviour */
|
||||
fprintf(stderr, "Cannot reuse MSI config for device#%d", ndev);
|
||||
error_report("Cannot reuse MSI config for device#%d", ndev);
|
||||
rtas_st(rets, 0, RTAS_OUT_HW_ERROR);
|
||||
return;
|
||||
}
|
||||
@@ -345,7 +346,7 @@ static void rtas_ibm_change_msi(PowerPCCPU *cpu, sPAPREnvironment *spapr,
|
||||
irq = spapr_allocate_irq_block(req_num, false,
|
||||
ret_intr_type == RTAS_TYPE_MSI);
|
||||
if (irq < 0) {
|
||||
fprintf(stderr, "Cannot allocate MSIs for device#%d", ndev);
|
||||
error_report("Cannot allocate MSIs for device#%d", ndev);
|
||||
rtas_st(rets, 0, RTAS_OUT_HW_ERROR);
|
||||
return;
|
||||
}
|
||||
@@ -505,12 +506,11 @@ static AddressSpace *spapr_pci_dma_iommu(PCIBus *bus, void *opaque, int devfn)
|
||||
return &phb->iommu_as;
|
||||
}
|
||||
|
||||
static int spapr_phb_init(SysBusDevice *s)
|
||||
static void spapr_phb_realize(DeviceState *dev, Error **errp)
|
||||
{
|
||||
DeviceState *dev = DEVICE(s);
|
||||
SysBusDevice *s = SYS_BUS_DEVICE(dev);
|
||||
sPAPRPHBState *sphb = SPAPR_PCI_HOST_BRIDGE(s);
|
||||
PCIHostState *phb = PCI_HOST_BRIDGE(s);
|
||||
const char *busname;
|
||||
char *namebuf;
|
||||
int i;
|
||||
PCIBus *bus;
|
||||
@@ -521,9 +521,9 @@ static int spapr_phb_init(SysBusDevice *s)
|
||||
if ((sphb->buid != -1) || (sphb->dma_liobn != -1)
|
||||
|| (sphb->mem_win_addr != -1)
|
||||
|| (sphb->io_win_addr != -1)) {
|
||||
fprintf(stderr, "Either \"index\" or other parameters must"
|
||||
" be specified for PAPR PHB, not both\n");
|
||||
return -1;
|
||||
error_setg(errp, "Either \"index\" or other parameters must"
|
||||
" be specified for PAPR PHB, not both");
|
||||
return;
|
||||
}
|
||||
|
||||
sphb->buid = SPAPR_PCI_BASE_BUID + sphb->index;
|
||||
@@ -536,28 +536,28 @@ static int spapr_phb_init(SysBusDevice *s)
|
||||
}
|
||||
|
||||
if (sphb->buid == -1) {
|
||||
fprintf(stderr, "BUID not specified for PHB\n");
|
||||
return -1;
|
||||
error_setg(errp, "BUID not specified for PHB");
|
||||
return;
|
||||
}
|
||||
|
||||
if (sphb->dma_liobn == -1) {
|
||||
fprintf(stderr, "LIOBN not specified for PHB\n");
|
||||
return -1;
|
||||
error_setg(errp, "LIOBN not specified for PHB");
|
||||
return;
|
||||
}
|
||||
|
||||
if (sphb->mem_win_addr == -1) {
|
||||
fprintf(stderr, "Memory window address not specified for PHB\n");
|
||||
return -1;
|
||||
error_setg(errp, "Memory window address not specified for PHB");
|
||||
return;
|
||||
}
|
||||
|
||||
if (sphb->io_win_addr == -1) {
|
||||
fprintf(stderr, "IO window address not specified for PHB\n");
|
||||
return -1;
|
||||
error_setg(errp, "IO window address not specified for PHB");
|
||||
return;
|
||||
}
|
||||
|
||||
if (find_phb(spapr, sphb->buid)) {
|
||||
fprintf(stderr, "PCI host bridges must have unique BUIDs\n");
|
||||
return -1;
|
||||
error_setg(errp, "PCI host bridges must have unique BUIDs");
|
||||
return;
|
||||
}
|
||||
|
||||
sphb->dtbusname = g_strdup_printf("pci@%" PRIx64, sphb->buid);
|
||||
@@ -594,26 +594,8 @@ static int spapr_phb_init(SysBusDevice *s)
|
||||
get_system_io(), 0, SPAPR_PCI_IO_WIN_SIZE);
|
||||
memory_region_add_subregion(get_system_memory(), sphb->io_win_addr,
|
||||
&sphb->iowindow);
|
||||
/*
|
||||
* Selecting a busname is more complex than you'd think, due to
|
||||
* interacting constraints. If the user has specified an id
|
||||
* explicitly for the phb , then we want to use the qdev default
|
||||
* of naming the bus based on the bridge device (so the user can
|
||||
* then assign devices to it in the way they expect). For the
|
||||
* first / default PCI bus (index=0) we want to use just "pci"
|
||||
* because libvirt expects there to be a bus called, simply,
|
||||
* "pci". Otherwise, we use the same name as in the device tree,
|
||||
* since it's unique by construction, and makes the guest visible
|
||||
* BUID clear.
|
||||
*/
|
||||
if (dev->id) {
|
||||
busname = NULL;
|
||||
} else if (sphb->index == 0) {
|
||||
busname = "pci";
|
||||
} else {
|
||||
busname = sphb->dtbusname;
|
||||
}
|
||||
bus = pci_register_bus(dev, busname,
|
||||
|
||||
bus = pci_register_bus(dev, NULL,
|
||||
pci_spapr_set_irq, pci_spapr_map_irq, sphb,
|
||||
&sphb->memspace, &sphb->iospace,
|
||||
PCI_DEVFN(0, 0), PCI_NUM_PINS, TYPE_PCI_BUS);
|
||||
@@ -624,8 +606,9 @@ static int spapr_phb_init(SysBusDevice *s)
|
||||
sphb->tcet = spapr_tce_new_table(dev, sphb->dma_liobn,
|
||||
sphb->dma_window_size);
|
||||
if (!sphb->tcet) {
|
||||
fprintf(stderr, "Unable to create TCE table for %s\n", sphb->dtbusname);
|
||||
return -1;
|
||||
error_setg(errp, "Unable to create TCE table for %s",
|
||||
sphb->dtbusname);
|
||||
return;
|
||||
}
|
||||
address_space_init(&sphb->iommu_as, spapr_tce_get_iommu(sphb->tcet),
|
||||
sphb->dtbusname);
|
||||
@@ -642,13 +625,12 @@ static int spapr_phb_init(SysBusDevice *s)
|
||||
|
||||
irq = spapr_allocate_lsi(0);
|
||||
if (!irq) {
|
||||
return -1;
|
||||
error_setg(errp, "spapr_allocate_lsi failed");
|
||||
return;
|
||||
}
|
||||
|
||||
sphb->lsi_table[i].irq = irq;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void spapr_phb_reset(DeviceState *qdev)
|
||||
@@ -731,11 +713,10 @@ static const char *spapr_phb_root_bus_path(PCIHostState *host_bridge,
|
||||
static void spapr_phb_class_init(ObjectClass *klass, void *data)
|
||||
{
|
||||
PCIHostBridgeClass *hc = PCI_HOST_BRIDGE_CLASS(klass);
|
||||
SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass);
|
||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||
|
||||
hc->root_bus_path = spapr_phb_root_bus_path;
|
||||
sdc->init = spapr_phb_init;
|
||||
dc->realize = spapr_phb_realize;
|
||||
dc->props = spapr_phb_properties;
|
||||
dc->reset = spapr_phb_reset;
|
||||
dc->vmsd = &vmstate_spapr_pci;
|
||||
|
@@ -80,7 +80,7 @@ static int s390_ipl_init(SysBusDevice *dev)
|
||||
|
||||
bios_size = load_elf(bios_filename, NULL, NULL, &ipl->start_addr, NULL,
|
||||
NULL, 1, ELF_MACHINE, 0);
|
||||
if (bios_size == -1) {
|
||||
if (bios_size < 0) {
|
||||
bios_size = load_image_targphys(bios_filename, ZIPL_IMAGE_START,
|
||||
4096);
|
||||
ipl->start_addr = ZIPL_IMAGE_START;
|
||||
|
@@ -135,25 +135,23 @@ static unsigned s390_running_cpus;
|
||||
void s390_add_running_cpu(S390CPU *cpu)
|
||||
{
|
||||
CPUState *cs = CPU(cpu);
|
||||
CPUS390XState *env = &cpu->env;
|
||||
|
||||
if (cs->halted) {
|
||||
s390_running_cpus++;
|
||||
cs->halted = 0;
|
||||
env->exception_index = -1;
|
||||
cs->exception_index = -1;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned s390_del_running_cpu(S390CPU *cpu)
|
||||
{
|
||||
CPUState *cs = CPU(cpu);
|
||||
CPUS390XState *env = &cpu->env;
|
||||
|
||||
if (cs->halted == 0) {
|
||||
assert(s390_running_cpus >= 1);
|
||||
s390_running_cpus--;
|
||||
cs->halted = 1;
|
||||
env->exception_index = EXCP_HLT;
|
||||
cs->exception_index = EXCP_HLT;
|
||||
}
|
||||
return s390_running_cpus;
|
||||
}
|
||||
@@ -196,7 +194,7 @@ void s390_init_cpus(const char *cpu_model, uint8_t *storage_keys)
|
||||
|
||||
ipi_states[i] = cpu;
|
||||
cs->halted = 1;
|
||||
cpu->env.exception_index = EXCP_HLT;
|
||||
cs->exception_index = EXCP_HLT;
|
||||
cpu->env.storage_keys = storage_keys;
|
||||
}
|
||||
}
|
||||
|
@@ -25,13 +25,13 @@ typedef struct ConfigMgtData {
|
||||
uint8_t event_qualifier;
|
||||
} QEMU_PACKED ConfigMgtData;
|
||||
|
||||
static qemu_irq irq_cpu_hotplug; /* Only used in this file */
|
||||
static qemu_irq *irq_cpu_hotplug; /* Only used in this file */
|
||||
|
||||
#define EVENT_QUAL_CPU_CHANGE 1
|
||||
|
||||
void raise_irq_cpu_hotplug(void)
|
||||
{
|
||||
qemu_irq_raise(irq_cpu_hotplug);
|
||||
qemu_irq_raise(*irq_cpu_hotplug);
|
||||
}
|
||||
|
||||
static unsigned int send_mask(void)
|
||||
@@ -81,7 +81,7 @@ static void trigger_signal(void *opaque, int n, int level)
|
||||
|
||||
static int irq_cpu_hotplug_init(SCLPEvent *event)
|
||||
{
|
||||
irq_cpu_hotplug = *qemu_allocate_irqs(trigger_signal, event, 1);
|
||||
irq_cpu_hotplug = qemu_allocate_irqs(trigger_signal, event, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@@ -1905,6 +1905,26 @@ static const VMStateInfo vmstate_info_scsi_requests = {
|
||||
.put = put_scsi_requests,
|
||||
};
|
||||
|
||||
static bool scsi_sense_state_needed(void *opaque)
|
||||
{
|
||||
SCSIDevice *s = opaque;
|
||||
|
||||
return s->sense_len > SCSI_SENSE_BUF_SIZE_OLD;
|
||||
}
|
||||
|
||||
static const VMStateDescription vmstate_scsi_sense_state = {
|
||||
.name = "SCSIDevice/sense",
|
||||
.version_id = 1,
|
||||
.minimum_version_id = 1,
|
||||
.minimum_version_id_old = 1,
|
||||
.fields = (VMStateField []) {
|
||||
VMSTATE_UINT8_SUB_ARRAY(sense, SCSIDevice,
|
||||
SCSI_SENSE_BUF_SIZE_OLD,
|
||||
SCSI_SENSE_BUF_SIZE - SCSI_SENSE_BUF_SIZE_OLD),
|
||||
VMSTATE_END_OF_LIST()
|
||||
}
|
||||
};
|
||||
|
||||
const VMStateDescription vmstate_scsi_device = {
|
||||
.name = "SCSIDevice",
|
||||
.version_id = 1,
|
||||
@@ -1915,7 +1935,7 @@ const VMStateDescription vmstate_scsi_device = {
|
||||
VMSTATE_UINT8(unit_attention.asc, SCSIDevice),
|
||||
VMSTATE_UINT8(unit_attention.ascq, SCSIDevice),
|
||||
VMSTATE_BOOL(sense_is_ua, SCSIDevice),
|
||||
VMSTATE_UINT8_ARRAY(sense, SCSIDevice, SCSI_SENSE_BUF_SIZE),
|
||||
VMSTATE_UINT8_SUB_ARRAY(sense, SCSIDevice, 0, SCSI_SENSE_BUF_SIZE_OLD),
|
||||
VMSTATE_UINT32(sense_len, SCSIDevice),
|
||||
{
|
||||
.name = "requests",
|
||||
@@ -1927,6 +1947,14 @@ const VMStateDescription vmstate_scsi_device = {
|
||||
.offset = 0,
|
||||
},
|
||||
VMSTATE_END_OF_LIST()
|
||||
},
|
||||
.subsections = (VMStateSubsection []) {
|
||||
{
|
||||
.vmsd = &vmstate_scsi_sense_state,
|
||||
.needed = scsi_sense_state_needed,
|
||||
}, {
|
||||
/* empty */
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
@@ -195,9 +195,9 @@ static int vscsi_send_iu(VSCSIState *s, vscsi_req *req,
|
||||
req->crq.s.IU_data_ptr = req->iu.srp.rsp.tag; /* right byte order */
|
||||
|
||||
if (rc == 0) {
|
||||
req->crq.s.status = 0x99; /* Just needs to be non-zero */
|
||||
req->crq.s.status = VIOSRP_OK;
|
||||
} else {
|
||||
req->crq.s.status = 0x00;
|
||||
req->crq.s.status = VIOSRP_ADAPTER_FAIL;
|
||||
}
|
||||
|
||||
rc1 = spapr_vio_send_crq(&s->vdev, req->crq.raw);
|
||||
|
@@ -304,6 +304,8 @@ static void virtio_scsi_command_complete(SCSIRequest *r, uint32_t status,
|
||||
size_t resid)
|
||||
{
|
||||
VirtIOSCSIReq *req = r->hba_private;
|
||||
VirtIOSCSI *s = req->dev;
|
||||
VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(s);
|
||||
uint32_t sense_len;
|
||||
|
||||
if (r->io_canceled) {
|
||||
@@ -317,7 +319,7 @@ static void virtio_scsi_command_complete(SCSIRequest *r, uint32_t status,
|
||||
} else {
|
||||
req->resp.cmd->resid = 0;
|
||||
sense_len = scsi_req_get_sense(r, req->resp.cmd->sense,
|
||||
VIRTIO_SCSI_SENSE_SIZE);
|
||||
vs->sense_size);
|
||||
req->resp.cmd->sense_len = tswap32(sense_len);
|
||||
}
|
||||
virtio_scsi_complete_req(req);
|
||||
|
@@ -238,9 +238,10 @@ static int ssi_sd_load(QEMUFile *f, void *opaque, int version_id)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ssi_sd_init(SSISlave *dev)
|
||||
static int ssi_sd_init(SSISlave *d)
|
||||
{
|
||||
ssi_sd_state *s = FROM_SSI_SLAVE(ssi_sd_state, dev);
|
||||
DeviceState *dev = DEVICE(d);
|
||||
ssi_sd_state *s = FROM_SSI_SLAVE(ssi_sd_state, d);
|
||||
DriveInfo *dinfo;
|
||||
|
||||
s->mode = SSI_SD_CMD;
|
||||
@@ -249,7 +250,7 @@ static int ssi_sd_init(SSISlave *dev)
|
||||
if (s->sd == NULL) {
|
||||
return -1;
|
||||
}
|
||||
register_savevm(&dev->qdev, "ssi_sd", -1, 1, ssi_sd_save, ssi_sd_load, s);
|
||||
register_savevm(dev, "ssi_sd", -1, 1, ssi_sd_save, ssi_sd_load, s);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@@ -416,7 +416,7 @@ static void sh7750_mem_writel(void *opaque, hwaddr addr,
|
||||
case SH7750_PTEH_A7:
|
||||
/* If asid changes, clear all registered tlb entries. */
|
||||
if ((s->cpu->env.pteh & 0xff) != (mem_value & 0xff)) {
|
||||
tlb_flush(&s->cpu->env, 1);
|
||||
tlb_flush(CPU(s->cpu), 1);
|
||||
}
|
||||
s->cpu->env.pteh = mem_value;
|
||||
return;
|
||||
|
11
hw/ssi/ssi.c
11
hw/ssi/ssi.c
@@ -15,7 +15,7 @@
|
||||
#include "hw/ssi.h"
|
||||
|
||||
struct SSIBus {
|
||||
BusState qbus;
|
||||
BusState parent_obj;
|
||||
};
|
||||
|
||||
#define TYPE_SSI_BUS "SSI"
|
||||
@@ -60,7 +60,7 @@ static int ssi_slave_init(DeviceState *dev)
|
||||
|
||||
if (ssc->transfer_raw == ssi_transfer_raw_default &&
|
||||
ssc->cs_polarity != SSI_CS_NONE) {
|
||||
qdev_init_gpio_in(&s->qdev, ssi_cs_default, 1);
|
||||
qdev_init_gpio_in(dev, ssi_cs_default, 1);
|
||||
}
|
||||
|
||||
return ssc->init(s);
|
||||
@@ -88,7 +88,7 @@ static const TypeInfo ssi_slave_info = {
|
||||
|
||||
DeviceState *ssi_create_slave_no_init(SSIBus *bus, const char *name)
|
||||
{
|
||||
return qdev_create(&bus->qbus, name);
|
||||
return qdev_create(BUS(bus), name);
|
||||
}
|
||||
|
||||
DeviceState *ssi_create_slave(SSIBus *bus, const char *name)
|
||||
@@ -108,11 +108,12 @@ SSIBus *ssi_create_bus(DeviceState *parent, const char *name)
|
||||
|
||||
uint32_t ssi_transfer(SSIBus *bus, uint32_t val)
|
||||
{
|
||||
BusState *b = BUS(bus);
|
||||
BusChild *kid;
|
||||
SSISlaveClass *ssc;
|
||||
uint32_t r = 0;
|
||||
|
||||
QTAILQ_FOREACH(kid, &bus->qbus.children, sibling) {
|
||||
QTAILQ_FOREACH(kid, &b->children, sibling) {
|
||||
SSISlave *slave = SSI_SLAVE(kid->child);
|
||||
ssc = SSI_SLAVE_GET_CLASS(slave);
|
||||
r |= ssc->transfer_raw(slave, val);
|
||||
@@ -156,7 +157,7 @@ static int ssi_auto_connect_slave(Object *child, void *opaque)
|
||||
}
|
||||
|
||||
cs_line = qdev_get_gpio_in(DEVICE(dev), 0);
|
||||
qdev_set_parent_bus(DEVICE(dev), &arg->bus->qbus);
|
||||
qdev_set_parent_bus(DEVICE(dev), BUS(arg->bus));
|
||||
**arg->cs_linep = cs_line;
|
||||
(*arg->cs_linep)++;
|
||||
return 0;
|
||||
|
@@ -106,9 +106,9 @@ static void grlib_gptimer_enable(GPTimer *timer)
|
||||
/* ptimer is triggered when the counter reach 0 but GPTimer is triggered at
|
||||
underflow. Set count + 1 to simulate the GPTimer behavior. */
|
||||
|
||||
trace_grlib_gptimer_enable(timer->id, timer->counter + 1);
|
||||
trace_grlib_gptimer_enable(timer->id, timer->counter);
|
||||
|
||||
ptimer_set_count(timer->ptimer, timer->counter + 1);
|
||||
ptimer_set_count(timer->ptimer, (uint64_t)timer->counter + 1);
|
||||
ptimer_run(timer->ptimer, 1);
|
||||
}
|
||||
|
||||
|
@@ -19,6 +19,7 @@
|
||||
#include "qemu/queue.h"
|
||||
#include "qemu/event_notifier.h"
|
||||
#include "qemu/thread.h"
|
||||
#include "qemu/rfifolock.h"
|
||||
#include "qemu/timer.h"
|
||||
|
||||
typedef struct BlockDriverAIOCB BlockDriverAIOCB;
|
||||
@@ -47,6 +48,9 @@ typedef void IOHandler(void *opaque);
|
||||
struct AioContext {
|
||||
GSource source;
|
||||
|
||||
/* Protects all fields from multi-threaded access */
|
||||
RFifoLock lock;
|
||||
|
||||
/* The list of registered AIO handlers */
|
||||
QLIST_HEAD(, AioHandler) aio_handlers;
|
||||
|
||||
@@ -104,6 +108,20 @@ void aio_context_ref(AioContext *ctx);
|
||||
*/
|
||||
void aio_context_unref(AioContext *ctx);
|
||||
|
||||
/* Take ownership of the AioContext. If the AioContext will be shared between
|
||||
* threads, a thread must have ownership when calling aio_poll().
|
||||
*
|
||||
* Note that multiple threads calling aio_poll() means timers, BHs, and
|
||||
* callbacks may be invoked from a different thread than they were registered
|
||||
* from. Therefore, code must use AioContext acquire/release or use
|
||||
* fine-grained synchronization to protect shared state if other threads will
|
||||
* be accessing it simultaneously.
|
||||
*/
|
||||
void aio_context_acquire(AioContext *ctx);
|
||||
|
||||
/* Relinquish ownership of the AioContext. */
|
||||
void aio_context_release(AioContext *ctx);
|
||||
|
||||
/**
|
||||
* aio_bh_new: Allocate a new bottom half structure.
|
||||
*
|
||||
|
@@ -286,15 +286,6 @@ int bdrv_check(BlockDriverState *bs, BdrvCheckResult *res, BdrvCheckMode fix);
|
||||
int bdrv_amend_options(BlockDriverState *bs_new, QEMUOptionParameter *options);
|
||||
|
||||
/* external snapshots */
|
||||
|
||||
typedef enum {
|
||||
BS_IS_A_FILTER,
|
||||
BS_FILTER_PASS_DOWN,
|
||||
BS_AUTHORIZATION_COUNT,
|
||||
} BsAuthorization;
|
||||
|
||||
bool bdrv_generic_is_first_non_filter(BlockDriverState *bs,
|
||||
BlockDriverState *candidate);
|
||||
bool bdrv_recurse_is_first_non_filter(BlockDriverState *bs,
|
||||
BlockDriverState *candidate);
|
||||
bool bdrv_is_first_non_filter(BlockDriverState *candidate);
|
||||
|
@@ -76,10 +76,10 @@ struct BlockDriver {
|
||||
const char *format_name;
|
||||
int instance_size;
|
||||
|
||||
/* this table of boolean contains authorizations for the block operations */
|
||||
bool authorizations[BS_AUTHORIZATION_COUNT];
|
||||
/* for snapshots complex block filter like Quorum can implement the
|
||||
* following recursive callback instead of BS_IS_A_FILTER.
|
||||
/* set to true if the BlockDriver is a block filter */
|
||||
bool is_filter;
|
||||
/* for snapshots block filter like Quorum can implement the
|
||||
* following recursive callback.
|
||||
* It's purpose is to recurse on the filter children while calling
|
||||
* bdrv_recurse_is_first_non_filter on them.
|
||||
* For a sample implementation look in the future Quorum block filter.
|
||||
|
@@ -360,9 +360,6 @@ int page_check_range(target_ulong start, target_ulong len, int flags);
|
||||
|
||||
CPUArchState *cpu_copy(CPUArchState *env);
|
||||
|
||||
void QEMU_NORETURN cpu_abort(CPUArchState *env, const char *fmt, ...)
|
||||
GCC_FMT_ATTR(2, 3);
|
||||
|
||||
/* Flags for use in ENV->INTERRUPT_PENDING.
|
||||
|
||||
The numbers assigned here are non-sequential in order to preserve
|
||||
@@ -413,27 +410,6 @@ void QEMU_NORETURN cpu_abort(CPUArchState *env, const char *fmt, ...)
|
||||
| CPU_INTERRUPT_TGT_EXT_3 \
|
||||
| CPU_INTERRUPT_TGT_EXT_4)
|
||||
|
||||
/* Breakpoint/watchpoint flags */
|
||||
#define BP_MEM_READ 0x01
|
||||
#define BP_MEM_WRITE 0x02
|
||||
#define BP_MEM_ACCESS (BP_MEM_READ | BP_MEM_WRITE)
|
||||
#define BP_STOP_BEFORE_ACCESS 0x04
|
||||
#define BP_WATCHPOINT_HIT 0x08
|
||||
#define BP_GDB 0x10
|
||||
#define BP_CPU 0x20
|
||||
|
||||
int cpu_breakpoint_insert(CPUArchState *env, target_ulong pc, int flags,
|
||||
CPUBreakpoint **breakpoint);
|
||||
int cpu_breakpoint_remove(CPUArchState *env, target_ulong pc, int flags);
|
||||
void cpu_breakpoint_remove_by_ref(CPUArchState *env, CPUBreakpoint *breakpoint);
|
||||
void cpu_breakpoint_remove_all(CPUArchState *env, int mask);
|
||||
int cpu_watchpoint_insert(CPUArchState *env, target_ulong addr, target_ulong len,
|
||||
int flags, CPUWatchpoint **watchpoint);
|
||||
int cpu_watchpoint_remove(CPUArchState *env, target_ulong addr,
|
||||
target_ulong len, int flags);
|
||||
void cpu_watchpoint_remove_by_ref(CPUArchState *env, CPUWatchpoint *watchpoint);
|
||||
void cpu_watchpoint_remove_all(CPUArchState *env, int mask);
|
||||
|
||||
#if !defined(CONFIG_USER_ONLY)
|
||||
|
||||
/* memory API */
|
||||
|
@@ -24,7 +24,6 @@
|
||||
#endif
|
||||
|
||||
#include "config.h"
|
||||
#include <setjmp.h>
|
||||
#include <inttypes.h>
|
||||
#include "qemu/osdep.h"
|
||||
#include "qemu/queue.h"
|
||||
@@ -61,9 +60,6 @@ typedef uint64_t target_ulong;
|
||||
#define EXCP_HALTED 0x10003 /* cpu is halted (waiting for external event) */
|
||||
#define EXCP_YIELD 0x10004 /* cpu wants to yield timeslice to another */
|
||||
|
||||
#define TB_JMP_CACHE_BITS 12
|
||||
#define TB_JMP_CACHE_SIZE (1 << TB_JMP_CACHE_BITS)
|
||||
|
||||
/* Only the bottom TB_JMP_PAGE_BITS of the jump cache hash bits vary for
|
||||
addresses on the same page. The top bits are the same. This allows
|
||||
TLB invalidation to quickly clear a subset of the hash table. */
|
||||
@@ -118,66 +114,9 @@ QEMU_BUILD_BUG_ON(sizeof(CPUTLBEntry) != (1 << CPU_TLB_ENTRY_BITS));
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef HOST_WORDS_BIGENDIAN
|
||||
typedef struct icount_decr_u16 {
|
||||
uint16_t high;
|
||||
uint16_t low;
|
||||
} icount_decr_u16;
|
||||
#else
|
||||
typedef struct icount_decr_u16 {
|
||||
uint16_t low;
|
||||
uint16_t high;
|
||||
} icount_decr_u16;
|
||||
#endif
|
||||
|
||||
typedef struct CPUBreakpoint {
|
||||
target_ulong pc;
|
||||
int flags; /* BP_* */
|
||||
QTAILQ_ENTRY(CPUBreakpoint) entry;
|
||||
} CPUBreakpoint;
|
||||
|
||||
typedef struct CPUWatchpoint {
|
||||
target_ulong vaddr;
|
||||
target_ulong len_mask;
|
||||
int flags; /* BP_* */
|
||||
QTAILQ_ENTRY(CPUWatchpoint) entry;
|
||||
} CPUWatchpoint;
|
||||
|
||||
#define CPU_TEMP_BUF_NLONGS 128
|
||||
#define CPU_COMMON \
|
||||
/* soft mmu support */ \
|
||||
/* in order to avoid passing too many arguments to the MMIO \
|
||||
helpers, we store some rarely used information in the CPU \
|
||||
context) */ \
|
||||
uintptr_t mem_io_pc; /* host pc at which the memory was \
|
||||
accessed */ \
|
||||
target_ulong mem_io_vaddr; /* target virtual addr at which the \
|
||||
memory was accessed */ \
|
||||
CPU_COMMON_TLB \
|
||||
struct TranslationBlock *tb_jmp_cache[TB_JMP_CACHE_SIZE]; \
|
||||
\
|
||||
int64_t icount_extra; /* Instructions until next timer event. */ \
|
||||
/* Number of cycles left, with interrupt flag in high bit. \
|
||||
This allows a single read-compare-cbranch-write sequence to test \
|
||||
for both decrementer underflow and exceptions. */ \
|
||||
union { \
|
||||
uint32_t u32; \
|
||||
icount_decr_u16 u16; \
|
||||
} icount_decr; \
|
||||
uint32_t can_do_io; /* nonzero if memory mapped IO is safe. */ \
|
||||
\
|
||||
/* from this point: preserved by CPU reset */ \
|
||||
/* ice debug support */ \
|
||||
QTAILQ_HEAD(breakpoints_head, CPUBreakpoint) breakpoints; \
|
||||
\
|
||||
QTAILQ_HEAD(watchpoints_head, CPUWatchpoint) watchpoints; \
|
||||
CPUWatchpoint *watchpoint_hit; \
|
||||
\
|
||||
/* Core interrupt code */ \
|
||||
sigjmp_buf jmp_env; \
|
||||
int exception_index; \
|
||||
\
|
||||
/* user data */ \
|
||||
void *opaque; \
|
||||
|
||||
#endif
|
||||
|
@@ -22,7 +22,7 @@
|
||||
#if !defined(CONFIG_USER_ONLY)
|
||||
/* cputlb.c */
|
||||
void tlb_protect_code(ram_addr_t ram_addr);
|
||||
void tlb_unprotect_code_phys(CPUArchState *env, ram_addr_t ram_addr,
|
||||
void tlb_unprotect_code_phys(CPUState *cpu, ram_addr_t ram_addr,
|
||||
target_ulong vaddr);
|
||||
void tlb_reset_dirty_range(CPUTLBEntry *tlb_entry, uintptr_t start,
|
||||
uintptr_t length);
|
||||
@@ -31,12 +31,12 @@ void tlb_set_dirty(CPUArchState *env, target_ulong vaddr);
|
||||
extern int tlb_flush_count;
|
||||
|
||||
/* exec.c */
|
||||
void tb_flush_jmp_cache(CPUArchState *env, target_ulong addr);
|
||||
void tb_flush_jmp_cache(CPUState *cpu, target_ulong addr);
|
||||
|
||||
MemoryRegionSection *
|
||||
address_space_translate_for_iotlb(AddressSpace *as, hwaddr addr, hwaddr *xlat,
|
||||
hwaddr *plen);
|
||||
hwaddr memory_region_section_get_iotlb(CPUArchState *env,
|
||||
hwaddr memory_region_section_get_iotlb(CPUState *cpu,
|
||||
MemoryRegionSection *section,
|
||||
target_ulong vaddr,
|
||||
hwaddr paddr, hwaddr xlat,
|
||||
|
@@ -80,16 +80,16 @@ void restore_state_to_opc(CPUArchState *env, struct TranslationBlock *tb,
|
||||
void cpu_gen_init(void);
|
||||
int cpu_gen_code(CPUArchState *env, struct TranslationBlock *tb,
|
||||
int *gen_code_size_ptr);
|
||||
bool cpu_restore_state(CPUArchState *env, uintptr_t searched_pc);
|
||||
bool cpu_restore_state(CPUState *cpu, uintptr_t searched_pc);
|
||||
void page_size_init(void);
|
||||
|
||||
void QEMU_NORETURN cpu_resume_from_signal(CPUArchState *env1, void *puc);
|
||||
void QEMU_NORETURN cpu_io_recompile(CPUArchState *env, uintptr_t retaddr);
|
||||
TranslationBlock *tb_gen_code(CPUArchState *env,
|
||||
void QEMU_NORETURN cpu_resume_from_signal(CPUState *cpu, void *puc);
|
||||
void QEMU_NORETURN cpu_io_recompile(CPUState *cpu, uintptr_t retaddr);
|
||||
TranslationBlock *tb_gen_code(CPUState *cpu,
|
||||
target_ulong pc, target_ulong cs_base, int flags,
|
||||
int cflags);
|
||||
void cpu_exec_init(CPUArchState *env);
|
||||
void QEMU_NORETURN cpu_loop_exit(CPUArchState *env1);
|
||||
void QEMU_NORETURN cpu_loop_exit(CPUState *cpu);
|
||||
int page_unprotect(target_ulong address, uintptr_t pc, void *puc);
|
||||
void tb_invalidate_phys_page_range(tb_page_addr_t start, tb_page_addr_t end,
|
||||
int is_cpu_write_access);
|
||||
@@ -98,18 +98,18 @@ void tb_invalidate_phys_range(tb_page_addr_t start, tb_page_addr_t end,
|
||||
#if !defined(CONFIG_USER_ONLY)
|
||||
void tcg_cpu_address_space_init(CPUState *cpu, AddressSpace *as);
|
||||
/* cputlb.c */
|
||||
void tlb_flush_page(CPUArchState *env, target_ulong addr);
|
||||
void tlb_flush(CPUArchState *env, int flush_global);
|
||||
void tlb_set_page(CPUArchState *env, target_ulong vaddr,
|
||||
void tlb_flush_page(CPUState *cpu, target_ulong addr);
|
||||
void tlb_flush(CPUState *cpu, int flush_global);
|
||||
void tlb_set_page(CPUState *cpu, target_ulong vaddr,
|
||||
hwaddr paddr, int prot,
|
||||
int mmu_idx, target_ulong size);
|
||||
void tb_invalidate_phys_addr(AddressSpace *as, hwaddr addr);
|
||||
#else
|
||||
static inline void tlb_flush_page(CPUArchState *env, target_ulong addr)
|
||||
static inline void tlb_flush_page(CPUState *cpu, target_ulong addr)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void tlb_flush(CPUArchState *env, int flush_global)
|
||||
static inline void tlb_flush(CPUState *cpu, int flush_global)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
@@ -332,7 +332,7 @@ bool io_mem_read(struct MemoryRegion *mr, hwaddr addr,
|
||||
bool io_mem_write(struct MemoryRegion *mr, hwaddr addr,
|
||||
uint64_t value, unsigned size);
|
||||
|
||||
void tlb_fill(CPUArchState *env1, target_ulong addr, int is_write, int mmu_idx,
|
||||
void tlb_fill(CPUState *cpu, target_ulong addr, int is_write, int mmu_idx,
|
||||
uintptr_t retaddr);
|
||||
|
||||
uint8_t helper_ldb_cmmu(CPUArchState *env, target_ulong addr, int mmu_idx);
|
||||
@@ -380,20 +380,25 @@ extern int singlestep;
|
||||
/* cpu-exec.c */
|
||||
extern volatile sig_atomic_t exit_request;
|
||||
|
||||
/* Deterministic execution requires that IO only be performed on the last
|
||||
instruction of a TB so that interrupts take effect immediately. */
|
||||
static inline int can_do_io(CPUArchState *env)
|
||||
/**
|
||||
* cpu_can_do_io:
|
||||
* @cpu: The CPU for which to check IO.
|
||||
*
|
||||
* Deterministic execution requires that IO only be performed on the last
|
||||
* instruction of a TB so that interrupts take effect immediately.
|
||||
*
|
||||
* Returns: %true if memory-mapped IO is safe, %false otherwise.
|
||||
*/
|
||||
static inline bool cpu_can_do_io(CPUState *cpu)
|
||||
{
|
||||
CPUState *cpu = ENV_GET_CPU(env);
|
||||
|
||||
if (!use_icount) {
|
||||
return 1;
|
||||
return true;
|
||||
}
|
||||
/* If not executing code then assume we are ok. */
|
||||
if (cpu->current_tb == NULL) {
|
||||
return 1;
|
||||
return true;
|
||||
}
|
||||
return env->can_do_io != 0;
|
||||
return cpu->can_do_io != 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@@ -26,13 +26,15 @@ static inline void gen_tb_start(void)
|
||||
|
||||
icount_label = gen_new_label();
|
||||
count = tcg_temp_local_new_i32();
|
||||
tcg_gen_ld_i32(count, cpu_env, offsetof(CPUArchState, icount_decr.u32));
|
||||
tcg_gen_ld_i32(count, cpu_env,
|
||||
-ENV_OFFSET + offsetof(CPUState, icount_decr.u32));
|
||||
/* This is a horrid hack to allow fixing up the value later. */
|
||||
icount_arg = tcg_ctx.gen_opparam_ptr + 1;
|
||||
tcg_gen_subi_i32(count, count, 0xdeadbeef);
|
||||
|
||||
tcg_gen_brcondi_i32(TCG_COND_LT, count, 0, icount_label);
|
||||
tcg_gen_st16_i32(count, cpu_env, offsetof(CPUArchState, icount_decr.u16.low));
|
||||
tcg_gen_st16_i32(count, cpu_env,
|
||||
-ENV_OFFSET + offsetof(CPUState, icount_decr.u16.low));
|
||||
tcg_temp_free_i32(count);
|
||||
}
|
||||
|
||||
@@ -51,14 +53,14 @@ static void gen_tb_end(TranslationBlock *tb, int num_insns)
|
||||
static inline void gen_io_start(void)
|
||||
{
|
||||
TCGv_i32 tmp = tcg_const_i32(1);
|
||||
tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUArchState, can_do_io));
|
||||
tcg_gen_st_i32(tmp, cpu_env, -ENV_OFFSET + offsetof(CPUState, can_do_io));
|
||||
tcg_temp_free_i32(tmp);
|
||||
}
|
||||
|
||||
static inline void gen_io_end(void)
|
||||
{
|
||||
TCGv_i32 tmp = tcg_const_i32(0);
|
||||
tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUArchState, can_do_io));
|
||||
tcg_gen_st_i32(tmp, cpu_env, -ENV_OFFSET + offsetof(CPUState, can_do_io));
|
||||
tcg_temp_free_i32(tmp);
|
||||
}
|
||||
|
||||
|
@@ -126,12 +126,12 @@ static inline DATA_TYPE glue(io_read, SUFFIX)(CPUArchState *env,
|
||||
MemoryRegion *mr = iotlb_to_region(cpu->as, physaddr);
|
||||
|
||||
physaddr = (physaddr & TARGET_PAGE_MASK) + addr;
|
||||
env->mem_io_pc = retaddr;
|
||||
if (mr != &io_mem_rom && mr != &io_mem_notdirty && !can_do_io(env)) {
|
||||
cpu_io_recompile(env, retaddr);
|
||||
cpu->mem_io_pc = retaddr;
|
||||
if (mr != &io_mem_rom && mr != &io_mem_notdirty && !cpu_can_do_io(cpu)) {
|
||||
cpu_io_recompile(cpu, retaddr);
|
||||
}
|
||||
|
||||
env->mem_io_vaddr = addr;
|
||||
cpu->mem_io_vaddr = addr;
|
||||
io_mem_read(mr, physaddr, &val, 1 << SHIFT);
|
||||
return val;
|
||||
}
|
||||
@@ -158,7 +158,7 @@ WORD_TYPE helper_le_ld_name(CPUArchState *env, target_ulong addr, int mmu_idx,
|
||||
do_unaligned_access(env, addr, READ_ACCESS_TYPE, mmu_idx, retaddr);
|
||||
}
|
||||
#endif
|
||||
tlb_fill(env, addr, READ_ACCESS_TYPE, mmu_idx, retaddr);
|
||||
tlb_fill(ENV_GET_CPU(env), addr, READ_ACCESS_TYPE, mmu_idx, retaddr);
|
||||
tlb_addr = env->tlb_table[mmu_idx][index].ADDR_READ;
|
||||
}
|
||||
|
||||
@@ -240,7 +240,7 @@ WORD_TYPE helper_be_ld_name(CPUArchState *env, target_ulong addr, int mmu_idx,
|
||||
do_unaligned_access(env, addr, READ_ACCESS_TYPE, mmu_idx, retaddr);
|
||||
}
|
||||
#endif
|
||||
tlb_fill(env, addr, READ_ACCESS_TYPE, mmu_idx, retaddr);
|
||||
tlb_fill(ENV_GET_CPU(env), addr, READ_ACCESS_TYPE, mmu_idx, retaddr);
|
||||
tlb_addr = env->tlb_table[mmu_idx][index].ADDR_READ;
|
||||
}
|
||||
|
||||
@@ -333,12 +333,12 @@ static inline void glue(io_write, SUFFIX)(CPUArchState *env,
|
||||
MemoryRegion *mr = iotlb_to_region(cpu->as, physaddr);
|
||||
|
||||
physaddr = (physaddr & TARGET_PAGE_MASK) + addr;
|
||||
if (mr != &io_mem_rom && mr != &io_mem_notdirty && !can_do_io(env)) {
|
||||
cpu_io_recompile(env, retaddr);
|
||||
if (mr != &io_mem_rom && mr != &io_mem_notdirty && !cpu_can_do_io(cpu)) {
|
||||
cpu_io_recompile(cpu, retaddr);
|
||||
}
|
||||
|
||||
env->mem_io_vaddr = addr;
|
||||
env->mem_io_pc = retaddr;
|
||||
cpu->mem_io_vaddr = addr;
|
||||
cpu->mem_io_pc = retaddr;
|
||||
io_mem_write(mr, physaddr, val, 1 << SHIFT);
|
||||
}
|
||||
|
||||
@@ -360,7 +360,7 @@ void helper_le_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val,
|
||||
do_unaligned_access(env, addr, 1, mmu_idx, retaddr);
|
||||
}
|
||||
#endif
|
||||
tlb_fill(env, addr, 1, mmu_idx, retaddr);
|
||||
tlb_fill(ENV_GET_CPU(env), addr, 1, mmu_idx, retaddr);
|
||||
tlb_addr = env->tlb_table[mmu_idx][index].addr_write;
|
||||
}
|
||||
|
||||
@@ -436,7 +436,7 @@ void helper_be_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val,
|
||||
do_unaligned_access(env, addr, 1, mmu_idx, retaddr);
|
||||
}
|
||||
#endif
|
||||
tlb_fill(env, addr, 1, mmu_idx, retaddr);
|
||||
tlb_fill(ENV_GET_CPU(env), addr, 1, mmu_idx, retaddr);
|
||||
tlb_addr = env->tlb_table[mmu_idx][index].addr_write;
|
||||
}
|
||||
|
||||
|
@@ -4,8 +4,8 @@
|
||||
#define HW_BOARDS_H
|
||||
|
||||
#include "sysemu/blockdev.h"
|
||||
#include "sysemu/qemumachine.h"
|
||||
#include "hw/qdev.h"
|
||||
#include "qom/object.h"
|
||||
|
||||
typedef struct QEMUMachineInitArgs {
|
||||
const QEMUMachine *machine;
|
||||
@@ -50,9 +50,59 @@ struct QEMUMachine {
|
||||
const char *hw_version;
|
||||
};
|
||||
|
||||
#define TYPE_MACHINE_SUFFIX "-machine"
|
||||
int qemu_register_machine(QEMUMachine *m);
|
||||
QEMUMachine *find_default_machine(void);
|
||||
|
||||
extern QEMUMachine *current_machine;
|
||||
#define TYPE_MACHINE "machine"
|
||||
#define MACHINE(obj) \
|
||||
OBJECT_CHECK(MachineState, (obj), TYPE_MACHINE)
|
||||
#define MACHINE_GET_CLASS(obj) \
|
||||
OBJECT_GET_CLASS(MachineClass, (obj), TYPE_MACHINE)
|
||||
#define MACHINE_CLASS(klass) \
|
||||
OBJECT_CLASS_CHECK(MachineClass, (klass), TYPE_MACHINE)
|
||||
|
||||
typedef struct MachineState MachineState;
|
||||
typedef struct MachineClass MachineClass;
|
||||
|
||||
MachineClass *find_default_machine(void);
|
||||
extern MachineState *current_machine;
|
||||
|
||||
/**
|
||||
* MachineClass:
|
||||
* @qemu_machine: #QEMUMachine
|
||||
*/
|
||||
struct MachineClass {
|
||||
/*< private >*/
|
||||
ObjectClass parent_class;
|
||||
/*< public >*/
|
||||
|
||||
QEMUMachine *qemu_machine;
|
||||
};
|
||||
|
||||
/**
|
||||
* MachineState:
|
||||
*/
|
||||
struct MachineState {
|
||||
/*< private >*/
|
||||
Object parent_obj;
|
||||
/*< public >*/
|
||||
|
||||
char *accel;
|
||||
bool kernel_irqchip;
|
||||
int kvm_shadow_mem;
|
||||
char *kernel;
|
||||
char *initrd;
|
||||
char *append;
|
||||
char *dtb;
|
||||
char *dumpdtb;
|
||||
int phandle_start;
|
||||
char *dt_compatible;
|
||||
bool dump_guest_core;
|
||||
bool mem_merge;
|
||||
bool usb;
|
||||
char *firmware;
|
||||
|
||||
QEMUMachineInitArgs init_args;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@@ -102,7 +102,7 @@ Object *ich9_lpc_find(void);
|
||||
#define ICH9_USB_UHCI1_DEV 29
|
||||
#define ICH9_USB_UHCI1_FUNC 0
|
||||
|
||||
/* D30:F0 DMI-to-PCI brdige */
|
||||
/* D30:F0 DMI-to-PCI bridge */
|
||||
#define ICH9_D2P_BRIDGE "ICH9 D2P BRIDGE"
|
||||
#define ICH9_D2P_BRIDGE_SAVEVM_VERSION 0
|
||||
|
||||
|
@@ -49,10 +49,12 @@ void pstrcpy_targphys(const char *name,
|
||||
hwaddr dest, int buf_size,
|
||||
const char *source);
|
||||
|
||||
extern bool rom_file_in_ram;
|
||||
extern bool option_rom_has_mr;
|
||||
extern bool rom_file_has_mr;
|
||||
|
||||
int rom_add_file(const char *file, const char *fw_dir,
|
||||
hwaddr addr, int32_t bootindex);
|
||||
hwaddr addr, int32_t bootindex,
|
||||
bool option_rom);
|
||||
void *rom_add_blob(const char *name, const void *blob, size_t len,
|
||||
hwaddr addr, const char *fw_file_name,
|
||||
FWCfgReadCallback fw_callback, void *callback_opaque);
|
||||
@@ -66,7 +68,7 @@ void *rom_ptr(hwaddr addr);
|
||||
void do_info_roms(Monitor *mon, const QDict *qdict);
|
||||
|
||||
#define rom_add_file_fixed(_f, _a, _i) \
|
||||
rom_add_file(_f, NULL, _a, _i)
|
||||
rom_add_file(_f, NULL, _a, _i, false)
|
||||
#define rom_add_blob_fixed(_f, _b, _l, _a) \
|
||||
rom_add_blob(_f, _b, _l, _a, NULL, NULL, NULL)
|
||||
|
||||
|
@@ -125,8 +125,8 @@ typedef struct Q35PCIHost {
|
||||
#define MCH_HOST_BRIDGE_PAM_RE ((uint8_t)0x1)
|
||||
#define MCH_HOST_BRIDGE_PAM_MASK ((uint8_t)0x3)
|
||||
|
||||
#define MCH_HOST_BRDIGE_SMRAM 0x9d
|
||||
#define MCH_HOST_BRDIGE_SMRAM_SIZE 1
|
||||
#define MCH_HOST_BRIDGE_SMRAM 0x9d
|
||||
#define MCH_HOST_BRIDGE_SMRAM_SIZE 1
|
||||
#define MCH_HOST_BRIDGE_SMRAM_DEFAULT ((uint8_t)0x2)
|
||||
#define MCH_HOST_BRIDGE_SMRAM_D_OPEN ((uint8_t)(1 << 6))
|
||||
#define MCH_HOST_BRIDGE_SMRAM_D_CLS ((uint8_t)(1 << 5))
|
||||
@@ -140,16 +140,16 @@ typedef struct Q35PCIHost {
|
||||
#define MCH_HOST_BRIDGE_UPPER_SYSTEM_BIOS_END 0x100000
|
||||
|
||||
#define MCH_HOST_BRIDGE_ESMRAMC 0x9e
|
||||
#define MCH_HOST_BRDIGE_ESMRAMC_H_SMRAME ((uint8_t)(1 << 6))
|
||||
#define MCH_HOST_BRDIGE_ESMRAMC_E_SMERR ((uint8_t)(1 << 5))
|
||||
#define MCH_HOST_BRDIGE_ESMRAMC_SM_CACHE ((uint8_t)(1 << 4))
|
||||
#define MCH_HOST_BRDIGE_ESMRAMC_SM_L1 ((uint8_t)(1 << 3))
|
||||
#define MCH_HOST_BRDIGE_ESMRAMC_SM_L2 ((uint8_t)(1 << 2))
|
||||
#define MCH_HOST_BRDIGE_ESMRAMC_TSEG_SZ_MASK ((uint8_t)(0x3 << 1))
|
||||
#define MCH_HOST_BRDIGE_ESMRAMC_TSEG_SZ_1MB ((uint8_t)(0x0 << 1))
|
||||
#define MCH_HOST_BRDIGE_ESMRAMC_TSEG_SZ_2MB ((uint8_t)(0x1 << 1))
|
||||
#define MCH_HOST_BRDIGE_ESMRAMC_TSEG_SZ_8MB ((uint8_t)(0x2 << 1))
|
||||
#define MCH_HOST_BRDIGE_ESMRAMC_T_EN ((uint8_t)1)
|
||||
#define MCH_HOST_BRIDGE_ESMRAMC_H_SMRAME ((uint8_t)(1 << 6))
|
||||
#define MCH_HOST_BRIDGE_ESMRAMC_E_SMERR ((uint8_t)(1 << 5))
|
||||
#define MCH_HOST_BRIDGE_ESMRAMC_SM_CACHE ((uint8_t)(1 << 4))
|
||||
#define MCH_HOST_BRIDGE_ESMRAMC_SM_L1 ((uint8_t)(1 << 3))
|
||||
#define MCH_HOST_BRIDGE_ESMRAMC_SM_L2 ((uint8_t)(1 << 2))
|
||||
#define MCH_HOST_BRIDGE_ESMRAMC_TSEG_SZ_MASK ((uint8_t)(0x3 << 1))
|
||||
#define MCH_HOST_BRIDGE_ESMRAMC_TSEG_SZ_1MB ((uint8_t)(0x0 << 1))
|
||||
#define MCH_HOST_BRIDGE_ESMRAMC_TSEG_SZ_2MB ((uint8_t)(0x1 << 1))
|
||||
#define MCH_HOST_BRIDGE_ESMRAMC_TSEG_SZ_8MB ((uint8_t)(0x2 << 1))
|
||||
#define MCH_HOST_BRIDGE_ESMRAMC_T_EN ((uint8_t)1)
|
||||
|
||||
/* D1:F0 PCIE* port*/
|
||||
#define MCH_PCIE_DEV 1
|
||||
|
@@ -36,6 +36,8 @@ typedef int (*qdev_event)(DeviceState *dev);
|
||||
typedef void (*qdev_resetfn)(DeviceState *dev);
|
||||
typedef void (*DeviceRealize)(DeviceState *dev, Error **errp);
|
||||
typedef void (*DeviceUnrealize)(DeviceState *dev, Error **errp);
|
||||
typedef void (*BusRealize)(BusState *bus, Error **errp);
|
||||
typedef void (*BusUnrealize)(BusState *bus, Error **errp);
|
||||
|
||||
struct VMStateDescription;
|
||||
|
||||
@@ -174,6 +176,9 @@ struct BusClass {
|
||||
*/
|
||||
char *(*get_fw_dev_path)(DeviceState *dev);
|
||||
void (*reset)(BusState *bus);
|
||||
BusRealize realize;
|
||||
BusUnrealize unrealize;
|
||||
|
||||
/* maximum devices allowed on the bus, 0: no limit. */
|
||||
int max_dev;
|
||||
/* number of automatically allocated bus ids (e.g. ide.0) */
|
||||
@@ -199,6 +204,7 @@ struct BusState {
|
||||
int allow_hotplug;
|
||||
HotplugHandler *hotplug_handler;
|
||||
int max_index;
|
||||
bool realized;
|
||||
QTAILQ_HEAD(ChildrenHead, BusChild) children;
|
||||
QLIST_ENTRY(BusState) sibling;
|
||||
};
|
||||
|
@@ -22,6 +22,7 @@ extern PropertyInfo qdev_prop_bios_chs_trans;
|
||||
extern PropertyInfo qdev_prop_drive;
|
||||
extern PropertyInfo qdev_prop_netdev;
|
||||
extern PropertyInfo qdev_prop_vlan;
|
||||
extern PropertyInfo qdev_prop_iothread;
|
||||
extern PropertyInfo qdev_prop_pci_devfn;
|
||||
extern PropertyInfo qdev_prop_blocksize;
|
||||
extern PropertyInfo qdev_prop_pci_host_devaddr;
|
||||
@@ -142,6 +143,8 @@ extern PropertyInfo qdev_prop_arraylen;
|
||||
DEFINE_PROP(_n, _s, _f, qdev_prop_vlan, NICPeers)
|
||||
#define DEFINE_PROP_DRIVE(_n, _s, _f) \
|
||||
DEFINE_PROP(_n, _s, _f, qdev_prop_drive, BlockDriverState *)
|
||||
#define DEFINE_PROP_IOTHREAD(_n, _s, _f) \
|
||||
DEFINE_PROP(_n, _s, _f, qdev_prop_iothread, IOThread *)
|
||||
#define DEFINE_PROP_MACADDR(_n, _s, _f) \
|
||||
DEFINE_PROP(_n, _s, _f, qdev_prop_macaddr, MACAddr)
|
||||
#define DEFINE_PROP_LOSTTICKPOLICY(_n, _s, _f, _d) \
|
||||
|
@@ -31,6 +31,7 @@ typedef struct SCSISense {
|
||||
uint8_t ascq;
|
||||
} SCSISense;
|
||||
|
||||
#define SCSI_SENSE_BUF_SIZE_OLD 96
|
||||
#define SCSI_SENSE_BUF_SIZE 252
|
||||
|
||||
struct SCSICommand {
|
||||
|
@@ -56,13 +56,12 @@ typedef struct SSISlaveClass {
|
||||
} SSISlaveClass;
|
||||
|
||||
struct SSISlave {
|
||||
DeviceState qdev;
|
||||
DeviceState parent_obj;
|
||||
|
||||
/* Chip select state */
|
||||
bool cs;
|
||||
};
|
||||
|
||||
#define SSI_SLAVE_FROM_QDEV(dev) DO_UPCAST(SSISlave, qdev, dev)
|
||||
#define FROM_SSI_SLAVE(type, dev) DO_UPCAST(type, ssidev, dev)
|
||||
|
||||
extern const VMStateDescription vmstate_ssi_slave;
|
||||
|
@@ -16,6 +16,7 @@
|
||||
|
||||
#include "hw/virtio/virtio.h"
|
||||
#include "hw/block/block.h"
|
||||
#include "sysemu/iothread.h"
|
||||
|
||||
#define TYPE_VIRTIO_BLK "virtio-blk-device"
|
||||
#define VIRTIO_BLK(obj) \
|
||||
@@ -106,6 +107,7 @@ struct virtio_scsi_inhdr
|
||||
struct VirtIOBlkConf
|
||||
{
|
||||
BlockConf conf;
|
||||
IOThread *iothread;
|
||||
char *serial;
|
||||
uint32_t scsi;
|
||||
uint32_t config_wce;
|
||||
@@ -140,13 +142,15 @@ typedef struct VirtIOBlock {
|
||||
DEFINE_BLOCK_CHS_PROPERTIES(_state, _field.conf), \
|
||||
DEFINE_PROP_STRING("serial", _state, _field.serial), \
|
||||
DEFINE_PROP_BIT("config-wce", _state, _field.config_wce, 0, true), \
|
||||
DEFINE_PROP_BIT("scsi", _state, _field.scsi, 0, true)
|
||||
DEFINE_PROP_BIT("scsi", _state, _field.scsi, 0, true), \
|
||||
DEFINE_PROP_IOTHREAD("x-iothread", _state, _field.iothread)
|
||||
#else
|
||||
#define DEFINE_VIRTIO_BLK_PROPERTIES(_state, _field) \
|
||||
DEFINE_BLOCK_PROPERTIES(_state, _field.conf), \
|
||||
DEFINE_BLOCK_CHS_PROPERTIES(_state, _field.conf), \
|
||||
DEFINE_PROP_STRING("serial", _state, _field.serial), \
|
||||
DEFINE_PROP_BIT("config-wce", _state, _field.config_wce, 0, true)
|
||||
DEFINE_PROP_BIT("config-wce", _state, _field.config_wce, 0, true), \
|
||||
DEFINE_PROP_IOTHREAD("x-iothread", _state, _field.iothread)
|
||||
#endif /* __linux__ */
|
||||
|
||||
void virtio_blk_set_conf(DeviceState *dev, VirtIOBlkConf *blk);
|
||||
|
@@ -81,15 +81,15 @@ typedef struct VirtIOSerialPortClass {
|
||||
bool is_console;
|
||||
|
||||
/*
|
||||
* The per-port (or per-app) init function that's called when a
|
||||
* The per-port (or per-app) realize function that's called when a
|
||||
* new device is found on the bus.
|
||||
*/
|
||||
int (*init)(VirtIOSerialPort *port);
|
||||
DeviceRealize realize;
|
||||
/*
|
||||
* Per-port exit function that's called when a port gets
|
||||
* Per-port unrealize function that's called when a port gets
|
||||
* hot-unplugged or removed.
|
||||
*/
|
||||
int (*exit)(VirtIOSerialPort *port);
|
||||
DeviceUnrealize unrealize;
|
||||
|
||||
/* Callbacks for guest events */
|
||||
/* Guest opened/closed device. */
|
||||
|
@@ -10,7 +10,6 @@
|
||||
|
||||
#include "hw/irq.h"
|
||||
#include "qemu-common.h"
|
||||
#include "sysemu/qemumachine.h"
|
||||
|
||||
/* xen-machine.c */
|
||||
enum xen_mode {
|
||||
|
@@ -650,6 +650,9 @@ extern const VMStateInfo vmstate_info_bitmap;
|
||||
#define VMSTATE_UINT8_ARRAY(_f, _s, _n) \
|
||||
VMSTATE_UINT8_ARRAY_V(_f, _s, _n, 0)
|
||||
|
||||
#define VMSTATE_UINT8_SUB_ARRAY(_f, _s, _start, _num) \
|
||||
VMSTATE_SUB_ARRAY(_f, _s, _start, _num, 0, vmstate_info_uint8, uint8_t)
|
||||
|
||||
#define VMSTATE_UINT8_2DARRAY(_f, _s, _n1, _n2) \
|
||||
VMSTATE_UINT8_2DARRAY_V(_f, _s, _n1, _n2, 0)
|
||||
|
||||
|
@@ -159,7 +159,7 @@ void qerror_report_err(Error *err);
|
||||
ERROR_CLASS_GENERIC_ERROR, "Invalid JSON syntax"
|
||||
|
||||
#define QERR_KVM_MISSING_CAP \
|
||||
ERROR_CLASS_K_V_M_MISSING_CAP, "Using KVM without %s, %s unavailable"
|
||||
ERROR_CLASS_KVM_MISSING_CAP, "Using KVM without %s, %s unavailable"
|
||||
|
||||
#define QERR_MIGRATION_ACTIVE \
|
||||
ERROR_CLASS_GENERIC_ERROR, "There's a migration process in progress"
|
||||
|
@@ -38,6 +38,8 @@ typedef struct cmdinfo {
|
||||
helpfunc_t help;
|
||||
} cmdinfo_t;
|
||||
|
||||
extern bool qemuio_misalign;
|
||||
|
||||
bool qemuio_command(BlockDriverState *bs, const char *cmd);
|
||||
|
||||
void qemuio_add_command(const cmdinfo_t *ci);
|
||||
|
54
include/qemu/rfifolock.h
Normal file
54
include/qemu/rfifolock.h
Normal file
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Recursive FIFO lock
|
||||
*
|
||||
* Copyright Red Hat, Inc. 2013
|
||||
*
|
||||
* Authors:
|
||||
* Stefan Hajnoczi <stefanha@redhat.com>
|
||||
*
|
||||
* This work is licensed under the terms of the GNU GPL, version 2 or later.
|
||||
* See the COPYING file in the top-level directory.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef QEMU_RFIFOLOCK_H
|
||||
#define QEMU_RFIFOLOCK_H
|
||||
|
||||
#include "qemu/thread.h"
|
||||
|
||||
/* Recursive FIFO lock
|
||||
*
|
||||
* This lock provides more features than a plain mutex:
|
||||
*
|
||||
* 1. Fairness - enforces FIFO order.
|
||||
* 2. Nesting - can be taken recursively.
|
||||
* 3. Contention callback - optional, called when thread must wait.
|
||||
*
|
||||
* The recursive FIFO lock is heavyweight so prefer other synchronization
|
||||
* primitives if you do not need its features.
|
||||
*/
|
||||
typedef struct {
|
||||
QemuMutex lock; /* protects all fields */
|
||||
|
||||
/* FIFO order */
|
||||
unsigned int head; /* active ticket number */
|
||||
unsigned int tail; /* waiting ticket number */
|
||||
QemuCond cond; /* used to wait for our ticket number */
|
||||
|
||||
/* Nesting */
|
||||
QemuThread owner_thread; /* thread that currently has ownership */
|
||||
unsigned int nesting; /* amount of nesting levels */
|
||||
|
||||
/* Contention callback */
|
||||
void (*cb)(void *); /* called when thread must wait, with ->lock
|
||||
* held so it may not recursively lock/unlock
|
||||
*/
|
||||
void *cb_opaque;
|
||||
} RFifoLock;
|
||||
|
||||
void rfifolock_init(RFifoLock *r, void (*cb)(void *), void *opaque);
|
||||
void rfifolock_destroy(RFifoLock *r);
|
||||
void rfifolock_lock(RFifoLock *r);
|
||||
void rfifolock_unlock(RFifoLock *r);
|
||||
|
||||
#endif /* QEMU_RFIFOLOCK_H */
|
@@ -30,6 +30,7 @@ typedef struct MemoryListener MemoryListener;
|
||||
|
||||
typedef struct MemoryMappingList MemoryMappingList;
|
||||
|
||||
typedef struct QEMUMachine QEMUMachine;
|
||||
typedef struct NICInfo NICInfo;
|
||||
typedef struct HCIInfo HCIInfo;
|
||||
typedef struct AudioState AudioState;
|
||||
|
@@ -21,6 +21,7 @@
|
||||
#define QEMU_CPU_H
|
||||
|
||||
#include <signal.h>
|
||||
#include <setjmp.h>
|
||||
#include "hw/qdev-core.h"
|
||||
#include "exec/hwaddr.h"
|
||||
#include "qemu/queue.h"
|
||||
@@ -68,8 +69,10 @@ struct TranslationBlock;
|
||||
* CPUClass:
|
||||
* @class_by_name: Callback to map -cpu command line model name to an
|
||||
* instantiatable CPU type.
|
||||
* @parse_features: Callback to parse command line arguments.
|
||||
* @reset: Callback to reset the #CPUState to its initial state.
|
||||
* @reset_dump_flags: #CPUDumpFlags to use for reset logging.
|
||||
* @has_work: Callback for checking if there is work to do.
|
||||
* @do_interrupt: Callback for interrupt handling.
|
||||
* @do_unassigned_access: Callback for unassigned access handling.
|
||||
* @memory_rw_debug: Callback for GDB memory access.
|
||||
@@ -81,6 +84,7 @@ struct TranslationBlock;
|
||||
* @set_pc: Callback for setting the Program Counter register.
|
||||
* @synchronize_from_tb: Callback for synchronizing state from a TCG
|
||||
* #TranslationBlock.
|
||||
* @handle_mmu_fault: Callback for handling an MMU fault.
|
||||
* @get_phys_page_debug: Callback for obtaining a physical address.
|
||||
* @gdb_read_register: Callback for letting GDB read a register.
|
||||
* @gdb_write_register: Callback for letting GDB write a register.
|
||||
@@ -96,9 +100,11 @@ typedef struct CPUClass {
|
||||
/*< public >*/
|
||||
|
||||
ObjectClass *(*class_by_name)(const char *cpu_model);
|
||||
void (*parse_features)(CPUState *cpu, char *str, Error **errp);
|
||||
|
||||
void (*reset)(CPUState *cpu);
|
||||
int reset_dump_flags;
|
||||
bool (*has_work)(CPUState *cpu);
|
||||
void (*do_interrupt)(CPUState *cpu);
|
||||
CPUUnassignedAccess do_unassigned_access;
|
||||
int (*memory_rw_debug)(CPUState *cpu, vaddr addr,
|
||||
@@ -113,6 +119,8 @@ typedef struct CPUClass {
|
||||
Error **errp);
|
||||
void (*set_pc)(CPUState *cpu, vaddr value);
|
||||
void (*synchronize_from_tb)(CPUState *cpu, struct TranslationBlock *tb);
|
||||
int (*handle_mmu_fault)(CPUState *cpu, vaddr address, int rw,
|
||||
int mmu_index);
|
||||
hwaddr (*get_phys_page_debug)(CPUState *cpu, vaddr addr);
|
||||
int (*gdb_read_register)(CPUState *cpu, uint8_t *buf, int reg);
|
||||
int (*gdb_write_register)(CPUState *cpu, uint8_t *buf, int reg);
|
||||
@@ -131,9 +139,37 @@ typedef struct CPUClass {
|
||||
const char *gdb_core_xml_file;
|
||||
} CPUClass;
|
||||
|
||||
#ifdef HOST_WORDS_BIGENDIAN
|
||||
typedef struct icount_decr_u16 {
|
||||
uint16_t high;
|
||||
uint16_t low;
|
||||
} icount_decr_u16;
|
||||
#else
|
||||
typedef struct icount_decr_u16 {
|
||||
uint16_t low;
|
||||
uint16_t high;
|
||||
} icount_decr_u16;
|
||||
#endif
|
||||
|
||||
typedef struct CPUBreakpoint {
|
||||
vaddr pc;
|
||||
int flags; /* BP_* */
|
||||
QTAILQ_ENTRY(CPUBreakpoint) entry;
|
||||
} CPUBreakpoint;
|
||||
|
||||
typedef struct CPUWatchpoint {
|
||||
vaddr vaddr;
|
||||
vaddr len_mask;
|
||||
int flags; /* BP_* */
|
||||
QTAILQ_ENTRY(CPUWatchpoint) entry;
|
||||
} CPUWatchpoint;
|
||||
|
||||
struct KVMState;
|
||||
struct kvm_run;
|
||||
|
||||
#define TB_JMP_CACHE_BITS 12
|
||||
#define TB_JMP_CACHE_SIZE (1 << TB_JMP_CACHE_BITS)
|
||||
|
||||
/**
|
||||
* CPUState:
|
||||
* @cpu_index: CPU index (informative).
|
||||
@@ -150,12 +186,20 @@ struct kvm_run;
|
||||
* @tcg_exit_req: Set to force TCG to stop executing linked TBs for this
|
||||
* CPU and return to its top level loop.
|
||||
* @singlestep_enabled: Flags for single-stepping.
|
||||
* @icount_extra: Instructions until next timer event.
|
||||
* @icount_decr: Number of cycles left, with interrupt flag in high bit.
|
||||
* This allows a single read-compare-cbranch-write sequence to test
|
||||
* for both decrementer underflow and exceptions.
|
||||
* @can_do_io: Nonzero if memory-mapped IO is safe.
|
||||
* @env_ptr: Pointer to subclass-specific CPUArchState field.
|
||||
* @current_tb: Currently executing TB.
|
||||
* @gdb_regs: Additional GDB registers.
|
||||
* @gdb_num_regs: Number of total registers accessible to GDB.
|
||||
* @gdb_num_g_regs: Number of registers in GDB 'g' packets.
|
||||
* @next_cpu: Next CPU sharing TB cache.
|
||||
* @opaque: User data.
|
||||
* @mem_io_pc: Host Program Counter at which the memory was accessed.
|
||||
* @mem_io_vaddr: Target virtual address at which the memory was accessed.
|
||||
* @kvm_fd: vCPU file descriptor for KVM.
|
||||
*
|
||||
* State of one CPU core or thread.
|
||||
@@ -186,17 +230,34 @@ struct CPUState {
|
||||
volatile sig_atomic_t tcg_exit_req;
|
||||
uint32_t interrupt_request;
|
||||
int singlestep_enabled;
|
||||
int64_t icount_extra;
|
||||
sigjmp_buf jmp_env;
|
||||
|
||||
AddressSpace *as;
|
||||
MemoryListener *tcg_as_listener;
|
||||
|
||||
void *env_ptr; /* CPUArchState */
|
||||
struct TranslationBlock *current_tb;
|
||||
struct TranslationBlock *tb_jmp_cache[TB_JMP_CACHE_SIZE];
|
||||
struct GDBRegisterState *gdb_regs;
|
||||
int gdb_num_regs;
|
||||
int gdb_num_g_regs;
|
||||
QTAILQ_ENTRY(CPUState) node;
|
||||
|
||||
/* ice debug support */
|
||||
QTAILQ_HEAD(breakpoints_head, CPUBreakpoint) breakpoints;
|
||||
|
||||
QTAILQ_HEAD(watchpoints_head, CPUWatchpoint) watchpoints;
|
||||
CPUWatchpoint *watchpoint_hit;
|
||||
|
||||
void *opaque;
|
||||
|
||||
/* In order to avoid passing too many arguments to the MMIO helpers,
|
||||
* we store some rarely used information in the CPU context.
|
||||
*/
|
||||
uintptr_t mem_io_pc;
|
||||
vaddr mem_io_vaddr;
|
||||
|
||||
int kvm_fd;
|
||||
bool kvm_vcpu_dirty;
|
||||
struct KVMState *kvm_state;
|
||||
@@ -205,6 +266,12 @@ struct CPUState {
|
||||
/* TODO Move common fields from CPUArchState here. */
|
||||
int cpu_index; /* used by alpha TCG */
|
||||
uint32_t halted; /* used by alpha, cris, ppc TCG */
|
||||
union {
|
||||
uint32_t u32;
|
||||
icount_decr_u16 u16;
|
||||
} icount_decr;
|
||||
uint32_t can_do_io;
|
||||
int32_t exception_index; /* used by m68k TCG */
|
||||
};
|
||||
|
||||
QTAILQ_HEAD(CPUTailQ, CPUState);
|
||||
@@ -348,14 +415,31 @@ void cpu_reset(CPUState *cpu);
|
||||
ObjectClass *cpu_class_by_name(const char *typename, const char *cpu_model);
|
||||
|
||||
/**
|
||||
* qemu_cpu_has_work:
|
||||
* cpu_generic_init:
|
||||
* @typename: The CPU base type.
|
||||
* @cpu_model: The model string including optional parameters.
|
||||
*
|
||||
* Instantiates a CPU, processes optional parameters and realizes the CPU.
|
||||
*
|
||||
* Returns: A #CPUState or %NULL if an error occurred.
|
||||
*/
|
||||
CPUState *cpu_generic_init(const char *typename, const char *cpu_model);
|
||||
|
||||
/**
|
||||
* cpu_has_work:
|
||||
* @cpu: The vCPU to check.
|
||||
*
|
||||
* Checks whether the CPU has work to do.
|
||||
*
|
||||
* Returns: %true if the CPU has work, %false otherwise.
|
||||
*/
|
||||
bool qemu_cpu_has_work(CPUState *cpu);
|
||||
static inline bool cpu_has_work(CPUState *cpu)
|
||||
{
|
||||
CPUClass *cc = CPU_GET_CLASS(cpu);
|
||||
|
||||
g_assert(cc->has_work);
|
||||
return cc->has_work(cpu);
|
||||
}
|
||||
|
||||
/**
|
||||
* qemu_cpu_is_self:
|
||||
@@ -511,6 +595,31 @@ void qemu_init_vcpu(CPUState *cpu);
|
||||
*/
|
||||
void cpu_single_step(CPUState *cpu, int enabled);
|
||||
|
||||
/* Breakpoint/watchpoint flags */
|
||||
#define BP_MEM_READ 0x01
|
||||
#define BP_MEM_WRITE 0x02
|
||||
#define BP_MEM_ACCESS (BP_MEM_READ | BP_MEM_WRITE)
|
||||
#define BP_STOP_BEFORE_ACCESS 0x04
|
||||
#define BP_WATCHPOINT_HIT 0x08
|
||||
#define BP_GDB 0x10
|
||||
#define BP_CPU 0x20
|
||||
|
||||
int cpu_breakpoint_insert(CPUState *cpu, vaddr pc, int flags,
|
||||
CPUBreakpoint **breakpoint);
|
||||
int cpu_breakpoint_remove(CPUState *cpu, vaddr pc, int flags);
|
||||
void cpu_breakpoint_remove_by_ref(CPUState *cpu, CPUBreakpoint *breakpoint);
|
||||
void cpu_breakpoint_remove_all(CPUState *cpu, int mask);
|
||||
|
||||
int cpu_watchpoint_insert(CPUState *cpu, vaddr addr, vaddr len,
|
||||
int flags, CPUWatchpoint **watchpoint);
|
||||
int cpu_watchpoint_remove(CPUState *cpu, vaddr addr,
|
||||
vaddr len, int flags);
|
||||
void cpu_watchpoint_remove_by_ref(CPUState *cpu, CPUWatchpoint *watchpoint);
|
||||
void cpu_watchpoint_remove_all(CPUState *cpu, int mask);
|
||||
|
||||
void QEMU_NORETURN cpu_abort(CPUState *cpu, const char *fmt, ...)
|
||||
GCC_FMT_ATTR(2, 3);
|
||||
|
||||
#ifdef CONFIG_SOFTMMU
|
||||
extern const struct VMStateDescription vmstate_cpu_common;
|
||||
#else
|
||||
|
@@ -973,6 +973,14 @@ const char *object_property_get_type(Object *obj, const char *name,
|
||||
*/
|
||||
Object *object_get_root(void);
|
||||
|
||||
/**
|
||||
* object_get_canonical_path_component:
|
||||
*
|
||||
* Returns: The final component in the object's canonical path. The canonical
|
||||
* path is the path within the composition tree starting from the root.
|
||||
*/
|
||||
gchar *object_get_canonical_path_component(Object *obj);
|
||||
|
||||
/**
|
||||
* object_get_canonical_path:
|
||||
*
|
||||
|
30
include/sysemu/iothread.h
Normal file
30
include/sysemu/iothread.h
Normal file
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Event loop thread
|
||||
*
|
||||
* Copyright Red Hat Inc., 2013
|
||||
*
|
||||
* Authors:
|
||||
* Stefan Hajnoczi <stefanha@redhat.com>
|
||||
*
|
||||
* This work is licensed under the terms of the GNU GPL, version 2 or later.
|
||||
* See the COPYING file in the top-level directory.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef IOTHREAD_H
|
||||
#define IOTHREAD_H
|
||||
|
||||
#include "block/aio.h"
|
||||
|
||||
#define TYPE_IOTHREAD "iothread"
|
||||
|
||||
typedef struct IOThread IOThread;
|
||||
|
||||
#define IOTHREAD(obj) \
|
||||
OBJECT_CHECK(IOThread, obj, TYPE_IOTHREAD)
|
||||
|
||||
IOThread *iothread_find(const char *id);
|
||||
char *iothread_get_id(IOThread *iothread);
|
||||
AioContext *iothread_get_aio_context(IOThread *iothread);
|
||||
|
||||
#endif /* IOTHREAD_H */
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user