Compare commits
333 Commits
vfio-fixes
...
pull-input
Author | SHA1 | Date | |
---|---|---|---|
|
ec044a80e7 | ||
|
8c10e0baf0 | ||
|
57d5c005d3 | ||
|
4df23b64c5 | ||
|
06b3611fc2 | ||
|
7cfdc02dae | ||
|
fb9f592623 | ||
|
d29a09ca68 | ||
|
d61e45ecc7 | ||
|
ab71cc0d58 | ||
|
fb1131b674 | ||
|
4355c1abca | ||
|
412e0e81b1 | ||
|
b1c7c07f2d | ||
|
d65abf85e7 | ||
|
ec55da1924 | ||
|
791b1daf72 | ||
|
f5ed36635d | ||
|
8275e2f6be | ||
|
152fcbecad | ||
|
2e0910329b | ||
|
973e7170dd | ||
|
9294d76c15 | ||
|
ed0a8d9252 | ||
|
5d443f5ada | ||
|
3b71ec8516 | ||
|
eaff9c4367 | ||
|
c229472af0 | ||
|
4c892756fd | ||
|
9ec8873e68 | ||
|
7864588150 | ||
|
e467da7b92 | ||
|
62acae8a9d | ||
|
eed875838e | ||
|
e4fd2e9dfc | ||
|
1f4c4d7361 | ||
|
5feb08ed8f | ||
|
26d5fa10ff | ||
|
ffec99f722 | ||
|
522ce4ecd4 | ||
|
476fb028bf | ||
|
486b88bdc8 | ||
|
7a9877a026 | ||
|
70e2cb3bd7 | ||
|
fbe2d8163e | ||
|
00949babe9 | ||
|
716df21707 | ||
|
b33945cfff | ||
|
9680caee0f | ||
|
6c1db528b0 | ||
|
1c89e1fa2f | ||
|
6bed028056 | ||
|
4e200cf8e6 | ||
|
0fe282bb4b | ||
|
5b7ba05fe7 | ||
|
f87a0e29a9 | ||
|
9b7e869167 | ||
|
14499ea541 | ||
|
38b5e4c3dc | ||
|
c2519009b4 | ||
|
1813d33015 | ||
|
bb9f8dd0e1 | ||
|
6de68ffd7c | ||
|
fea55615b2 | ||
|
0444a3b793 | ||
|
d7779acb30 | ||
|
2ef4186964 | ||
|
8a8001b147 | ||
|
3a87a954c8 | ||
|
e1be160691 | ||
|
d208ac0c2e | ||
|
e9deaad8a5 | ||
|
9b77336d83 | ||
|
97cba1a1d1 | ||
|
ec960b9a73 | ||
|
9445c28ec3 | ||
|
3d3a6eb60d | ||
|
a2bd7252fe | ||
|
5008fc787b | ||
|
28a0cccd54 | ||
|
a34ac8d472 | ||
|
65a03dd6c6 | ||
|
080d7aac31 | ||
|
c739cdddeb | ||
|
0d6ae94783 | ||
|
9c5ce8db2e | ||
|
315d318452 | ||
|
586d15ff87 | ||
|
2ef950f91d | ||
|
38440a21fa | ||
|
7c6f55b697 | ||
|
cb6414dfec | ||
|
3630be75d8 | ||
|
cea25275a3 | ||
|
0679f98b40 | ||
|
4814401fa0 | ||
|
27a83f8e7e | ||
|
58eb53083c | ||
|
0d594f5565 | ||
|
15ed653fa4 | ||
|
056b977521 | ||
|
5145ad4fad | ||
|
d76ab5e1c7 | ||
|
e3cffe6fad | ||
|
a8a6d53e36 | ||
|
7ebaf79556 | ||
|
fec5c62a64 | ||
|
ddb9ac50ae | ||
|
740ae9a27f | ||
|
f113283525 | ||
|
2391b35773 | ||
|
aa2008af0c | ||
|
48793c95c9 | ||
|
804108aaf9 | ||
|
2468f23dcb | ||
|
761a89c641 | ||
|
ff5f3981a2 | ||
|
4f364fe76f | ||
|
09bfe50d57 | ||
|
f19661c8b1 | ||
|
e8bb33de42 | ||
|
7ab6a501c6 | ||
|
028ec3cee3 | ||
|
24ac7755d7 | ||
|
f366e729f9 | ||
|
25c01db74b | ||
|
5a1f497186 | ||
|
5375c83b1e | ||
|
a70ab357cd | ||
|
eeddd59f59 | ||
|
8d6ef7c9fe | ||
|
aa15f49717 | ||
|
95cda4c44e | ||
|
ab04543602 | ||
|
01fe9a470c | ||
|
a5ad8fbf9d | ||
|
b5d569a1bb | ||
|
e7b1e06fbc | ||
|
6ca038c292 | ||
|
b5d5502047 | ||
|
68c6efe07a | ||
|
6867783a80 | ||
9e14037f05 | |||
|
95eaa78537 | ||
|
e678c56f16 | ||
|
d675765a02 | ||
|
d486ccaa9e | ||
|
2ccfd336dc | ||
|
e7f76c521f | ||
|
a43639b12d | ||
|
93ffc7c766 | ||
|
5e774eb3bd | ||
|
70bb1d16f4 | ||
|
3e76099aac | ||
|
d6ac342a48 | ||
|
8cf6e9daca | ||
|
1372fc0b87 | ||
|
77524d1157 | ||
|
6710172501 | ||
|
e8e4994313 | ||
|
2bf57f73e3 | ||
|
bcb39a65f1 | ||
|
5b262bb697 | ||
|
2a8b58703e | ||
|
e7ea81c37d | ||
|
780d23e54e | ||
|
de46f5f46c | ||
|
c6c7cfb01a | ||
|
b2fd45458d | ||
|
3755f9e316 | ||
|
67077e3014 | ||
|
9a7c175011 | ||
|
365aff1eaa | ||
|
8da33ef757 | ||
|
c3ba99f723 | ||
|
74fb1f3807 | ||
|
aaf4e67f0e | ||
|
b033271f11 | ||
|
ff90606f9a | ||
|
00442402ea | ||
|
dcf578ed8c | ||
|
f8d9ccf8d5 | ||
|
73e1b8f2f9 | ||
|
430da7a81d | ||
|
3648100e2a | ||
|
ffd455ae41 | ||
|
b98bbea2d9 | ||
|
5457dc9e37 | ||
|
45eafb4d32 | ||
|
5ea2fc84da | ||
|
7cfbd386b9 | ||
|
c4b3574402 | ||
|
c599d4d6d6 | ||
|
28298c912e | ||
|
0939166997 | ||
|
9d2803f720 | ||
|
8bd3773cce | ||
|
c836112997 | ||
|
ee8e76141b | ||
|
0ef9ea290e | ||
|
772034b63e | ||
|
e5a869ed56 | ||
|
f9757b1d96 | ||
|
3211215e74 | ||
|
68754b442b | ||
|
0cb581d6bd | ||
|
ce9c139d93 | ||
|
2ba7fae3bd | ||
|
700fa58e4b | ||
|
6080723102 | ||
|
26a6fc96e0 | ||
|
97b0797033 | ||
|
dab32b321f | ||
|
cf9dc9e480 | ||
|
819cec0114 | ||
|
4d6f8cbba7 | ||
|
4be4879ff8 | ||
|
88d88798b7 | ||
|
0c0c1fd973 | ||
|
f57b4b5fb1 | ||
|
f7c1553388 | ||
|
86ce1f6e2b | ||
|
ebb90a005d | ||
|
a008535b9f | ||
|
9b8595bca6 | ||
|
fa5376dd8a | ||
|
1560fcfa96 | ||
|
3f32bd21df | ||
|
33e1666b42 | ||
|
bd6092e407 | ||
|
3d47a1390b | ||
|
bdf0513323 | ||
|
842894994e | ||
|
5c678ee8d9 | ||
|
4bdadd8671 | ||
|
a0067da157 | ||
|
077b009ebb | ||
|
2b9e35760a | ||
|
9e812b6adc | ||
|
c823501ea9 | ||
|
b804dc3bcd | ||
|
5032a16d1d | ||
|
60b03e4e6a | ||
|
edcfaefe07 | ||
|
d79bedfa40 | ||
|
94cfd07f26 | ||
|
119ebac1fe | ||
|
3688d8c717 | ||
|
b57482d7a0 | ||
|
533008f4f3 | ||
|
2ab66cd577 | ||
|
acd0dfd0c2 | ||
|
e74aabcffb | ||
|
8813800b7d | ||
|
3bd18890ca | ||
|
59b060be18 | ||
|
55b90fc766 | ||
|
6e98670feb | ||
|
0f2fa73ba0 | ||
|
13fd08e631 | ||
|
4d4ccabdd2 | ||
|
7aa2adc283 | ||
|
e32652f759 | ||
|
1e4738b2d4 | ||
|
e73316d594 | ||
|
6bd7776cd0 | ||
|
e3571ae30c | ||
|
34f939218c | ||
|
cc19e497a0 | ||
|
ce1bd93f94 | ||
|
61e4c432ab | ||
|
ae2264d526 | ||
|
a1e69e2f81 | ||
|
f8f03b3707 | ||
|
c9314d610e | ||
|
7b4af5ee8a | ||
|
6f0b99104a | ||
|
5bbadbdfd6 | ||
|
40f191ab82 | ||
|
c7a59c2a92 | ||
|
a7d00d4eff | ||
|
f65e19bc2c | ||
|
be2208e2a5 | ||
|
01ecaf438b | ||
|
85aa80813d | ||
|
557a4cc04a | ||
|
993f8054d1 | ||
|
e3e83f2e21 | ||
|
abdf008640 | ||
|
da4bc86c54 | ||
|
799fe087e4 | ||
|
ebc231d7da | ||
|
5f473241ac | ||
|
518352b601 | ||
|
d1b4259f1a | ||
|
39c88f5697 | ||
|
46f5feaa0a | ||
|
927d5a1d98 | ||
|
afe4c95331 | ||
|
38e826de00 | ||
|
7ad9339e37 | ||
|
11d816a5bc | ||
|
ec8193a001 | ||
|
416296a9d1 | ||
|
57ddd73e61 | ||
|
c1bc91c35c | ||
|
ac4e29f100 | ||
|
a41c457881 | ||
|
d4b84d564e | ||
|
d7d26226b8 | ||
|
ace18d198a | ||
|
f586d5fc60 | ||
|
460423d3a4 | ||
|
8a90f9008b | ||
|
d46d14e631 | ||
|
47b98d5944 | ||
|
344aa283b8 | ||
|
347519eb9d | ||
|
d41f3c3cc7 | ||
|
885b7c44e4 | ||
|
89d0a64f49 | ||
71200fb966 | |||
|
0d8e065fc5 | ||
|
b8da57fa15 | ||
|
7616f1c2da | ||
|
bb93e09988 | ||
|
d251157ac1 | ||
|
58268c8d3d | ||
|
883e4f7624 | ||
|
d9911d14e0 | ||
|
670e56d3ed | ||
|
2a2d69f490 | ||
|
cd723b8560 |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -55,7 +55,6 @@
|
||||
/qemu-monitor-info.texi
|
||||
/qemu-version.h
|
||||
/qemu-version.h.tmp
|
||||
/qmp-commands.txt
|
||||
/vscclient
|
||||
/fsdev/virtfs-proxy-helper
|
||||
*.[1-9]
|
||||
|
53
MAINTAINERS
53
MAINTAINERS
@@ -83,6 +83,7 @@ F: include/exec/cpu*.h
|
||||
F: include/exec/exec-all.h
|
||||
F: include/exec/helper*.h
|
||||
F: include/exec/tb-hash.h
|
||||
F: include/sysemu/cpus.h
|
||||
|
||||
FPU emulation
|
||||
M: Aurelien Jarno <aurelien@aurel32.net>
|
||||
@@ -171,6 +172,7 @@ L: qemu-ppc@nongnu.org
|
||||
S: Maintained
|
||||
F: target-ppc/
|
||||
F: hw/ppc/
|
||||
F: include/hw/ppc/
|
||||
F: disas/ppc.c
|
||||
|
||||
S390
|
||||
@@ -187,6 +189,7 @@ S: Odd Fixes
|
||||
F: target-sh4/
|
||||
F: hw/sh4/
|
||||
F: disas/sh4.c
|
||||
F: include/hw/sh4/
|
||||
|
||||
SPARC
|
||||
M: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
|
||||
@@ -202,6 +205,7 @@ M: Guan Xuetao <gxt@mprc.pku.edu.cn>
|
||||
S: Maintained
|
||||
F: target-unicore32/
|
||||
F: hw/unicore32/
|
||||
F: include/hw/unicore32/
|
||||
|
||||
X86
|
||||
M: Paolo Bonzini <pbonzini@redhat.com>
|
||||
@@ -225,6 +229,7 @@ M: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
|
||||
S: Maintained
|
||||
F: target-tricore/
|
||||
F: hw/tricore/
|
||||
F: include/hw/tricore/
|
||||
|
||||
Guest CPU Cores (KVM):
|
||||
----------------------
|
||||
@@ -456,7 +461,6 @@ S: Maintained
|
||||
F: hw/*/xilinx_*
|
||||
F: hw/*/cadence_*
|
||||
F: hw/misc/zynq_slcr.c
|
||||
F: include/hw/xilinx.h
|
||||
X: hw/ssi/xilinx_*
|
||||
|
||||
Xilinx ZynqMP
|
||||
@@ -465,7 +469,7 @@ M: Edgar E. Iglesias <edgar.iglesias@gmail.com>
|
||||
L: qemu-arm@nongnu.org
|
||||
S: Maintained
|
||||
F: hw/*/xlnx*.c
|
||||
F: include/hw/*/xlnx*.c
|
||||
F: include/hw/*/xlnx*.h
|
||||
|
||||
ARM ACPI Subsystem
|
||||
M: Shannon Zhao <zhaoshenglong@huawei.com>
|
||||
@@ -571,6 +575,9 @@ L: qemu-ppc@nongnu.org
|
||||
S: Supported
|
||||
F: hw/ppc/e500.[hc]
|
||||
F: hw/ppc/e500plat.c
|
||||
F: include/hw/ppc/ppc_e500.h
|
||||
F: include/hw/pci-host/ppce500.h
|
||||
F: pc-bios/u-boot.e500
|
||||
|
||||
mpc8544ds
|
||||
M: Alexander Graf <agraf@suse.de>
|
||||
@@ -588,6 +595,8 @@ F: hw/ppc/mac_newworld.c
|
||||
F: hw/pci-host/uninorth.c
|
||||
F: hw/pci-bridge/dec.[hc]
|
||||
F: hw/misc/macio/
|
||||
F: include/hw/ppc/mac_dbdma.h
|
||||
F: hw/nvram/mac_nvram.c
|
||||
|
||||
Old World
|
||||
M: Alexander Graf <agraf@suse.de>
|
||||
@@ -615,6 +624,14 @@ F: include/hw/*/spapr*
|
||||
F: hw/*/xics*
|
||||
F: include/hw/*/xics*
|
||||
F: pc-bios/spapr-rtas/*
|
||||
F: pc-bios/spapr-rtas.bin
|
||||
F: pc-bios/slof.bin
|
||||
F: docs/specs/ppc-spapr-hcalls.txt
|
||||
F: docs/specs/ppc-spapr-hotplug.txt
|
||||
F: tests/spapr*
|
||||
F: tests/libqos/*spapr*
|
||||
F: tests/rtas*
|
||||
F: tests/libqos/rtas*
|
||||
|
||||
virtex_ml507
|
||||
M: Edgar E. Iglesias <edgar.iglesias@gmail.com>
|
||||
@@ -666,6 +683,9 @@ F: hw/s390x/
|
||||
F: include/hw/s390x/
|
||||
F: pc-bios/s390-ccw/
|
||||
F: hw/watchdog/wdt_diag288.c
|
||||
F: include/hw/watchdog/wdt_diag288.h
|
||||
F: pc-bios/s390-ccw.img
|
||||
F: default-configs/s390x-softmmu.mak
|
||||
T: git git://github.com/cohuck/qemu.git s390-next
|
||||
T: git git://github.com/borntraeger/qemu.git s390-next
|
||||
|
||||
@@ -695,7 +715,7 @@ F: hw/i2c/smbus_ich9.c
|
||||
F: hw/acpi/piix4.c
|
||||
F: hw/acpi/ich9.c
|
||||
F: include/hw/acpi/ich9.h
|
||||
F: include/hw/acpi/piix.h
|
||||
F: include/hw/acpi/piix4.h
|
||||
F: hw/misc/sga.c
|
||||
|
||||
PC Chipset
|
||||
@@ -801,16 +821,15 @@ F: hw/mem/*
|
||||
F: hw/acpi/*
|
||||
F: hw/smbios/*
|
||||
F: hw/i386/acpi-build.[hc]
|
||||
F: hw/i386/*dsl
|
||||
F: hw/arm/virt-acpi-build.c
|
||||
F: include/hw/arm/virt-acpi-build.h
|
||||
F: scripts/acpi*py
|
||||
|
||||
ppc4xx
|
||||
M: Alexander Graf <agraf@suse.de>
|
||||
L: qemu-ppc@nongnu.org
|
||||
S: Odd Fixes
|
||||
F: hw/ppc/ppc4*.c
|
||||
F: include/hw/ppc/ppc4xx.h
|
||||
|
||||
ppce500
|
||||
M: Alexander Graf <agraf@suse.de>
|
||||
@@ -830,6 +849,7 @@ Network devices
|
||||
M: Jason Wang <jasowang@redhat.com>
|
||||
S: Odd Fixes
|
||||
F: hw/net/
|
||||
F: tests/virtio-net-test.c
|
||||
T: git git://github.com/jasowang/qemu.git net
|
||||
|
||||
SCSI
|
||||
@@ -837,6 +857,7 @@ M: Paolo Bonzini <pbonzini@redhat.com>
|
||||
S: Supported
|
||||
F: include/hw/scsi/*
|
||||
F: hw/scsi/*
|
||||
F: tests/virtio-scsi-test.c
|
||||
T: git git://github.com/bonzini/qemu.git scsi-next
|
||||
|
||||
LSI53C895A
|
||||
@@ -889,6 +910,7 @@ S: Supported
|
||||
F: hw/*/virtio*
|
||||
F: net/vhost-user.c
|
||||
F: include/hw/virtio/
|
||||
F: tests/virtio-balloon-test.c
|
||||
|
||||
virtio-9p
|
||||
M: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
|
||||
@@ -906,7 +928,7 @@ L: qemu-block@nongnu.org
|
||||
S: Supported
|
||||
F: hw/block/virtio-blk.c
|
||||
F: hw/block/dataplane/*
|
||||
F: hw/virtio/dataplane/*
|
||||
F: tests/virtio-blk-test.c
|
||||
T: git git://github.com/stefanha/qemu.git block
|
||||
|
||||
virtio-ccw
|
||||
@@ -929,6 +951,8 @@ S: Supported
|
||||
F: hw/char/virtio-serial-bus.c
|
||||
F: hw/char/virtio-console.c
|
||||
F: include/hw/virtio/virtio-serial.h
|
||||
F: tests/virtio-console-test.c
|
||||
F: tests/virtio-serial-test.c
|
||||
|
||||
virtio-rng
|
||||
M: Amit Shah <amit.shah@redhat.com>
|
||||
@@ -937,6 +961,7 @@ F: hw/virtio/virtio-rng.c
|
||||
F: include/hw/virtio/virtio-rng.h
|
||||
F: include/sysemu/rng*.h
|
||||
F: backends/rng*.c
|
||||
F: tests/virtio-rng-test.c
|
||||
|
||||
nvme
|
||||
M: Keith Busch <keith.busch@intel.com>
|
||||
@@ -1068,12 +1093,6 @@ S: Supported
|
||||
F: qom/cpu.c
|
||||
F: include/qom/cpu.h
|
||||
|
||||
ICC Bus
|
||||
M: Igor Mammedov <imammedo@redhat.com>
|
||||
S: Supported
|
||||
F: include/hw/cpu/icc_bus.h
|
||||
F: hw/cpu/icc_bus.c
|
||||
|
||||
Device Tree
|
||||
M: Peter Crosthwaite <crosthwaite.peter@gmail.com>
|
||||
M: Alexander Graf <agraf@suse.de>
|
||||
@@ -1241,7 +1260,6 @@ M: Markus Armbruster <armbru@redhat.com>
|
||||
S: Supported
|
||||
F: qmp.c
|
||||
F: monitor.c
|
||||
F: qmp-commands.hx
|
||||
F: docs/*qmp-*
|
||||
F: scripts/qmp/
|
||||
T: git git://repo.or.cz/qemu/armbru.git qapi-next
|
||||
@@ -1339,6 +1357,13 @@ F: include/qemu/throttle.h
|
||||
F: util/throttle.c
|
||||
L: qemu-block@nongnu.org
|
||||
|
||||
UUID
|
||||
M: Fam Zheng <famz@redhat.com>
|
||||
S: Supported
|
||||
F: util/uuid.c
|
||||
F: include/qemu/uuid.h
|
||||
F: tests/test-uuid.c
|
||||
|
||||
Usermode Emulation
|
||||
------------------
|
||||
Overall
|
||||
@@ -1589,7 +1614,7 @@ M: Kevin Wolf <kwolf@redhat.com>
|
||||
L: qemu-block@nongnu.org
|
||||
S: Supported
|
||||
F: block/linux-aio.c
|
||||
F: block/raw-aio.h
|
||||
F: include/block/raw-aio.h
|
||||
F: block/raw-posix.c
|
||||
F: block/raw-win32.c
|
||||
F: block/raw_bsd.c
|
||||
|
55
Makefile
55
Makefile
@@ -76,6 +76,8 @@ GENERATED_HEADERS += trace/generated-ust-provider.h
|
||||
GENERATED_SOURCES += trace/generated-ust.c
|
||||
endif
|
||||
|
||||
GENERATED_HEADERS += module_block.h
|
||||
|
||||
# Don't try to regenerate Makefile or configure
|
||||
# We don't generate any of them
|
||||
Makefile: ;
|
||||
@@ -92,7 +94,6 @@ HELPERS-$(CONFIG_LINUX) = qemu-bridge-helper$(EXESUF)
|
||||
|
||||
ifdef BUILD_DOCS
|
||||
DOCS=qemu-doc.html qemu-tech.html qemu.1 qemu-img.1 qemu-nbd.8 qemu-ga.8
|
||||
DOCS+=qmp-commands.txt
|
||||
ifdef CONFIG_VIRTFS
|
||||
DOCS+=fsdev/virtfs-proxy-helper.1
|
||||
endif
|
||||
@@ -246,9 +247,6 @@ Makefile: $(version-obj-y) $(version-lobj-y)
|
||||
libqemustub.a: $(stub-obj-y)
|
||||
libqemuutil.a: $(util-obj-y)
|
||||
|
||||
block-modules = $(foreach o,$(block-obj-m),"$(basename $(subst /,-,$o))",) NULL
|
||||
util/module.o-cflags = -D'CONFIG_BLOCK_MODULES=$(block-modules)'
|
||||
|
||||
######################################################################
|
||||
|
||||
qemu-img.o: qemu-img-cmds.h
|
||||
@@ -312,7 +310,7 @@ $(qapi-modules) $(SRC_PATH)/scripts/qapi-event.py $(qapi-py)
|
||||
qmp-commands.h qmp-marshal.c :\
|
||||
$(qapi-modules) $(SRC_PATH)/scripts/qapi-commands.py $(qapi-py)
|
||||
$(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-commands.py \
|
||||
$(gen-out-type) -o "." -m $<, \
|
||||
$(gen-out-type) -o "." $<, \
|
||||
" GEN $@")
|
||||
qmp-introspect.h qmp-introspect.c :\
|
||||
$(qapi-modules) $(SRC_PATH)/scripts/qapi-introspect.py $(qapi-py)
|
||||
@@ -353,6 +351,11 @@ ivshmem-client$(EXESUF): $(ivshmem-client-obj-y) libqemuutil.a libqemustub.a
|
||||
ivshmem-server$(EXESUF): $(ivshmem-server-obj-y) libqemuutil.a libqemustub.a
|
||||
$(call LINK, $^)
|
||||
|
||||
module_block.h: $(SRC_PATH)/scripts/modules/module_block.py config-host.mak
|
||||
$(call quiet-command,$(PYTHON) $< $@ \
|
||||
$(addprefix $(SRC_PATH)/,$(patsubst %.mo,%.c,$(block-obj-m))), \
|
||||
" GEN $@")
|
||||
|
||||
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
|
||||
@@ -432,7 +435,7 @@ endif
|
||||
install-doc: $(DOCS)
|
||||
$(INSTALL_DIR) "$(DESTDIR)$(qemu_docdir)"
|
||||
$(INSTALL_DATA) qemu-doc.html qemu-tech.html "$(DESTDIR)$(qemu_docdir)"
|
||||
$(INSTALL_DATA) qmp-commands.txt "$(DESTDIR)$(qemu_docdir)"
|
||||
$(INSTALL_DATA) $(SRC_PATH)/docs/qmp-commands.txt "$(DESTDIR)$(qemu_docdir)"
|
||||
ifdef CONFIG_POSIX
|
||||
$(INSTALL_DIR) "$(DESTDIR)$(mandir)/man1"
|
||||
$(INSTALL_DATA) qemu.1 "$(DESTDIR)$(mandir)/man1"
|
||||
@@ -555,9 +558,6 @@ qemu-monitor.texi: $(SRC_PATH)/hmp-commands.hx $(SRC_PATH)/scripts/hxtool
|
||||
qemu-monitor-info.texi: $(SRC_PATH)/hmp-commands-info.hx $(SRC_PATH)/scripts/hxtool
|
||||
$(call quiet-command,sh $(SRC_PATH)/scripts/hxtool -t < $< > $@," GEN $@")
|
||||
|
||||
qmp-commands.txt: $(SRC_PATH)/qmp-commands.hx $(SRC_PATH)/scripts/hxtool
|
||||
$(call quiet-command,sh $(SRC_PATH)/scripts/hxtool -q < $< > $@," GEN $@")
|
||||
|
||||
qemu-img-cmds.texi: $(SRC_PATH)/qemu-img-cmds.hx $(SRC_PATH)/scripts/hxtool
|
||||
$(call quiet-command,sh $(SRC_PATH)/scripts/hxtool -t < $< > $@," GEN $@")
|
||||
|
||||
@@ -669,3 +669,40 @@ endif
|
||||
-include $(wildcard *.d tests/*.d)
|
||||
|
||||
include $(SRC_PATH)/tests/docker/Makefile.include
|
||||
|
||||
.PHONY: help
|
||||
help:
|
||||
@echo 'Generic targets:'
|
||||
@echo ' all - Build all'
|
||||
@echo ' dir/file.o - Build specified target only'
|
||||
@echo ' install - Install QEMU, documentation and tools'
|
||||
@echo ' ctags/TAGS - Generate tags file for editors'
|
||||
@echo ' cscope - Generate cscope index'
|
||||
@echo ''
|
||||
@$(if $(TARGET_DIRS), \
|
||||
echo 'Architecture specific targets:'; \
|
||||
$(foreach t, $(TARGET_DIRS), \
|
||||
printf " %-30s - Build for %s\\n" $(patsubst %,subdir-%,$(t)) $(t);) \
|
||||
echo '')
|
||||
@echo 'Cleaning targets:'
|
||||
@echo ' clean - Remove most generated files but keep the config'
|
||||
@echo ' distclean - Remove all generated files'
|
||||
@echo ' dist - Build a distributable tarball'
|
||||
@echo ''
|
||||
@echo 'Test targets:'
|
||||
@echo ' check - Run all tests (check-help for details)'
|
||||
@echo ' docker - Help about targets running tests inside Docker containers'
|
||||
@echo ''
|
||||
@echo 'Documentation targets:'
|
||||
@echo ' dvi html info pdf'
|
||||
@echo ' - Build documentation in specified format'
|
||||
@echo ''
|
||||
ifdef CONFIG_WIN32
|
||||
@echo 'Windows targets:'
|
||||
@echo ' installer - Build NSIS-based installer for qemu-ga'
|
||||
ifdef QEMU_GA_MSI_ENABLED
|
||||
@echo ' msi - Build MSI-based installer for qemu-ga'
|
||||
endif
|
||||
@echo ''
|
||||
endif
|
||||
@echo ' make V=0|1 [targets] 0 => quiet build (default), 1 => verbose build'
|
||||
|
@@ -156,7 +156,7 @@ else
|
||||
obj-y += hw/$(TARGET_BASE_ARCH)/
|
||||
endif
|
||||
|
||||
GENERATED_HEADERS += hmp-commands.h hmp-commands-info.h qmp-commands-old.h
|
||||
GENERATED_HEADERS += hmp-commands.h hmp-commands-info.h
|
||||
|
||||
endif # CONFIG_SOFTMMU
|
||||
|
||||
@@ -209,13 +209,10 @@ hmp-commands.h: $(SRC_PATH)/hmp-commands.hx $(SRC_PATH)/scripts/hxtool
|
||||
hmp-commands-info.h: $(SRC_PATH)/hmp-commands-info.hx $(SRC_PATH)/scripts/hxtool
|
||||
$(call quiet-command,sh $(SRC_PATH)/scripts/hxtool -h < $< > $@," GEN $(TARGET_DIR)$@")
|
||||
|
||||
qmp-commands-old.h: $(SRC_PATH)/qmp-commands.hx $(SRC_PATH)/scripts/hxtool
|
||||
$(call quiet-command,sh $(SRC_PATH)/scripts/hxtool -h < $< > $@," GEN $(TARGET_DIR)$@")
|
||||
|
||||
clean: clean-target
|
||||
rm -f *.a *~ $(PROGS)
|
||||
rm -f $(shell find . -name '*.[od]')
|
||||
rm -f hmp-commands.h qmp-commands-old.h gdbstub-xml.c
|
||||
rm -f hmp-commands.h gdbstub-xml.c
|
||||
ifdef CONFIG_TRACE_SYSTEMTAP
|
||||
rm -f *.stp
|
||||
endif
|
||||
|
19
arch_init.c
19
arch_init.c
@@ -235,25 +235,6 @@ void audio_init(void)
|
||||
}
|
||||
}
|
||||
|
||||
int qemu_uuid_parse(const char *str, uint8_t *uuid)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (strlen(str) != 36) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = sscanf(str, UUID_FMT, &uuid[0], &uuid[1], &uuid[2], &uuid[3],
|
||||
&uuid[4], &uuid[5], &uuid[6], &uuid[7], &uuid[8], &uuid[9],
|
||||
&uuid[10], &uuid[11], &uuid[12], &uuid[13], &uuid[14],
|
||||
&uuid[15]);
|
||||
|
||||
if (ret != 16) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void do_acpitable_option(const QemuOpts *opts)
|
||||
{
|
||||
#ifdef TARGET_I386
|
||||
|
@@ -139,7 +139,6 @@ static void msmouse_chr_close (struct CharDriverState *chr)
|
||||
|
||||
qemu_input_handler_unregister(mouse->hs);
|
||||
g_free(mouse);
|
||||
g_free(chr);
|
||||
}
|
||||
|
||||
static QemuInputHandler msmouse_handler = {
|
||||
@@ -159,6 +158,9 @@ static CharDriverState *qemu_chr_open_msmouse(const char *id,
|
||||
CharDriverState *chr;
|
||||
|
||||
chr = qemu_chr_alloc(common, errp);
|
||||
if (!chr) {
|
||||
return NULL;
|
||||
}
|
||||
chr->chr_write = msmouse_chr_write;
|
||||
chr->chr_close = msmouse_chr_close;
|
||||
chr->chr_accept_input = msmouse_chr_accept_input;
|
||||
|
151
block.c
151
block.c
@@ -27,6 +27,7 @@
|
||||
#include "block/blockjob.h"
|
||||
#include "block/nbd.h"
|
||||
#include "qemu/error-report.h"
|
||||
#include "module_block.h"
|
||||
#include "qemu/module.h"
|
||||
#include "qapi/qmp/qerror.h"
|
||||
#include "qapi/qmp/qbool.h"
|
||||
@@ -242,17 +243,40 @@ BlockDriverState *bdrv_new(void)
|
||||
return bs;
|
||||
}
|
||||
|
||||
BlockDriver *bdrv_find_format(const char *format_name)
|
||||
static BlockDriver *bdrv_do_find_format(const char *format_name)
|
||||
{
|
||||
BlockDriver *drv1;
|
||||
|
||||
QLIST_FOREACH(drv1, &bdrv_drivers, list) {
|
||||
if (!strcmp(drv1->format_name, format_name)) {
|
||||
return drv1;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
BlockDriver *bdrv_find_format(const char *format_name)
|
||||
{
|
||||
BlockDriver *drv1;
|
||||
int i;
|
||||
|
||||
drv1 = bdrv_do_find_format(format_name);
|
||||
if (drv1) {
|
||||
return drv1;
|
||||
}
|
||||
|
||||
/* The driver isn't registered, maybe we need to load a module */
|
||||
for (i = 0; i < (int)ARRAY_SIZE(block_driver_modules); ++i) {
|
||||
if (!strcmp(block_driver_modules[i].format_name, format_name)) {
|
||||
block_module_load_one(block_driver_modules[i].library_name);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return bdrv_do_find_format(format_name);
|
||||
}
|
||||
|
||||
static int bdrv_is_whitelisted(BlockDriver *drv, bool read_only)
|
||||
{
|
||||
static const char *whitelist_rw[] = {
|
||||
@@ -461,6 +485,19 @@ static BlockDriver *find_hdev_driver(const char *filename)
|
||||
return drv;
|
||||
}
|
||||
|
||||
static BlockDriver *bdrv_do_find_protocol(const char *protocol)
|
||||
{
|
||||
BlockDriver *drv1;
|
||||
|
||||
QLIST_FOREACH(drv1, &bdrv_drivers, list) {
|
||||
if (drv1->protocol_name && !strcmp(drv1->protocol_name, protocol)) {
|
||||
return drv1;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
BlockDriver *bdrv_find_protocol(const char *filename,
|
||||
bool allow_protocol_prefix,
|
||||
Error **errp)
|
||||
@@ -469,6 +506,7 @@ BlockDriver *bdrv_find_protocol(const char *filename,
|
||||
char protocol[128];
|
||||
int len;
|
||||
const char *p;
|
||||
int i;
|
||||
|
||||
/* TODO Drivers without bdrv_file_open must be specified explicitly */
|
||||
|
||||
@@ -495,15 +533,25 @@ BlockDriver *bdrv_find_protocol(const char *filename,
|
||||
len = sizeof(protocol) - 1;
|
||||
memcpy(protocol, filename, len);
|
||||
protocol[len] = '\0';
|
||||
QLIST_FOREACH(drv1, &bdrv_drivers, list) {
|
||||
if (drv1->protocol_name &&
|
||||
!strcmp(drv1->protocol_name, protocol)) {
|
||||
return drv1;
|
||||
|
||||
drv1 = bdrv_do_find_protocol(protocol);
|
||||
if (drv1) {
|
||||
return drv1;
|
||||
}
|
||||
|
||||
for (i = 0; i < (int)ARRAY_SIZE(block_driver_modules); ++i) {
|
||||
if (block_driver_modules[i].protocol_name &&
|
||||
!strcmp(block_driver_modules[i].protocol_name, protocol)) {
|
||||
block_module_load_one(block_driver_modules[i].library_name);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
error_setg(errp, "Unknown protocol '%s'", protocol);
|
||||
return NULL;
|
||||
drv1 = bdrv_do_find_protocol(protocol);
|
||||
if (!drv1) {
|
||||
error_setg(errp, "Unknown protocol '%s'", protocol);
|
||||
}
|
||||
return drv1;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -685,6 +733,9 @@ static void bdrv_temp_snapshot_options(int *child_flags, QDict *child_options,
|
||||
qdict_set_default_str(child_options, BDRV_OPT_CACHE_DIRECT, "off");
|
||||
qdict_set_default_str(child_options, BDRV_OPT_CACHE_NO_FLUSH, "on");
|
||||
|
||||
/* Copy the read-only option from the parent */
|
||||
qdict_copy_default(child_options, parent_options, BDRV_OPT_READ_ONLY);
|
||||
|
||||
/* aio=native doesn't work for cache.direct=off, so disable it for the
|
||||
* temporary snapshot */
|
||||
*child_flags &= ~BDRV_O_NATIVE_AIO;
|
||||
@@ -707,6 +758,9 @@ static void bdrv_inherited_options(int *child_flags, QDict *child_options,
|
||||
qdict_copy_default(child_options, parent_options, BDRV_OPT_CACHE_DIRECT);
|
||||
qdict_copy_default(child_options, parent_options, BDRV_OPT_CACHE_NO_FLUSH);
|
||||
|
||||
/* Inherit the read-only option from the parent if it's not set */
|
||||
qdict_copy_default(child_options, parent_options, BDRV_OPT_READ_ONLY);
|
||||
|
||||
/* Our block drivers take care to send flushes and respect unmap policy,
|
||||
* so we can default to enable both on lower layers regardless of the
|
||||
* corresponding parent options. */
|
||||
@@ -760,7 +814,8 @@ static void bdrv_backing_options(int *child_flags, QDict *child_options,
|
||||
qdict_copy_default(child_options, parent_options, BDRV_OPT_CACHE_NO_FLUSH);
|
||||
|
||||
/* backing files always opened read-only */
|
||||
flags &= ~(BDRV_O_RDWR | BDRV_O_COPY_ON_READ);
|
||||
qdict_set_default_str(child_options, BDRV_OPT_READ_ONLY, "on");
|
||||
flags &= ~BDRV_O_COPY_ON_READ;
|
||||
|
||||
/* snapshot=on is handled on the top layer */
|
||||
flags &= ~(BDRV_O_SNAPSHOT | BDRV_O_TEMPORARY);
|
||||
@@ -807,6 +862,14 @@ static void update_flags_from_options(int *flags, QemuOpts *opts)
|
||||
if (qemu_opt_get_bool(opts, BDRV_OPT_CACHE_DIRECT, false)) {
|
||||
*flags |= BDRV_O_NOCACHE;
|
||||
}
|
||||
|
||||
*flags &= ~BDRV_O_RDWR;
|
||||
|
||||
assert(qemu_opt_find(opts, BDRV_OPT_READ_ONLY));
|
||||
if (!qemu_opt_get_bool(opts, BDRV_OPT_READ_ONLY, false)) {
|
||||
*flags |= BDRV_O_RDWR;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void update_options_from_flags(QDict *options, int flags)
|
||||
@@ -819,6 +882,10 @@ static void update_options_from_flags(QDict *options, int flags)
|
||||
qdict_put(options, BDRV_OPT_CACHE_NO_FLUSH,
|
||||
qbool_from_bool(flags & BDRV_O_NO_FLUSH));
|
||||
}
|
||||
if (!qdict_haskey(options, BDRV_OPT_READ_ONLY)) {
|
||||
qdict_put(options, BDRV_OPT_READ_ONLY,
|
||||
qbool_from_bool(!(flags & BDRV_O_RDWR)));
|
||||
}
|
||||
}
|
||||
|
||||
static void bdrv_assign_node_name(BlockDriverState *bs,
|
||||
@@ -882,6 +949,11 @@ static QemuOptsList bdrv_runtime_opts = {
|
||||
.type = QEMU_OPT_BOOL,
|
||||
.help = "Ignore flush requests",
|
||||
},
|
||||
{
|
||||
.name = BDRV_OPT_READ_ONLY,
|
||||
.type = QEMU_OPT_BOOL,
|
||||
.help = "Node is opened in read-only mode",
|
||||
},
|
||||
{ /* end of list */ }
|
||||
},
|
||||
};
|
||||
@@ -913,6 +985,8 @@ static int bdrv_open_common(BlockDriverState *bs, BdrvChild *file,
|
||||
goto fail_opts;
|
||||
}
|
||||
|
||||
update_flags_from_options(&bs->open_flags, opts);
|
||||
|
||||
driver_name = qemu_opt_get(opts, "driver");
|
||||
drv = bdrv_find_format(driver_name);
|
||||
assert(drv != NULL);
|
||||
@@ -974,9 +1048,6 @@ static int bdrv_open_common(BlockDriverState *bs, BdrvChild *file,
|
||||
bs->drv = drv;
|
||||
bs->opaque = g_malloc0(drv->instance_size);
|
||||
|
||||
/* Apply cache mode options */
|
||||
update_flags_from_options(&bs->open_flags, opts);
|
||||
|
||||
/* Open the image, either directly or using a protocol */
|
||||
open_flags = bdrv_open_flags(bs, bs->open_flags);
|
||||
if (drv->bdrv_file_open) {
|
||||
@@ -1627,6 +1698,25 @@ static BlockDriverState *bdrv_open_inherit(const char *filename,
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* Set the BDRV_O_RDWR and BDRV_O_ALLOW_RDWR flags.
|
||||
* FIXME: we're parsing the QDict to avoid having to create a
|
||||
* QemuOpts just for this, but neither option is optimal. */
|
||||
if (g_strcmp0(qdict_get_try_str(options, BDRV_OPT_READ_ONLY), "on") &&
|
||||
!qdict_get_try_bool(options, BDRV_OPT_READ_ONLY, false)) {
|
||||
flags |= (BDRV_O_RDWR | BDRV_O_ALLOW_RDWR);
|
||||
} else {
|
||||
flags &= ~BDRV_O_RDWR;
|
||||
}
|
||||
|
||||
if (flags & BDRV_O_SNAPSHOT) {
|
||||
snapshot_options = qdict_new();
|
||||
bdrv_temp_snapshot_options(&snapshot_flags, snapshot_options,
|
||||
flags, options);
|
||||
/* Let bdrv_backing_options() override "read-only" */
|
||||
qdict_del(options, BDRV_OPT_READ_ONLY);
|
||||
bdrv_backing_options(&flags, options, flags, options);
|
||||
}
|
||||
|
||||
bs->open_flags = flags;
|
||||
bs->options = options;
|
||||
options = qdict_clone_shallow(options);
|
||||
@@ -1651,18 +1741,6 @@ static BlockDriverState *bdrv_open_inherit(const char *filename,
|
||||
|
||||
/* Open image file without format layer */
|
||||
if ((flags & BDRV_O_PROTOCOL) == 0) {
|
||||
if (flags & BDRV_O_RDWR) {
|
||||
flags |= BDRV_O_ALLOW_RDWR;
|
||||
}
|
||||
if (flags & BDRV_O_SNAPSHOT) {
|
||||
snapshot_options = qdict_new();
|
||||
bdrv_temp_snapshot_options(&snapshot_flags, snapshot_options,
|
||||
flags, options);
|
||||
bdrv_backing_options(&flags, options, flags, options);
|
||||
}
|
||||
|
||||
bs->open_flags = flags;
|
||||
|
||||
file = bdrv_open_child(filename, options, "file", bs,
|
||||
&child_file, true, &local_err);
|
||||
if (local_err) {
|
||||
@@ -1847,6 +1925,13 @@ static BlockReopenQueue *bdrv_reopen_queue_child(BlockReopenQueue *bs_queue,
|
||||
options = qdict_new();
|
||||
}
|
||||
|
||||
/* Check if this BlockDriverState is already in the queue */
|
||||
QSIMPLEQ_FOREACH(bs_entry, bs_queue, entry) {
|
||||
if (bs == bs_entry->state.bs) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Precedence of options:
|
||||
* 1. Explicitly passed in options (highest)
|
||||
@@ -1867,7 +1952,11 @@ static BlockReopenQueue *bdrv_reopen_queue_child(BlockReopenQueue *bs_queue,
|
||||
}
|
||||
|
||||
/* Old explicitly set values (don't overwrite by inherited value) */
|
||||
old_options = qdict_clone_shallow(bs->explicit_options);
|
||||
if (bs_entry) {
|
||||
old_options = qdict_clone_shallow(bs_entry->state.explicit_options);
|
||||
} else {
|
||||
old_options = qdict_clone_shallow(bs->explicit_options);
|
||||
}
|
||||
bdrv_join_options(bs, options, old_options);
|
||||
QDECREF(old_options);
|
||||
|
||||
@@ -1906,8 +1995,13 @@ static BlockReopenQueue *bdrv_reopen_queue_child(BlockReopenQueue *bs_queue,
|
||||
child->role, options, flags);
|
||||
}
|
||||
|
||||
bs_entry = g_new0(BlockReopenQueueEntry, 1);
|
||||
QSIMPLEQ_INSERT_TAIL(bs_queue, bs_entry, entry);
|
||||
if (!bs_entry) {
|
||||
bs_entry = g_new0(BlockReopenQueueEntry, 1);
|
||||
QSIMPLEQ_INSERT_TAIL(bs_queue, bs_entry, entry);
|
||||
} else {
|
||||
QDECREF(bs_entry->state.options);
|
||||
QDECREF(bs_entry->state.explicit_options);
|
||||
}
|
||||
|
||||
bs_entry->state.bs = bs;
|
||||
bs_entry->state.options = options;
|
||||
@@ -2965,11 +3059,6 @@ bool bdrv_debug_is_suspended(BlockDriverState *bs, const char *tag)
|
||||
return false;
|
||||
}
|
||||
|
||||
int bdrv_is_snapshot(BlockDriverState *bs)
|
||||
{
|
||||
return !!(bs->open_flags & BDRV_O_SNAPSHOT);
|
||||
}
|
||||
|
||||
/* backing_file can either be relative, or absolute, or a protocol. If it is
|
||||
* relative, it must be relative to the chain. So, passing in bs->filename
|
||||
* from a BDS as backing_file should not be done, as that may be relative to
|
||||
|
@@ -1,8 +1,8 @@
|
||||
block-obj-y += raw_bsd.o qcow.o vdi.o vmdk.o cloop.o bochs.o vpc.o vvfat.o
|
||||
block-obj-y += raw_bsd.o qcow.o vdi.o vmdk.o cloop.o bochs.o vpc.o vvfat.o dmg.o
|
||||
block-obj-y += qcow2.o qcow2-refcount.o qcow2-cluster.o qcow2-snapshot.o qcow2-cache.o
|
||||
block-obj-y += qed.o qed-gencb.o qed-l2-cache.o qed-table.o qed-cluster.o
|
||||
block-obj-y += qed-check.o
|
||||
block-obj-$(CONFIG_VHDX) += vhdx.o vhdx-endian.o vhdx-log.o
|
||||
block-obj-y += vhdx.o vhdx-endian.o vhdx-log.o
|
||||
block-obj-y += quorum.o
|
||||
block-obj-y += parallels.o blkdebug.o blkverify.o blkreplay.o
|
||||
block-obj-y += block-backend.o snapshot.o qapi.o
|
||||
@@ -29,6 +29,7 @@ block-obj-y += crypto.o
|
||||
|
||||
common-obj-y += stream.o
|
||||
|
||||
nfs.o-libs := $(LIBNFS_LIBS)
|
||||
iscsi.o-cflags := $(LIBISCSI_CFLAGS)
|
||||
iscsi.o-libs := $(LIBISCSI_LIBS)
|
||||
curl.o-cflags := $(CURL_CFLAGS)
|
||||
@@ -40,7 +41,6 @@ gluster.o-libs := $(GLUSTERFS_LIBS)
|
||||
ssh.o-cflags := $(LIBSSH2_CFLAGS)
|
||||
ssh.o-libs := $(LIBSSH2_LIBS)
|
||||
archipelago.o-libs := $(ARCHIPELAGO_LIBS)
|
||||
block-obj-m += dmg.o
|
||||
dmg.o-libs := $(BZIP2_LIBS)
|
||||
qcow.o-libs := -lz
|
||||
linux-aio.o-libs := -laio
|
||||
|
@@ -559,6 +559,25 @@ void *blk_get_attached_dev(BlockBackend *blk)
|
||||
return blk->dev;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the BlockBackend which has the device model @dev attached if it
|
||||
* exists, else null.
|
||||
*
|
||||
* @dev must not be null.
|
||||
*/
|
||||
BlockBackend *blk_by_dev(void *dev)
|
||||
{
|
||||
BlockBackend *blk = NULL;
|
||||
|
||||
assert(dev != NULL);
|
||||
while ((blk = blk_all_next(blk)) != NULL) {
|
||||
if (blk->dev == dev) {
|
||||
return blk;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set @blk's device model callbacks to @ops.
|
||||
* @opaque is the opaque argument to pass to the callbacks.
|
||||
|
@@ -83,7 +83,7 @@ static void commit_complete(BlockJob *job, void *opaque)
|
||||
BlockDriverState *active = s->active;
|
||||
BlockDriverState *top = blk_bs(s->top);
|
||||
BlockDriverState *base = blk_bs(s->base);
|
||||
BlockDriverState *overlay_bs;
|
||||
BlockDriverState *overlay_bs = bdrv_find_overlay(active, top);
|
||||
int ret = data->ret;
|
||||
|
||||
if (!block_job_is_cancelled(&s->common) && ret == 0) {
|
||||
@@ -97,7 +97,6 @@ static void commit_complete(BlockJob *job, void *opaque)
|
||||
if (s->base_flags != bdrv_get_flags(base)) {
|
||||
bdrv_reopen(base, s->base_flags, NULL);
|
||||
}
|
||||
overlay_bs = bdrv_find_overlay(active, top);
|
||||
if (overlay_bs && s->orig_overlay_flags != bdrv_get_flags(overlay_bs)) {
|
||||
bdrv_reopen(overlay_bs, s->orig_overlay_flags, NULL);
|
||||
}
|
||||
@@ -243,14 +242,14 @@ void commit_start(const char *job_id, BlockDriverState *bs,
|
||||
orig_overlay_flags = bdrv_get_flags(overlay_bs);
|
||||
|
||||
/* convert base & overlay_bs to r/w, if necessary */
|
||||
if (!(orig_overlay_flags & BDRV_O_RDWR)) {
|
||||
reopen_queue = bdrv_reopen_queue(reopen_queue, overlay_bs, NULL,
|
||||
orig_overlay_flags | BDRV_O_RDWR);
|
||||
}
|
||||
if (!(orig_base_flags & BDRV_O_RDWR)) {
|
||||
reopen_queue = bdrv_reopen_queue(reopen_queue, base, NULL,
|
||||
orig_base_flags | BDRV_O_RDWR);
|
||||
}
|
||||
if (!(orig_overlay_flags & BDRV_O_RDWR)) {
|
||||
reopen_queue = bdrv_reopen_queue(reopen_queue, overlay_bs, NULL,
|
||||
orig_overlay_flags | BDRV_O_RDWR);
|
||||
}
|
||||
if (reopen_queue) {
|
||||
bdrv_reopen_multiple(reopen_queue, &local_err);
|
||||
if (local_err != NULL) {
|
||||
|
@@ -33,6 +33,7 @@
|
||||
#define BLOCK_CRYPTO_OPT_LUKS_IVGEN_ALG "ivgen-alg"
|
||||
#define BLOCK_CRYPTO_OPT_LUKS_IVGEN_HASH_ALG "ivgen-hash-alg"
|
||||
#define BLOCK_CRYPTO_OPT_LUKS_HASH_ALG "hash-alg"
|
||||
#define BLOCK_CRYPTO_OPT_LUKS_ITER_TIME "iter-time"
|
||||
|
||||
typedef struct BlockCrypto BlockCrypto;
|
||||
|
||||
@@ -183,6 +184,11 @@ static QemuOptsList block_crypto_create_opts_luks = {
|
||||
.type = QEMU_OPT_STRING,
|
||||
.help = "Name of encryption hash algorithm",
|
||||
},
|
||||
{
|
||||
.name = BLOCK_CRYPTO_OPT_LUKS_ITER_TIME,
|
||||
.type = QEMU_OPT_NUMBER,
|
||||
.help = "Time to spend in PBKDF in milliseconds",
|
||||
},
|
||||
{ /* end of list */ }
|
||||
},
|
||||
};
|
||||
|
25
block/curl.c
25
block/curl.c
@@ -675,11 +675,28 @@ static int curl_open(BlockDriverState *bs, QDict *options, int flags,
|
||||
curl_easy_setopt(state->curl, CURLOPT_HEADERDATA, s);
|
||||
if (curl_easy_perform(state->curl))
|
||||
goto out;
|
||||
curl_easy_getinfo(state->curl, CURLINFO_CONTENT_LENGTH_DOWNLOAD, &d);
|
||||
if (d)
|
||||
s->len = (size_t)d;
|
||||
else if(!s->len)
|
||||
if (curl_easy_getinfo(state->curl, CURLINFO_CONTENT_LENGTH_DOWNLOAD, &d)) {
|
||||
goto out;
|
||||
}
|
||||
/* Prior CURL 7.19.4 return value of 0 could mean that the file size is not
|
||||
* know or the size is zero. From 7.19.4 CURL returns -1 if size is not
|
||||
* known and zero if it is realy zero-length file. */
|
||||
#if LIBCURL_VERSION_NUM >= 0x071304
|
||||
if (d < 0) {
|
||||
pstrcpy(state->errmsg, CURL_ERROR_SIZE,
|
||||
"Server didn't report file size.");
|
||||
goto out;
|
||||
}
|
||||
#else
|
||||
if (d <= 0) {
|
||||
pstrcpy(state->errmsg, CURL_ERROR_SIZE,
|
||||
"Unknown file size or zero-length file.");
|
||||
goto out;
|
||||
}
|
||||
#endif
|
||||
|
||||
s->len = (size_t)d;
|
||||
|
||||
if ((!strncasecmp(s->url, "http://", strlen("http://"))
|
||||
|| !strncasecmp(s->url, "https://", strlen("https://")))
|
||||
&& !s->accept_range) {
|
||||
|
@@ -36,7 +36,7 @@
|
||||
#include "block/block_int.h"
|
||||
#include "block/scsi.h"
|
||||
#include "qemu/iov.h"
|
||||
#include "sysemu/sysemu.h"
|
||||
#include "qemu/uuid.h"
|
||||
#include "qmp-commands.h"
|
||||
#include "qapi/qmp/qstring.h"
|
||||
#include "crypto/secret.h"
|
||||
@@ -1813,19 +1813,22 @@ static void iscsi_refresh_limits(BlockDriverState *bs, Error **errp)
|
||||
|
||||
IscsiLun *iscsilun = bs->opaque;
|
||||
uint64_t max_xfer_len = iscsilun->use_16_for_rw ? 0xffffffff : 0xffff;
|
||||
unsigned int block_size = MAX(BDRV_SECTOR_SIZE, iscsilun->block_size);
|
||||
|
||||
bs->bl.request_alignment = iscsilun->block_size;
|
||||
assert(iscsilun->block_size >= BDRV_SECTOR_SIZE || bs->sg);
|
||||
|
||||
bs->bl.request_alignment = block_size;
|
||||
|
||||
if (iscsilun->bl.max_xfer_len) {
|
||||
max_xfer_len = MIN(max_xfer_len, iscsilun->bl.max_xfer_len);
|
||||
}
|
||||
|
||||
if (max_xfer_len * iscsilun->block_size < INT_MAX) {
|
||||
if (max_xfer_len * block_size < INT_MAX) {
|
||||
bs->bl.max_transfer = max_xfer_len * iscsilun->block_size;
|
||||
}
|
||||
|
||||
if (iscsilun->lbp.lbpu) {
|
||||
if (iscsilun->bl.max_unmap < 0xffffffff / iscsilun->block_size) {
|
||||
if (iscsilun->bl.max_unmap < 0xffffffff / block_size) {
|
||||
bs->bl.max_pdiscard =
|
||||
iscsilun->bl.max_unmap * iscsilun->block_size;
|
||||
}
|
||||
@@ -1835,7 +1838,7 @@ static void iscsi_refresh_limits(BlockDriverState *bs, Error **errp)
|
||||
bs->bl.pdiscard_alignment = iscsilun->block_size;
|
||||
}
|
||||
|
||||
if (iscsilun->bl.max_ws_len < 0xffffffff / iscsilun->block_size) {
|
||||
if (iscsilun->bl.max_ws_len < 0xffffffff / block_size) {
|
||||
bs->bl.max_pwrite_zeroes =
|
||||
iscsilun->bl.max_ws_len * iscsilun->block_size;
|
||||
}
|
||||
@@ -1846,7 +1849,7 @@ static void iscsi_refresh_limits(BlockDriverState *bs, Error **errp)
|
||||
bs->bl.pwrite_zeroes_alignment = iscsilun->block_size;
|
||||
}
|
||||
if (iscsilun->bl.opt_xfer_len &&
|
||||
iscsilun->bl.opt_xfer_len < INT_MAX / iscsilun->block_size) {
|
||||
iscsilun->bl.opt_xfer_len < INT_MAX / block_size) {
|
||||
bs->bl.opt_transfer = pow2floor(iscsilun->bl.opt_xfer_len *
|
||||
iscsilun->block_size);
|
||||
}
|
||||
@@ -2010,45 +2013,9 @@ static BlockDriver bdrv_iscsi = {
|
||||
.bdrv_attach_aio_context = iscsi_attach_aio_context,
|
||||
};
|
||||
|
||||
static QemuOptsList qemu_iscsi_opts = {
|
||||
.name = "iscsi",
|
||||
.head = QTAILQ_HEAD_INITIALIZER(qemu_iscsi_opts.head),
|
||||
.desc = {
|
||||
{
|
||||
.name = "user",
|
||||
.type = QEMU_OPT_STRING,
|
||||
.help = "username for CHAP authentication to target",
|
||||
},{
|
||||
.name = "password",
|
||||
.type = QEMU_OPT_STRING,
|
||||
.help = "password for CHAP authentication to target",
|
||||
},{
|
||||
.name = "password-secret",
|
||||
.type = QEMU_OPT_STRING,
|
||||
.help = "ID of the secret providing password for CHAP "
|
||||
"authentication to target",
|
||||
},{
|
||||
.name = "header-digest",
|
||||
.type = QEMU_OPT_STRING,
|
||||
.help = "HeaderDigest setting. "
|
||||
"{CRC32C|CRC32C-NONE|NONE-CRC32C|NONE}",
|
||||
},{
|
||||
.name = "initiator-name",
|
||||
.type = QEMU_OPT_STRING,
|
||||
.help = "Initiator iqn name to use when connecting",
|
||||
},{
|
||||
.name = "timeout",
|
||||
.type = QEMU_OPT_NUMBER,
|
||||
.help = "Request timeout in seconds (default 0 = no timeout)",
|
||||
},
|
||||
{ /* end of list */ }
|
||||
},
|
||||
};
|
||||
|
||||
static void iscsi_block_init(void)
|
||||
{
|
||||
bdrv_register(&bdrv_iscsi);
|
||||
qemu_add_opts(&qemu_iscsi_opts);
|
||||
}
|
||||
|
||||
block_init(iscsi_block_init);
|
||||
|
@@ -429,7 +429,7 @@ static int coroutine_fn do_perform_cow(BlockDriverState *bs,
|
||||
|
||||
if (bs->encrypted) {
|
||||
Error *err = NULL;
|
||||
int64_t sector = (cluster_offset + offset_in_cluster)
|
||||
int64_t sector = (src_cluster_offset + offset_in_cluster)
|
||||
>> BDRV_SECTOR_BITS;
|
||||
assert(s->cipher);
|
||||
assert((offset_in_cluster & ~BDRV_SECTOR_MASK) == 0);
|
||||
|
@@ -530,7 +530,6 @@ int qcow2_change_refcount_order(BlockDriverState *bs, int refcount_order,
|
||||
int qcow2_grow_l1_table(BlockDriverState *bs, uint64_t min_size,
|
||||
bool exact_size);
|
||||
int qcow2_write_l1_entry(BlockDriverState *bs, int l1_index);
|
||||
void qcow2_l2_cache_reset(BlockDriverState *bs);
|
||||
int qcow2_decompress_cluster(BlockDriverState *bs, uint64_t cluster_offset);
|
||||
int qcow2_encrypt_sectors(BDRVQcow2State *s, int64_t sector_num,
|
||||
uint8_t *out_buf, const uint8_t *in_buf,
|
||||
|
@@ -1049,7 +1049,7 @@ static int parse_vdiname(BDRVSheepdogState *s, const char *filename,
|
||||
const char *host_spec, *vdi_spec;
|
||||
int nr_sep, ret;
|
||||
|
||||
strstart(filename, "sheepdog:", (const char **)&filename);
|
||||
strstart(filename, "sheepdog:", &filename);
|
||||
p = q = g_strdup(filename);
|
||||
|
||||
/* count the number of separators */
|
||||
@@ -2652,7 +2652,7 @@ static int sd_snapshot_list(BlockDriverState *bs, QEMUSnapshotInfo **psn_tab)
|
||||
req.opcode = SD_OP_READ_VDIS;
|
||||
req.data_length = max;
|
||||
|
||||
ret = do_req(fd, s->aio_context, (SheepdogReq *)&req,
|
||||
ret = do_req(fd, s->aio_context, &req,
|
||||
vdi_inuse, &wlen, &rlen);
|
||||
|
||||
closesocket(fd);
|
||||
|
73
block/vdi.c
73
block/vdi.c
@@ -58,14 +58,7 @@
|
||||
#include "migration/migration.h"
|
||||
#include "qemu/coroutine.h"
|
||||
#include "qemu/cutils.h"
|
||||
|
||||
#if defined(CONFIG_UUID)
|
||||
#include <uuid/uuid.h>
|
||||
#else
|
||||
/* TODO: move uuid emulation to some central place in QEMU. */
|
||||
#include "sysemu/sysemu.h" /* UUID_FMT */
|
||||
typedef unsigned char uuid_t[16];
|
||||
#endif
|
||||
#include "qemu/uuid.h"
|
||||
|
||||
/* Code configuration options. */
|
||||
|
||||
@@ -140,28 +133,6 @@ typedef unsigned char uuid_t[16];
|
||||
#define VDI_DISK_SIZE_MAX ((uint64_t)VDI_BLOCKS_IN_IMAGE_MAX * \
|
||||
(uint64_t)DEFAULT_CLUSTER_SIZE)
|
||||
|
||||
#if !defined(CONFIG_UUID)
|
||||
static inline void uuid_generate(uuid_t out)
|
||||
{
|
||||
memset(out, 0, sizeof(uuid_t));
|
||||
}
|
||||
|
||||
static inline int uuid_is_null(const uuid_t uu)
|
||||
{
|
||||
uuid_t null_uuid = { 0 };
|
||||
return memcmp(uu, null_uuid, sizeof(uuid_t)) == 0;
|
||||
}
|
||||
|
||||
# if defined(CONFIG_VDI_DEBUG)
|
||||
static inline void uuid_unparse(const uuid_t uu, char *out)
|
||||
{
|
||||
snprintf(out, 37, UUID_FMT,
|
||||
uu[0], uu[1], uu[2], uu[3], uu[4], uu[5], uu[6], uu[7],
|
||||
uu[8], uu[9], uu[10], uu[11], uu[12], uu[13], uu[14], uu[15]);
|
||||
}
|
||||
# endif
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
char text[0x40];
|
||||
uint32_t signature;
|
||||
@@ -182,10 +153,10 @@ typedef struct {
|
||||
uint32_t block_extra; /* unused here */
|
||||
uint32_t blocks_in_image;
|
||||
uint32_t blocks_allocated;
|
||||
uuid_t uuid_image;
|
||||
uuid_t uuid_last_snap;
|
||||
uuid_t uuid_link;
|
||||
uuid_t uuid_parent;
|
||||
QemuUUID uuid_image;
|
||||
QemuUUID uuid_last_snap;
|
||||
QemuUUID uuid_link;
|
||||
QemuUUID uuid_parent;
|
||||
uint64_t unused2[7];
|
||||
} QEMU_PACKED VdiHeader;
|
||||
|
||||
@@ -206,16 +177,6 @@ typedef struct {
|
||||
Error *migration_blocker;
|
||||
} BDRVVdiState;
|
||||
|
||||
/* Change UUID from little endian (IPRT = VirtualBox format) to big endian
|
||||
* format (network byte order, standard, see RFC 4122) and vice versa.
|
||||
*/
|
||||
static void uuid_convert(uuid_t uuid)
|
||||
{
|
||||
bswap32s((uint32_t *)&uuid[0]);
|
||||
bswap16s((uint16_t *)&uuid[4]);
|
||||
bswap16s((uint16_t *)&uuid[6]);
|
||||
}
|
||||
|
||||
static void vdi_header_to_cpu(VdiHeader *header)
|
||||
{
|
||||
le32_to_cpus(&header->signature);
|
||||
@@ -234,10 +195,10 @@ static void vdi_header_to_cpu(VdiHeader *header)
|
||||
le32_to_cpus(&header->block_extra);
|
||||
le32_to_cpus(&header->blocks_in_image);
|
||||
le32_to_cpus(&header->blocks_allocated);
|
||||
uuid_convert(header->uuid_image);
|
||||
uuid_convert(header->uuid_last_snap);
|
||||
uuid_convert(header->uuid_link);
|
||||
uuid_convert(header->uuid_parent);
|
||||
qemu_uuid_bswap(&header->uuid_image);
|
||||
qemu_uuid_bswap(&header->uuid_last_snap);
|
||||
qemu_uuid_bswap(&header->uuid_link);
|
||||
qemu_uuid_bswap(&header->uuid_parent);
|
||||
}
|
||||
|
||||
static void vdi_header_to_le(VdiHeader *header)
|
||||
@@ -258,10 +219,10 @@ static void vdi_header_to_le(VdiHeader *header)
|
||||
cpu_to_le32s(&header->block_extra);
|
||||
cpu_to_le32s(&header->blocks_in_image);
|
||||
cpu_to_le32s(&header->blocks_allocated);
|
||||
uuid_convert(header->uuid_image);
|
||||
uuid_convert(header->uuid_last_snap);
|
||||
uuid_convert(header->uuid_link);
|
||||
uuid_convert(header->uuid_parent);
|
||||
qemu_uuid_bswap(&header->uuid_image);
|
||||
qemu_uuid_bswap(&header->uuid_last_snap);
|
||||
qemu_uuid_bswap(&header->uuid_link);
|
||||
qemu_uuid_bswap(&header->uuid_parent);
|
||||
}
|
||||
|
||||
#if defined(CONFIG_VDI_DEBUG)
|
||||
@@ -469,11 +430,11 @@ static int vdi_open(BlockDriverState *bs, QDict *options, int flags,
|
||||
(uint64_t)header.blocks_in_image * header.block_size);
|
||||
ret = -ENOTSUP;
|
||||
goto fail;
|
||||
} else if (!uuid_is_null(header.uuid_link)) {
|
||||
} else if (!qemu_uuid_is_null(&header.uuid_link)) {
|
||||
error_setg(errp, "unsupported VDI image (non-NULL link UUID)");
|
||||
ret = -ENOTSUP;
|
||||
goto fail;
|
||||
} else if (!uuid_is_null(header.uuid_parent)) {
|
||||
} else if (!qemu_uuid_is_null(&header.uuid_parent)) {
|
||||
error_setg(errp, "unsupported VDI image (non-NULL parent UUID)");
|
||||
ret = -ENOTSUP;
|
||||
goto fail;
|
||||
@@ -821,8 +782,8 @@ static int vdi_create(const char *filename, QemuOpts *opts, Error **errp)
|
||||
if (image_type == VDI_TYPE_STATIC) {
|
||||
header.blocks_allocated = blocks;
|
||||
}
|
||||
uuid_generate(header.uuid_image);
|
||||
uuid_generate(header.uuid_last_snap);
|
||||
qemu_uuid_generate(&header.uuid_image);
|
||||
qemu_uuid_generate(&header.uuid_last_snap);
|
||||
/* There is no need to set header.uuid_link or header.uuid_parent here. */
|
||||
#if defined(CONFIG_VDI_DEBUG)
|
||||
vdi_header_print(&header);
|
||||
|
@@ -21,9 +21,6 @@
|
||||
#include "qemu/bswap.h"
|
||||
#include "block/vhdx.h"
|
||||
|
||||
#include <uuid/uuid.h>
|
||||
|
||||
|
||||
/*
|
||||
* All the VHDX formats on disk are little endian - the following
|
||||
* are helper import/export functions to correctly convert
|
||||
|
@@ -25,8 +25,7 @@
|
||||
#include "qemu/bswap.h"
|
||||
#include "block/vhdx.h"
|
||||
#include "migration/migration.h"
|
||||
|
||||
#include <uuid/uuid.h>
|
||||
#include "qemu/uuid.h"
|
||||
|
||||
/* Options for VHDX creation */
|
||||
|
||||
@@ -213,11 +212,11 @@ bool vhdx_checksum_is_valid(uint8_t *buf, size_t size, int crc_offset)
|
||||
*/
|
||||
void vhdx_guid_generate(MSGUID *guid)
|
||||
{
|
||||
uuid_t uuid;
|
||||
QemuUUID uuid;
|
||||
assert(guid != NULL);
|
||||
|
||||
uuid_generate(uuid);
|
||||
memcpy(guid, uuid, sizeof(MSGUID));
|
||||
qemu_uuid_generate(&uuid);
|
||||
memcpy(guid, &uuid, sizeof(MSGUID));
|
||||
}
|
||||
|
||||
/* Check for region overlaps inside the VHDX image */
|
||||
|
10
block/vpc.c
10
block/vpc.c
@@ -30,9 +30,7 @@
|
||||
#include "qemu/module.h"
|
||||
#include "migration/migration.h"
|
||||
#include "qemu/bswap.h"
|
||||
#if defined(CONFIG_UUID)
|
||||
#include <uuid/uuid.h>
|
||||
#endif
|
||||
#include "qemu/uuid.h"
|
||||
|
||||
/**************************************************************/
|
||||
|
||||
@@ -89,7 +87,7 @@ typedef struct vhd_footer {
|
||||
uint32_t checksum;
|
||||
|
||||
/* UUID used to identify a parent hard disk (backing file) */
|
||||
uint8_t uuid[16];
|
||||
QemuUUID uuid;
|
||||
|
||||
uint8_t in_saved_state;
|
||||
} QEMU_PACKED VHDFooter;
|
||||
@@ -980,9 +978,7 @@ static int vpc_create(const char *filename, QemuOpts *opts, Error **errp)
|
||||
|
||||
footer->type = cpu_to_be32(disk_type);
|
||||
|
||||
#if defined(CONFIG_UUID)
|
||||
uuid_generate(footer->uuid);
|
||||
#endif
|
||||
qemu_uuid_generate(&footer->uuid);
|
||||
|
||||
footer->checksum = cpu_to_be32(vpc_checksum(buf, HEADER_SIZE));
|
||||
|
||||
|
@@ -2971,7 +2971,8 @@ static BlockDriver vvfat_write_target = {
|
||||
static void vvfat_qcow_options(int *child_flags, QDict *child_options,
|
||||
int parent_flags, QDict *parent_options)
|
||||
{
|
||||
*child_flags = BDRV_O_RDWR | BDRV_O_NO_FLUSH;
|
||||
qdict_set_default_str(child_options, BDRV_OPT_READ_ONLY, "off");
|
||||
*child_flags = BDRV_O_NO_FLUSH;
|
||||
}
|
||||
|
||||
static const BdrvChildRole child_vvfat_qcow = {
|
||||
|
313
blockdev.c
313
blockdev.c
@@ -56,7 +56,8 @@
|
||||
static QTAILQ_HEAD(, BlockDriverState) monitor_bdrv_states =
|
||||
QTAILQ_HEAD_INITIALIZER(monitor_bdrv_states);
|
||||
|
||||
static int do_open_tray(const char *device, bool force, Error **errp);
|
||||
static int do_open_tray(const char *blk_name, const char *qdev_id,
|
||||
bool force, Error **errp);
|
||||
|
||||
static const char *const if_name[IF_COUNT] = {
|
||||
[IF_NONE] = "none",
|
||||
@@ -360,9 +361,6 @@ static void extract_common_blockdev_options(QemuOpts *opts, int *bdrv_flags,
|
||||
const char *aio;
|
||||
|
||||
if (bdrv_flags) {
|
||||
if (!qemu_opt_get_bool(opts, "read-only", false)) {
|
||||
*bdrv_flags |= BDRV_O_RDWR;
|
||||
}
|
||||
if (qemu_opt_get_bool(opts, "copy-on-read", false)) {
|
||||
*bdrv_flags |= BDRV_O_COPY_ON_READ;
|
||||
}
|
||||
@@ -471,7 +469,7 @@ static BlockBackend *blockdev_init(const char *file, QDict *bs_opts,
|
||||
int bdrv_flags = 0;
|
||||
int on_read_error, on_write_error;
|
||||
bool account_invalid, account_failed;
|
||||
bool writethrough;
|
||||
bool writethrough, read_only;
|
||||
BlockBackend *blk;
|
||||
BlockDriverState *bs;
|
||||
ThrottleConfig cfg;
|
||||
@@ -567,6 +565,8 @@ static BlockBackend *blockdev_init(const char *file, QDict *bs_opts,
|
||||
bdrv_flags |= BDRV_O_SNAPSHOT;
|
||||
}
|
||||
|
||||
read_only = qemu_opt_get_bool(opts, BDRV_OPT_READ_ONLY, false);
|
||||
|
||||
/* init */
|
||||
if ((!file || !*file) && !qdict_size(bs_opts)) {
|
||||
BlockBackendRootState *blk_rs;
|
||||
@@ -574,7 +574,7 @@ static BlockBackend *blockdev_init(const char *file, QDict *bs_opts,
|
||||
blk = blk_new();
|
||||
blk_rs = blk_get_root_state(blk);
|
||||
blk_rs->open_flags = bdrv_flags;
|
||||
blk_rs->read_only = !(bdrv_flags & BDRV_O_RDWR);
|
||||
blk_rs->read_only = read_only;
|
||||
blk_rs->detect_zeroes = detect_zeroes;
|
||||
|
||||
QDECREF(bs_opts);
|
||||
@@ -588,6 +588,8 @@ static BlockBackend *blockdev_init(const char *file, QDict *bs_opts,
|
||||
* Apply the defaults here instead. */
|
||||
qdict_set_default_str(bs_opts, BDRV_OPT_CACHE_DIRECT, "off");
|
||||
qdict_set_default_str(bs_opts, BDRV_OPT_CACHE_NO_FLUSH, "off");
|
||||
qdict_set_default_str(bs_opts, BDRV_OPT_READ_ONLY,
|
||||
read_only ? "on" : "off");
|
||||
assert((bdrv_flags & BDRV_O_CACHE_MASK) == 0);
|
||||
|
||||
if (runstate_check(RUN_STATE_INMIGRATE)) {
|
||||
@@ -682,6 +684,7 @@ static BlockDriverState *bds_tree_init(QDict *bs_opts, Error **errp)
|
||||
* Apply the defaults here instead. */
|
||||
qdict_set_default_str(bs_opts, BDRV_OPT_CACHE_DIRECT, "off");
|
||||
qdict_set_default_str(bs_opts, BDRV_OPT_CACHE_NO_FLUSH, "off");
|
||||
qdict_set_default_str(bs_opts, BDRV_OPT_READ_ONLY, "off");
|
||||
|
||||
if (runstate_check(RUN_STATE_INMIGRATE)) {
|
||||
bdrv_flags |= BDRV_O_INACTIVE;
|
||||
@@ -805,7 +808,7 @@ QemuOptsList qemu_legacy_drive_opts = {
|
||||
|
||||
/* Options that are passed on, but have special semantics with -drive */
|
||||
{
|
||||
.name = "read-only",
|
||||
.name = BDRV_OPT_READ_ONLY,
|
||||
.type = QEMU_OPT_BOOL,
|
||||
.help = "open drive file as read-only",
|
||||
},{
|
||||
@@ -871,7 +874,7 @@ DriveInfo *drive_new(QemuOpts *all_opts, BlockInterfaceType block_default_type)
|
||||
|
||||
{ "group", "throttling.group" },
|
||||
|
||||
{ "readonly", "read-only" },
|
||||
{ "readonly", BDRV_OPT_READ_ONLY },
|
||||
};
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(opt_renames); i++) {
|
||||
@@ -943,7 +946,7 @@ DriveInfo *drive_new(QemuOpts *all_opts, BlockInterfaceType block_default_type)
|
||||
}
|
||||
|
||||
/* copy-on-read is disabled with a warning for read-only devices */
|
||||
read_only |= qemu_opt_get_bool(legacy_opts, "read-only", false);
|
||||
read_only |= qemu_opt_get_bool(legacy_opts, BDRV_OPT_READ_ONLY, false);
|
||||
copy_on_read = qemu_opt_get_bool(legacy_opts, "copy-on-read", false);
|
||||
|
||||
if (read_only && copy_on_read) {
|
||||
@@ -951,7 +954,7 @@ DriveInfo *drive_new(QemuOpts *all_opts, BlockInterfaceType block_default_type)
|
||||
copy_on_read = false;
|
||||
}
|
||||
|
||||
qdict_put(bs_opts, "read-only",
|
||||
qdict_put(bs_opts, BDRV_OPT_READ_ONLY,
|
||||
qstring_from_str(read_only ? "on" : "off"));
|
||||
qdict_put(bs_opts, "copy-on-read",
|
||||
qstring_from_str(copy_on_read ? "on" :"off"));
|
||||
@@ -1196,6 +1199,29 @@ static BlockDriverState *qmp_get_root_bs(const char *name, Error **errp)
|
||||
return bs;
|
||||
}
|
||||
|
||||
static BlockBackend *qmp_get_blk(const char *blk_name, const char *qdev_id,
|
||||
Error **errp)
|
||||
{
|
||||
BlockBackend *blk;
|
||||
|
||||
if (!blk_name == !qdev_id) {
|
||||
error_setg(errp, "Need exactly one of 'device' and 'id'");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (qdev_id) {
|
||||
blk = blk_by_qdev_id(qdev_id, errp);
|
||||
} else {
|
||||
blk = blk_by_name(blk_name);
|
||||
if (blk == NULL) {
|
||||
error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND,
|
||||
"Device '%s' not found", blk_name);
|
||||
}
|
||||
}
|
||||
|
||||
return blk;
|
||||
}
|
||||
|
||||
void hmp_commit(Monitor *mon, const QDict *qdict)
|
||||
{
|
||||
const char *device = qdict_get_str(qdict, "device");
|
||||
@@ -1777,8 +1803,7 @@ static void external_snapshot_prepare(BlkActionState *common,
|
||||
}
|
||||
|
||||
if (bdrv_has_blk(state->new_bs)) {
|
||||
error_setg(errp, "The snapshot is already in use by %s",
|
||||
bdrv_get_parent_name(state->new_bs));
|
||||
error_setg(errp, "The snapshot is already in use");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -2239,7 +2264,9 @@ exit:
|
||||
block_job_txn_unref(block_job_txn);
|
||||
}
|
||||
|
||||
void qmp_eject(const char *device, bool has_force, bool force, Error **errp)
|
||||
void qmp_eject(bool has_device, const char *device,
|
||||
bool has_id, const char *id,
|
||||
bool has_force, bool force, Error **errp)
|
||||
{
|
||||
Error *local_err = NULL;
|
||||
int rc;
|
||||
@@ -2248,14 +2275,16 @@ void qmp_eject(const char *device, bool has_force, bool force, Error **errp)
|
||||
force = false;
|
||||
}
|
||||
|
||||
rc = do_open_tray(device, force, &local_err);
|
||||
rc = do_open_tray(has_device ? device : NULL,
|
||||
has_id ? id : NULL,
|
||||
force, &local_err);
|
||||
if (rc && rc != -ENOSYS) {
|
||||
error_propagate(errp, local_err);
|
||||
return;
|
||||
}
|
||||
error_free(local_err);
|
||||
|
||||
qmp_x_blockdev_remove_medium(device, errp);
|
||||
qmp_x_blockdev_remove_medium(has_device, device, has_id, id, errp);
|
||||
}
|
||||
|
||||
void qmp_block_passwd(bool has_device, const char *device,
|
||||
@@ -2293,15 +2322,15 @@ void qmp_block_passwd(bool has_device, const char *device,
|
||||
* If the guest was asked to open the tray, return -EINPROGRESS.
|
||||
* Else, return 0.
|
||||
*/
|
||||
static int do_open_tray(const char *device, bool force, Error **errp)
|
||||
static int do_open_tray(const char *blk_name, const char *qdev_id,
|
||||
bool force, Error **errp)
|
||||
{
|
||||
BlockBackend *blk;
|
||||
const char *device = qdev_id ?: blk_name;
|
||||
bool locked;
|
||||
|
||||
blk = blk_by_name(device);
|
||||
blk = qmp_get_blk(blk_name, qdev_id, errp);
|
||||
if (!blk) {
|
||||
error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND,
|
||||
"Device '%s' not found", device);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
@@ -2337,7 +2366,9 @@ static int do_open_tray(const char *device, bool force, Error **errp)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void qmp_blockdev_open_tray(const char *device, bool has_force, bool force,
|
||||
void qmp_blockdev_open_tray(bool has_device, const char *device,
|
||||
bool has_id, const char *id,
|
||||
bool has_force, bool force,
|
||||
Error **errp)
|
||||
{
|
||||
Error *local_err = NULL;
|
||||
@@ -2346,7 +2377,9 @@ void qmp_blockdev_open_tray(const char *device, bool has_force, bool force,
|
||||
if (!has_force) {
|
||||
force = false;
|
||||
}
|
||||
rc = do_open_tray(device, force, &local_err);
|
||||
rc = do_open_tray(has_device ? device : NULL,
|
||||
has_id ? id : NULL,
|
||||
force, &local_err);
|
||||
if (rc && rc != -ENOSYS && rc != -EINPROGRESS) {
|
||||
error_propagate(errp, local_err);
|
||||
return;
|
||||
@@ -2354,19 +2387,22 @@ void qmp_blockdev_open_tray(const char *device, bool has_force, bool force,
|
||||
error_free(local_err);
|
||||
}
|
||||
|
||||
void qmp_blockdev_close_tray(const char *device, Error **errp)
|
||||
void qmp_blockdev_close_tray(bool has_device, const char *device,
|
||||
bool has_id, const char *id,
|
||||
Error **errp)
|
||||
{
|
||||
BlockBackend *blk;
|
||||
|
||||
blk = blk_by_name(device);
|
||||
device = has_device ? device : NULL;
|
||||
id = has_id ? id : NULL;
|
||||
|
||||
blk = qmp_get_blk(device, id, errp);
|
||||
if (!blk) {
|
||||
error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND,
|
||||
"Device '%s' not found", device);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!blk_dev_has_removable_media(blk)) {
|
||||
error_setg(errp, "Device '%s' is not removable", device);
|
||||
error_setg(errp, "Device '%s' is not removable", device ?: id);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -2382,30 +2418,34 @@ void qmp_blockdev_close_tray(const char *device, Error **errp)
|
||||
blk_dev_change_media_cb(blk, true);
|
||||
}
|
||||
|
||||
void qmp_x_blockdev_remove_medium(const char *device, Error **errp)
|
||||
void qmp_x_blockdev_remove_medium(bool has_device, const char *device,
|
||||
bool has_id, const char *id, Error **errp)
|
||||
{
|
||||
BlockBackend *blk;
|
||||
BlockDriverState *bs;
|
||||
AioContext *aio_context;
|
||||
bool has_device;
|
||||
bool has_attached_device;
|
||||
|
||||
blk = blk_by_name(device);
|
||||
device = has_device ? device : NULL;
|
||||
id = has_id ? id : NULL;
|
||||
|
||||
blk = qmp_get_blk(device, id, errp);
|
||||
if (!blk) {
|
||||
error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND,
|
||||
"Device '%s' not found", device);
|
||||
return;
|
||||
}
|
||||
|
||||
/* For BBs without a device, we can exchange the BDS tree at will */
|
||||
has_device = blk_get_attached_dev(blk);
|
||||
has_attached_device = blk_get_attached_dev(blk);
|
||||
|
||||
if (has_device && !blk_dev_has_removable_media(blk)) {
|
||||
error_setg(errp, "Device '%s' is not removable", device);
|
||||
if (has_attached_device && !blk_dev_has_removable_media(blk)) {
|
||||
error_setg(errp, "Device '%s' is not removable", device ?: id);
|
||||
return;
|
||||
}
|
||||
|
||||
if (has_device && blk_dev_has_tray(blk) && !blk_dev_is_tray_open(blk)) {
|
||||
error_setg(errp, "Tray of device '%s' is not open", device);
|
||||
if (has_attached_device && blk_dev_has_tray(blk) &&
|
||||
!blk_dev_is_tray_open(blk))
|
||||
{
|
||||
error_setg(errp, "Tray of device '%s' is not open", device ?: id);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -2435,34 +2475,26 @@ out:
|
||||
aio_context_release(aio_context);
|
||||
}
|
||||
|
||||
static void qmp_blockdev_insert_anon_medium(const char *device,
|
||||
static void qmp_blockdev_insert_anon_medium(BlockBackend *blk,
|
||||
BlockDriverState *bs, Error **errp)
|
||||
{
|
||||
BlockBackend *blk;
|
||||
bool has_device;
|
||||
|
||||
blk = blk_by_name(device);
|
||||
if (!blk) {
|
||||
error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND,
|
||||
"Device '%s' not found", device);
|
||||
return;
|
||||
}
|
||||
|
||||
/* For BBs without a device, we can exchange the BDS tree at will */
|
||||
has_device = blk_get_attached_dev(blk);
|
||||
|
||||
if (has_device && !blk_dev_has_removable_media(blk)) {
|
||||
error_setg(errp, "Device '%s' is not removable", device);
|
||||
error_setg(errp, "Device is not removable");
|
||||
return;
|
||||
}
|
||||
|
||||
if (has_device && blk_dev_has_tray(blk) && !blk_dev_is_tray_open(blk)) {
|
||||
error_setg(errp, "Tray of device '%s' is not open", device);
|
||||
error_setg(errp, "Tray of the device is not open");
|
||||
return;
|
||||
}
|
||||
|
||||
if (blk_bs(blk)) {
|
||||
error_setg(errp, "There already is a medium in device '%s'", device);
|
||||
error_setg(errp, "There already is a medium in the device");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -2478,11 +2510,20 @@ static void qmp_blockdev_insert_anon_medium(const char *device,
|
||||
}
|
||||
}
|
||||
|
||||
void qmp_x_blockdev_insert_medium(const char *device, const char *node_name,
|
||||
Error **errp)
|
||||
void qmp_x_blockdev_insert_medium(bool has_device, const char *device,
|
||||
bool has_id, const char *id,
|
||||
const char *node_name, Error **errp)
|
||||
{
|
||||
BlockBackend *blk;
|
||||
BlockDriverState *bs;
|
||||
|
||||
blk = qmp_get_blk(has_device ? device : NULL,
|
||||
has_id ? id : NULL,
|
||||
errp);
|
||||
if (!blk) {
|
||||
return;
|
||||
}
|
||||
|
||||
bs = bdrv_find_node(node_name);
|
||||
if (!bs) {
|
||||
error_setg(errp, "Node '%s' not found", node_name);
|
||||
@@ -2490,15 +2531,16 @@ void qmp_x_blockdev_insert_medium(const char *device, const char *node_name,
|
||||
}
|
||||
|
||||
if (bdrv_has_blk(bs)) {
|
||||
error_setg(errp, "Node '%s' is already in use by '%s'", node_name,
|
||||
bdrv_get_parent_name(bs));
|
||||
error_setg(errp, "Node '%s' is already in use", node_name);
|
||||
return;
|
||||
}
|
||||
|
||||
qmp_blockdev_insert_anon_medium(device, bs, errp);
|
||||
qmp_blockdev_insert_anon_medium(blk, bs, errp);
|
||||
}
|
||||
|
||||
void qmp_blockdev_change_medium(const char *device, const char *filename,
|
||||
void qmp_blockdev_change_medium(bool has_device, const char *device,
|
||||
bool has_id, const char *id,
|
||||
const char *filename,
|
||||
bool has_format, const char *format,
|
||||
bool has_read_only,
|
||||
BlockdevChangeReadOnlyMode read_only,
|
||||
@@ -2511,10 +2553,10 @@ void qmp_blockdev_change_medium(const char *device, const char *filename,
|
||||
QDict *options = NULL;
|
||||
Error *err = NULL;
|
||||
|
||||
blk = blk_by_name(device);
|
||||
blk = qmp_get_blk(has_device ? device : NULL,
|
||||
has_id ? id : NULL,
|
||||
errp);
|
||||
if (!blk) {
|
||||
error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND,
|
||||
"Device '%s' not found", device);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
@@ -2562,7 +2604,9 @@ void qmp_blockdev_change_medium(const char *device, const char *filename,
|
||||
goto fail;
|
||||
}
|
||||
|
||||
rc = do_open_tray(device, false, &err);
|
||||
rc = do_open_tray(has_device ? device : NULL,
|
||||
has_id ? id : NULL,
|
||||
false, &err);
|
||||
if (rc && rc != -ENOSYS) {
|
||||
error_propagate(errp, err);
|
||||
goto fail;
|
||||
@@ -2570,13 +2614,13 @@ void qmp_blockdev_change_medium(const char *device, const char *filename,
|
||||
error_free(err);
|
||||
err = NULL;
|
||||
|
||||
qmp_x_blockdev_remove_medium(device, &err);
|
||||
qmp_x_blockdev_remove_medium(has_device, device, has_id, id, errp);
|
||||
if (err) {
|
||||
error_propagate(errp, err);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
qmp_blockdev_insert_anon_medium(device, medium_bs, &err);
|
||||
qmp_blockdev_insert_anon_medium(blk, medium_bs, &err);
|
||||
if (err) {
|
||||
error_propagate(errp, err);
|
||||
goto fail;
|
||||
@@ -2584,7 +2628,7 @@ void qmp_blockdev_change_medium(const char *device, const char *filename,
|
||||
|
||||
blk_apply_root_state(blk, medium_bs);
|
||||
|
||||
qmp_blockdev_close_tray(device, errp);
|
||||
qmp_blockdev_close_tray(has_device, device, has_id, id, errp);
|
||||
|
||||
fail:
|
||||
/* If the medium has been inserted, the device has its own reference, so
|
||||
@@ -2601,10 +2645,10 @@ void qmp_block_set_io_throttle(BlockIOThrottle *arg, Error **errp)
|
||||
BlockBackend *blk;
|
||||
AioContext *aio_context;
|
||||
|
||||
blk = blk_by_name(arg->device);
|
||||
blk = qmp_get_blk(arg->has_device ? arg->device : NULL,
|
||||
arg->has_id ? arg->id : NULL,
|
||||
errp);
|
||||
if (!blk) {
|
||||
error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND,
|
||||
"Device '%s' not found", arg->device);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -2613,7 +2657,7 @@ void qmp_block_set_io_throttle(BlockIOThrottle *arg, Error **errp)
|
||||
|
||||
bs = blk_bs(blk);
|
||||
if (!bs) {
|
||||
error_setg(errp, "Device '%s' has no medium", arg->device);
|
||||
error_setg(errp, "Device has no medium");
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -2677,7 +2721,9 @@ void qmp_block_set_io_throttle(BlockIOThrottle *arg, Error **errp)
|
||||
* just update the throttling group. */
|
||||
if (!blk_get_public(blk)->throttle_state) {
|
||||
blk_io_limits_enable(blk,
|
||||
arg->has_group ? arg->group : arg->device);
|
||||
arg->has_group ? arg->group :
|
||||
arg->has_device ? arg->device :
|
||||
arg->id);
|
||||
} else if (arg->has_group) {
|
||||
blk_io_limits_update_group(blk, arg->group);
|
||||
}
|
||||
@@ -2798,7 +2844,7 @@ void hmp_drive_del(Monitor *mon, const QDict *qdict)
|
||||
|
||||
bs = bdrv_find_node(id);
|
||||
if (bs) {
|
||||
qmp_x_blockdev_del(false, NULL, true, id, &local_err);
|
||||
qmp_x_blockdev_del(id, &local_err);
|
||||
if (local_err) {
|
||||
error_report_err(local_err);
|
||||
}
|
||||
@@ -3781,7 +3827,6 @@ out:
|
||||
void qmp_blockdev_add(BlockdevOptions *options, Error **errp)
|
||||
{
|
||||
BlockDriverState *bs;
|
||||
BlockBackend *blk = NULL;
|
||||
QObject *obj;
|
||||
Visitor *v = qmp_output_visitor_new(&obj);
|
||||
QDict *qdict;
|
||||
@@ -3813,37 +3858,21 @@ void qmp_blockdev_add(BlockdevOptions *options, Error **errp)
|
||||
|
||||
qdict_flatten(qdict);
|
||||
|
||||
if (options->has_id) {
|
||||
blk = blockdev_init(NULL, qdict, &local_err);
|
||||
if (local_err) {
|
||||
error_propagate(errp, local_err);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
bs = blk_bs(blk);
|
||||
} else {
|
||||
if (!qdict_get_try_str(qdict, "node-name")) {
|
||||
error_setg(errp, "'id' and/or 'node-name' need to be specified for "
|
||||
"the root node");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
bs = bds_tree_init(qdict, errp);
|
||||
if (!bs) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
QTAILQ_INSERT_TAIL(&monitor_bdrv_states, bs, monitor_list);
|
||||
if (!qdict_get_try_str(qdict, "node-name")) {
|
||||
error_setg(errp, "'node-name' must be specified for the root node");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
bs = bds_tree_init(qdict, errp);
|
||||
if (!bs) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
QTAILQ_INSERT_TAIL(&monitor_bdrv_states, bs, monitor_list);
|
||||
|
||||
if (bs && bdrv_key_required(bs)) {
|
||||
if (blk) {
|
||||
monitor_remove_blk(blk);
|
||||
blk_unref(blk);
|
||||
} else {
|
||||
QTAILQ_REMOVE(&monitor_bdrv_states, bs, monitor_list);
|
||||
bdrv_unref(bs);
|
||||
}
|
||||
QTAILQ_REMOVE(&monitor_bdrv_states, bs, monitor_list);
|
||||
bdrv_unref(bs);
|
||||
error_setg(errp, "blockdev-add doesn't support encrypted devices");
|
||||
goto fail;
|
||||
}
|
||||
@@ -3852,82 +3881,42 @@ fail:
|
||||
visit_free(v);
|
||||
}
|
||||
|
||||
void qmp_x_blockdev_del(bool has_id, const char *id,
|
||||
bool has_node_name, const char *node_name, Error **errp)
|
||||
void qmp_x_blockdev_del(const char *node_name, Error **errp)
|
||||
{
|
||||
AioContext *aio_context;
|
||||
BlockBackend *blk;
|
||||
BlockDriverState *bs;
|
||||
|
||||
if (has_id && has_node_name) {
|
||||
error_setg(errp, "Only one of id and node-name must be specified");
|
||||
return;
|
||||
} else if (!has_id && !has_node_name) {
|
||||
error_setg(errp, "No block device specified");
|
||||
bs = bdrv_find_node(node_name);
|
||||
if (!bs) {
|
||||
error_setg(errp, "Cannot find node %s", node_name);
|
||||
return;
|
||||
}
|
||||
|
||||
if (has_id) {
|
||||
/* blk_by_name() never returns a BB that is not owned by the monitor */
|
||||
blk = blk_by_name(id);
|
||||
if (!blk) {
|
||||
error_setg(errp, "Cannot find block backend %s", id);
|
||||
return;
|
||||
}
|
||||
if (blk_legacy_dinfo(blk)) {
|
||||
error_setg(errp, "Deleting block backend added with drive-add"
|
||||
" is not supported");
|
||||
return;
|
||||
}
|
||||
if (blk_get_refcnt(blk) > 1) {
|
||||
error_setg(errp, "Block backend %s is in use", id);
|
||||
return;
|
||||
}
|
||||
bs = blk_bs(blk);
|
||||
aio_context = blk_get_aio_context(blk);
|
||||
} else {
|
||||
blk = NULL;
|
||||
bs = bdrv_find_node(node_name);
|
||||
if (!bs) {
|
||||
error_setg(errp, "Cannot find node %s", node_name);
|
||||
return;
|
||||
}
|
||||
if (bdrv_has_blk(bs)) {
|
||||
error_setg(errp, "Node %s is in use by %s",
|
||||
node_name, bdrv_get_parent_name(bs));
|
||||
return;
|
||||
}
|
||||
aio_context = bdrv_get_aio_context(bs);
|
||||
if (bdrv_has_blk(bs)) {
|
||||
error_setg(errp, "Node %s is in use", node_name);
|
||||
return;
|
||||
}
|
||||
|
||||
aio_context = bdrv_get_aio_context(bs);
|
||||
aio_context_acquire(aio_context);
|
||||
|
||||
if (bs) {
|
||||
if (bdrv_op_is_blocked(bs, BLOCK_OP_TYPE_DRIVE_DEL, errp)) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!blk && !QTAILQ_IN_USE(bs, monitor_list)) {
|
||||
error_setg(errp, "Node %s is not owned by the monitor",
|
||||
bs->node_name);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (bs->refcnt > 1) {
|
||||
error_setg(errp, "Block device %s is in use",
|
||||
bdrv_get_device_or_node_name(bs));
|
||||
goto out;
|
||||
}
|
||||
if (bdrv_op_is_blocked(bs, BLOCK_OP_TYPE_DRIVE_DEL, errp)) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (blk) {
|
||||
monitor_remove_blk(blk);
|
||||
blk_unref(blk);
|
||||
} else {
|
||||
QTAILQ_REMOVE(&monitor_bdrv_states, bs, monitor_list);
|
||||
bdrv_unref(bs);
|
||||
if (!bs->monitor_list.tqe_prev) {
|
||||
error_setg(errp, "Node %s is not owned by the monitor",
|
||||
bs->node_name);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (bs->refcnt > 1) {
|
||||
error_setg(errp, "Block device %s is in use",
|
||||
bdrv_get_device_or_node_name(bs));
|
||||
goto out;
|
||||
}
|
||||
|
||||
QTAILQ_REMOVE(&monitor_bdrv_states, bs, monitor_list);
|
||||
bdrv_unref(bs);
|
||||
|
||||
out:
|
||||
aio_context_release(aio_context);
|
||||
}
|
||||
@@ -4040,7 +4029,7 @@ QemuOptsList qemu_common_drive_opts = {
|
||||
.type = QEMU_OPT_STRING,
|
||||
.help = "write error action",
|
||||
},{
|
||||
.name = "read-only",
|
||||
.name = BDRV_OPT_READ_ONLY,
|
||||
.type = QEMU_OPT_BOOL,
|
||||
.help = "open drive file as read-only",
|
||||
},{
|
||||
@@ -4158,10 +4147,6 @@ static QemuOptsList qemu_root_bds_opts = {
|
||||
.name = "aio",
|
||||
.type = QEMU_OPT_STRING,
|
||||
.help = "host AIO implementation (threads, native)",
|
||||
},{
|
||||
.name = "read-only",
|
||||
.type = QEMU_OPT_BOOL,
|
||||
.help = "open drive file as read-only",
|
||||
},{
|
||||
.name = "copy-on-read",
|
||||
.type = QEMU_OPT_BOOL,
|
||||
|
81
configure
vendored
81
configure
vendored
@@ -212,7 +212,6 @@ sdlabi=""
|
||||
virtfs=""
|
||||
vnc="yes"
|
||||
sparse="no"
|
||||
uuid=""
|
||||
vde=""
|
||||
vnc_sasl=""
|
||||
vnc_jpeg=""
|
||||
@@ -317,7 +316,6 @@ vte=""
|
||||
virglrenderer=""
|
||||
tpm="yes"
|
||||
libssh2=""
|
||||
vhdx=""
|
||||
numa=""
|
||||
tcmalloc="no"
|
||||
jemalloc="no"
|
||||
@@ -511,8 +509,6 @@ elif check_define __arm__ ; then
|
||||
cpu="arm"
|
||||
elif check_define __aarch64__ ; then
|
||||
cpu="aarch64"
|
||||
elif check_define __hppa__ ; then
|
||||
cpu="hppa"
|
||||
else
|
||||
cpu=$(uname -m)
|
||||
fi
|
||||
@@ -889,10 +885,6 @@ for opt do
|
||||
;;
|
||||
--disable-slirp) slirp="no"
|
||||
;;
|
||||
--disable-uuid) uuid="no"
|
||||
;;
|
||||
--enable-uuid) uuid="yes"
|
||||
;;
|
||||
--disable-vde) vde="no"
|
||||
;;
|
||||
--enable-vde) vde="yes"
|
||||
@@ -1105,6 +1097,12 @@ for opt do
|
||||
--disable-virtio-blk-data-plane|--enable-virtio-blk-data-plane)
|
||||
echo "$0: $opt is obsolete, virtio-blk data-plane is always on" >&2
|
||||
;;
|
||||
--enable-vhdx|--disable-vhdx)
|
||||
echo "$0: $opt is obsolete, VHDX driver is always built" >&2
|
||||
;;
|
||||
--enable-uuid|--disable-uuid)
|
||||
echo "$0: $opt is obsolete, UUID support is always built" >&2
|
||||
;;
|
||||
--disable-gtk) gtk="no"
|
||||
;;
|
||||
--enable-gtk) gtk="yes"
|
||||
@@ -1145,10 +1143,6 @@ for opt do
|
||||
;;
|
||||
--enable-libssh2) libssh2="yes"
|
||||
;;
|
||||
--enable-vhdx) vhdx="yes"
|
||||
;;
|
||||
--disable-vhdx) vhdx="no"
|
||||
;;
|
||||
--disable-numa) numa="no"
|
||||
;;
|
||||
--enable-numa) numa="yes"
|
||||
@@ -1367,7 +1361,6 @@ disabled with --disable-FEATURE, default is enabled if available:
|
||||
bluez bluez stack connectivity
|
||||
kvm KVM acceleration support
|
||||
rdma RDMA-based migration support
|
||||
uuid uuid support
|
||||
vde support for vde network
|
||||
netmap support for netmap network
|
||||
linux-aio Linux AIO support
|
||||
@@ -1391,7 +1384,6 @@ disabled with --disable-FEATURE, default is enabled if available:
|
||||
archipelago Archipelago backend
|
||||
tpm TPM support
|
||||
libssh2 ssh block device support
|
||||
vhdx support for the Microsoft VHDX image format
|
||||
numa libnuma support
|
||||
tcmalloc tcmalloc support
|
||||
jemalloc jemalloc support
|
||||
@@ -2663,47 +2655,6 @@ if compile_prog "" "" ; then
|
||||
fnmatch="yes"
|
||||
fi
|
||||
|
||||
##########################################
|
||||
# uuid_generate() probe, used for vdi block driver
|
||||
# Note that on some systems (notably MacOSX) no extra library
|
||||
# need be linked to get the uuid functions.
|
||||
if test "$uuid" != "no" ; then
|
||||
uuid_libs="-luuid"
|
||||
cat > $TMPC << EOF
|
||||
#include <uuid/uuid.h>
|
||||
int main(void)
|
||||
{
|
||||
uuid_t my_uuid;
|
||||
uuid_generate(my_uuid);
|
||||
return 0;
|
||||
}
|
||||
EOF
|
||||
if compile_prog "" "" ; then
|
||||
uuid="yes"
|
||||
elif compile_prog "" "$uuid_libs" ; then
|
||||
uuid="yes"
|
||||
libs_softmmu="$uuid_libs $libs_softmmu"
|
||||
libs_tools="$uuid_libs $libs_tools"
|
||||
else
|
||||
if test "$uuid" = "yes" ; then
|
||||
feature_not_found "uuid" "Install libuuid devel"
|
||||
fi
|
||||
uuid=no
|
||||
fi
|
||||
fi
|
||||
|
||||
if test "$vhdx" = "yes" ; then
|
||||
if test "$uuid" = "no" ; then
|
||||
error_exit "uuid required for VHDX support"
|
||||
fi
|
||||
elif test "$vhdx" != "no" ; then
|
||||
if test "$uuid" = "yes" ; then
|
||||
vhdx=yes
|
||||
else
|
||||
vhdx=no
|
||||
fi
|
||||
fi
|
||||
|
||||
##########################################
|
||||
# xfsctl() probe, used for raw-posix
|
||||
if test "$xfs" != "no" ; then
|
||||
@@ -3016,7 +2967,7 @@ fi
|
||||
|
||||
# g_test_trap_subprocess added in 2.38. Used by some tests.
|
||||
glib_subprocess=yes
|
||||
if ! $pkg_config --atleast-version=2.38 glib-2.0; then
|
||||
if test "$mingw32" = "yes" || ! $pkg_config --atleast-version=2.38 glib-2.0; then
|
||||
glib_subprocess=no
|
||||
fi
|
||||
|
||||
@@ -4077,7 +4028,7 @@ EOF
|
||||
if compile_prog "$vss_win32_include" "" ; then
|
||||
guest_agent_with_vss="yes"
|
||||
QEMU_CFLAGS="$QEMU_CFLAGS $vss_win32_include"
|
||||
libs_qga="-lole32 -loleaut32 -lshlwapi -luuid -lstdc++ -Wl,--enable-stdcall-fixup $libs_qga"
|
||||
libs_qga="-lole32 -loleaut32 -lshlwapi -lstdc++ -Wl,--enable-stdcall-fixup $libs_qga"
|
||||
qga_vss_provider="qga/vss-win32/qga-vss.dll qga/vss-win32/qga-vss.tlb"
|
||||
else
|
||||
if test "$vss_win32_sdk" != "" ; then
|
||||
@@ -4580,7 +4531,6 @@ if test "$libnfs" != "no" ; then
|
||||
if $pkg_config --atleast-version=1.9.3 libnfs; then
|
||||
libnfs="yes"
|
||||
libnfs_libs=$($pkg_config --libs libnfs)
|
||||
LIBS="$LIBS $libnfs_libs"
|
||||
else
|
||||
if test "$libnfs" = "yes" ; then
|
||||
feature_not_found "libnfs" "Install libnfs devel >= 1.9.3"
|
||||
@@ -4886,7 +4836,6 @@ echo "preadv support $preadv"
|
||||
echo "fdatasync $fdatasync"
|
||||
echo "madvise $madvise"
|
||||
echo "posix_madvise $posix_madvise"
|
||||
echo "uuid support $uuid"
|
||||
echo "libcap-ng support $cap_ng"
|
||||
echo "vhost-net support $vhost_net"
|
||||
echo "vhost-scsi support $vhost_scsi"
|
||||
@@ -4920,7 +4869,6 @@ echo "TPM support $tpm"
|
||||
echo "libssh2 support $libssh2"
|
||||
echo "TPM passthrough $tpm_passthrough"
|
||||
echo "QOM debugging $qom_cast_debug"
|
||||
echo "vhdx $vhdx"
|
||||
echo "lzo support $lzo"
|
||||
echo "snappy support $snappy"
|
||||
echo "bzip2 support $bzip2"
|
||||
@@ -5077,9 +5025,6 @@ fi
|
||||
if test "$fnmatch" = "yes" ; then
|
||||
echo "CONFIG_FNMATCH=y" >> $config_host_mak
|
||||
fi
|
||||
if test "$uuid" = "yes" ; then
|
||||
echo "CONFIG_UUID=y" >> $config_host_mak
|
||||
fi
|
||||
if test "$xfs" = "yes" ; then
|
||||
echo "CONFIG_XFS=y" >> $config_host_mak
|
||||
fi
|
||||
@@ -5353,7 +5298,8 @@ if test "$libiscsi" = "yes" ; then
|
||||
fi
|
||||
|
||||
if test "$libnfs" = "yes" ; then
|
||||
echo "CONFIG_LIBNFS=y" >> $config_host_mak
|
||||
echo "CONFIG_LIBNFS=m" >> $config_host_mak
|
||||
echo "LIBNFS_LIBS=$libnfs_libs" >> $config_host_mak
|
||||
fi
|
||||
|
||||
if test "$seccomp" = "yes"; then
|
||||
@@ -5445,10 +5391,6 @@ if test "$libssh2" = "yes" ; then
|
||||
echo "LIBSSH2_LIBS=$libssh2_libs" >> $config_host_mak
|
||||
fi
|
||||
|
||||
if test "$vhdx" = "yes" ; then
|
||||
echo "CONFIG_VHDX=y" >> $config_host_mak
|
||||
fi
|
||||
|
||||
# USB host support
|
||||
if test "$libusb" = "yes"; then
|
||||
echo "HOST_USB=libusb legacy" >> $config_host_mak
|
||||
@@ -5899,9 +5841,6 @@ for i in $ARCH $TARGET_BASE_ARCH ; do
|
||||
cris)
|
||||
disas_config "CRIS"
|
||||
;;
|
||||
hppa)
|
||||
disas_config "HPPA"
|
||||
;;
|
||||
i386|x86_64|x32)
|
||||
disas_config "I386"
|
||||
;;
|
||||
|
@@ -147,7 +147,8 @@ static inline tcg_target_ulong cpu_tb_exec(CPUState *cpu, TranslationBlock *itb)
|
||||
itb->tc_ptr, itb->pc, lookup_symbol(itb->pc));
|
||||
|
||||
#if defined(DEBUG_DISAS)
|
||||
if (qemu_loglevel_mask(CPU_LOG_TB_CPU)) {
|
||||
if (qemu_loglevel_mask(CPU_LOG_TB_CPU)
|
||||
&& qemu_log_in_addr_range(itb->pc)) {
|
||||
#if defined(TARGET_I386)
|
||||
log_cpu_state(cpu, CPU_DUMP_CCOP);
|
||||
#elif defined(TARGET_M68K)
|
||||
|
6
cputlb.c
6
cputlb.c
@@ -543,10 +543,8 @@ static bool victim_tlb_hit(CPUArchState *env, size_t mmu_idx, size_t index,
|
||||
#undef MMUSUFFIX
|
||||
|
||||
#define MMUSUFFIX _cmmu
|
||||
#undef GETPC_ADJ
|
||||
#define GETPC_ADJ 0
|
||||
#undef GETRA
|
||||
#define GETRA() ((uintptr_t)0)
|
||||
#undef GETPC
|
||||
#define GETPC() ((uintptr_t)0)
|
||||
#define SOFTMMU_CODE_ACCESS
|
||||
|
||||
#define SHIFT 0
|
||||
|
@@ -29,10 +29,7 @@
|
||||
#include "crypto/pbkdf.h"
|
||||
#include "crypto/secret.h"
|
||||
#include "crypto/random.h"
|
||||
|
||||
#ifdef CONFIG_UUID
|
||||
#include <uuid/uuid.h>
|
||||
#endif
|
||||
#include "qemu/uuid.h"
|
||||
|
||||
#include "qemu/coroutine.h"
|
||||
|
||||
@@ -877,18 +874,12 @@ qcrypto_block_luks_open(QCryptoBlock *block,
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
qcrypto_block_luks_uuid_gen(uint8_t *uuidstr, Error **errp)
|
||||
static void
|
||||
qcrypto_block_luks_uuid_gen(uint8_t *uuidstr)
|
||||
{
|
||||
#ifdef CONFIG_UUID
|
||||
uuid_t uuid;
|
||||
uuid_generate(uuid);
|
||||
uuid_unparse(uuid, (char *)uuidstr);
|
||||
return 0;
|
||||
#else
|
||||
error_setg(errp, "Unable to generate uuids on this platform");
|
||||
return -1;
|
||||
#endif
|
||||
QemuUUID uuid;
|
||||
qemu_uuid_generate(&uuid);
|
||||
qemu_uuid_unparse(&uuid, (char *)uuidstr);
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -917,8 +908,12 @@ qcrypto_block_luks_create(QCryptoBlock *block,
|
||||
const char *hash_alg;
|
||||
char *cipher_mode_spec = NULL;
|
||||
QCryptoCipherAlgorithm ivcipheralg = 0;
|
||||
uint64_t iters;
|
||||
|
||||
memcpy(&luks_opts, &options->u.luks, sizeof(luks_opts));
|
||||
if (!luks_opts.has_iter_time) {
|
||||
luks_opts.iter_time = 2000;
|
||||
}
|
||||
if (!luks_opts.has_cipher_alg) {
|
||||
luks_opts.cipher_alg = QCRYPTO_CIPHER_ALG_AES_256;
|
||||
}
|
||||
@@ -961,10 +956,7 @@ qcrypto_block_luks_create(QCryptoBlock *block,
|
||||
* it out to disk
|
||||
*/
|
||||
luks->header.version = QCRYPTO_BLOCK_LUKS_VERSION;
|
||||
if (qcrypto_block_luks_uuid_gen(luks->header.uuid,
|
||||
errp) < 0) {
|
||||
goto error;
|
||||
}
|
||||
qcrypto_block_luks_uuid_gen(luks->header.uuid);
|
||||
|
||||
cipher_alg = qcrypto_block_luks_cipher_alg_lookup(luks_opts.cipher_alg,
|
||||
errp);
|
||||
@@ -1064,26 +1056,40 @@ qcrypto_block_luks_create(QCryptoBlock *block,
|
||||
/* Determine how many iterations we need to hash the master
|
||||
* key, in order to have 1 second of compute time used
|
||||
*/
|
||||
luks->header.master_key_iterations =
|
||||
qcrypto_pbkdf2_count_iters(luks_opts.hash_alg,
|
||||
masterkey, luks->header.key_bytes,
|
||||
luks->header.master_key_salt,
|
||||
QCRYPTO_BLOCK_LUKS_SALT_LEN,
|
||||
&local_err);
|
||||
iters = qcrypto_pbkdf2_count_iters(luks_opts.hash_alg,
|
||||
masterkey, luks->header.key_bytes,
|
||||
luks->header.master_key_salt,
|
||||
QCRYPTO_BLOCK_LUKS_SALT_LEN,
|
||||
QCRYPTO_BLOCK_LUKS_DIGEST_LEN,
|
||||
&local_err);
|
||||
if (local_err) {
|
||||
error_propagate(errp, local_err);
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (iters > (ULLONG_MAX / luks_opts.iter_time)) {
|
||||
error_setg_errno(errp, ERANGE,
|
||||
"PBKDF iterations %llu too large to scale",
|
||||
(unsigned long long)iters);
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* iter_time was in millis, but count_iters reported for secs */
|
||||
iters = iters * luks_opts.iter_time / 1000;
|
||||
|
||||
/* Why /= 8 ? That matches cryptsetup, but there's no
|
||||
* explanation why they chose /= 8... Probably so that
|
||||
* if all 8 keyslots are active we only spend 1 second
|
||||
* in total time to check all keys */
|
||||
luks->header.master_key_iterations /= 8;
|
||||
luks->header.master_key_iterations = MAX(
|
||||
luks->header.master_key_iterations,
|
||||
QCRYPTO_BLOCK_LUKS_MIN_MASTER_KEY_ITERS);
|
||||
|
||||
iters /= 8;
|
||||
if (iters > UINT32_MAX) {
|
||||
error_setg_errno(errp, ERANGE,
|
||||
"PBKDF iterations %llu larger than %u",
|
||||
(unsigned long long)iters, UINT32_MAX);
|
||||
goto error;
|
||||
}
|
||||
iters = MAX(iters, QCRYPTO_BLOCK_LUKS_MIN_MASTER_KEY_ITERS);
|
||||
luks->header.master_key_iterations = iters;
|
||||
|
||||
/* Hash the master key, saving the result in the LUKS
|
||||
* header. This hash is used when opening the encrypted
|
||||
@@ -1131,22 +1137,36 @@ qcrypto_block_luks_create(QCryptoBlock *block,
|
||||
/* Again we determine how many iterations are required to
|
||||
* hash the user password while consuming 1 second of compute
|
||||
* time */
|
||||
luks->header.key_slots[0].iterations =
|
||||
qcrypto_pbkdf2_count_iters(luks_opts.hash_alg,
|
||||
(uint8_t *)password, strlen(password),
|
||||
luks->header.key_slots[0].salt,
|
||||
QCRYPTO_BLOCK_LUKS_SALT_LEN,
|
||||
&local_err);
|
||||
iters = qcrypto_pbkdf2_count_iters(luks_opts.hash_alg,
|
||||
(uint8_t *)password, strlen(password),
|
||||
luks->header.key_slots[0].salt,
|
||||
QCRYPTO_BLOCK_LUKS_SALT_LEN,
|
||||
luks->header.key_bytes,
|
||||
&local_err);
|
||||
if (local_err) {
|
||||
error_propagate(errp, local_err);
|
||||
goto error;
|
||||
}
|
||||
/* Why /= 2 ? That matches cryptsetup, but there's no
|
||||
* explanation why they chose /= 2... */
|
||||
luks->header.key_slots[0].iterations /= 2;
|
||||
luks->header.key_slots[0].iterations = MAX(
|
||||
luks->header.key_slots[0].iterations,
|
||||
QCRYPTO_BLOCK_LUKS_MIN_SLOT_KEY_ITERS);
|
||||
|
||||
if (iters > (ULLONG_MAX / luks_opts.iter_time)) {
|
||||
error_setg_errno(errp, ERANGE,
|
||||
"PBKDF iterations %llu too large to scale",
|
||||
(unsigned long long)iters);
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* iter_time was in millis, but count_iters reported for secs */
|
||||
iters = iters * luks_opts.iter_time / 1000;
|
||||
|
||||
if (iters > UINT32_MAX) {
|
||||
error_setg_errno(errp, ERANGE,
|
||||
"PBKDF iterations %llu larger than %u",
|
||||
(unsigned long long)iters, UINT32_MAX);
|
||||
goto error;
|
||||
}
|
||||
|
||||
luks->header.key_slots[0].iterations =
|
||||
MAX(iters, QCRYPTO_BLOCK_LUKS_MIN_SLOT_KEY_ITERS);
|
||||
|
||||
|
||||
/* Generate a key that we'll use to encrypt the master
|
||||
|
@@ -28,7 +28,11 @@ bool qcrypto_pbkdf2_supports(QCryptoHashAlgorithm hash)
|
||||
switch (hash) {
|
||||
case QCRYPTO_HASH_ALG_MD5:
|
||||
case QCRYPTO_HASH_ALG_SHA1:
|
||||
case QCRYPTO_HASH_ALG_SHA224:
|
||||
case QCRYPTO_HASH_ALG_SHA256:
|
||||
case QCRYPTO_HASH_ALG_SHA384:
|
||||
case QCRYPTO_HASH_ALG_SHA512:
|
||||
case QCRYPTO_HASH_ALG_RIPEMD160:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
@@ -38,20 +42,33 @@ bool qcrypto_pbkdf2_supports(QCryptoHashAlgorithm hash)
|
||||
int qcrypto_pbkdf2(QCryptoHashAlgorithm hash,
|
||||
const uint8_t *key, size_t nkey,
|
||||
const uint8_t *salt, size_t nsalt,
|
||||
unsigned int iterations,
|
||||
uint64_t iterations,
|
||||
uint8_t *out, size_t nout,
|
||||
Error **errp)
|
||||
{
|
||||
static const int hash_map[QCRYPTO_HASH_ALG__MAX] = {
|
||||
[QCRYPTO_HASH_ALG_MD5] = GCRY_MD_MD5,
|
||||
[QCRYPTO_HASH_ALG_SHA1] = GCRY_MD_SHA1,
|
||||
[QCRYPTO_HASH_ALG_SHA224] = GCRY_MD_SHA224,
|
||||
[QCRYPTO_HASH_ALG_SHA256] = GCRY_MD_SHA256,
|
||||
[QCRYPTO_HASH_ALG_SHA384] = GCRY_MD_SHA384,
|
||||
[QCRYPTO_HASH_ALG_SHA512] = GCRY_MD_SHA512,
|
||||
[QCRYPTO_HASH_ALG_RIPEMD160] = GCRY_MD_RMD160,
|
||||
};
|
||||
int ret;
|
||||
|
||||
if (iterations > ULONG_MAX) {
|
||||
error_setg_errno(errp, ERANGE,
|
||||
"PBKDF iterations %llu must be less than %lu",
|
||||
(long long unsigned)iterations, ULONG_MAX);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (hash >= G_N_ELEMENTS(hash_map) ||
|
||||
hash_map[hash] == GCRY_MD_NONE) {
|
||||
error_setg(errp, "Unexpected hash algorithm %d", hash);
|
||||
error_setg_errno(errp, ENOSYS,
|
||||
"PBKDF does not support hash algorithm %s",
|
||||
QCryptoHashAlgorithm_lookup[hash]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@@ -20,6 +20,7 @@
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include <nettle/pbkdf2.h>
|
||||
#include <nettle/hmac.h>
|
||||
#include "qapi/error.h"
|
||||
#include "crypto/pbkdf.h"
|
||||
|
||||
@@ -28,7 +29,11 @@ bool qcrypto_pbkdf2_supports(QCryptoHashAlgorithm hash)
|
||||
{
|
||||
switch (hash) {
|
||||
case QCRYPTO_HASH_ALG_SHA1:
|
||||
case QCRYPTO_HASH_ALG_SHA224:
|
||||
case QCRYPTO_HASH_ALG_SHA256:
|
||||
case QCRYPTO_HASH_ALG_SHA384:
|
||||
case QCRYPTO_HASH_ALG_SHA512:
|
||||
case QCRYPTO_HASH_ALG_RIPEMD160:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
@@ -38,28 +43,74 @@ bool qcrypto_pbkdf2_supports(QCryptoHashAlgorithm hash)
|
||||
int qcrypto_pbkdf2(QCryptoHashAlgorithm hash,
|
||||
const uint8_t *key, size_t nkey,
|
||||
const uint8_t *salt, size_t nsalt,
|
||||
unsigned int iterations,
|
||||
uint64_t iterations,
|
||||
uint8_t *out, size_t nout,
|
||||
Error **errp)
|
||||
{
|
||||
union {
|
||||
struct hmac_md5_ctx md5;
|
||||
struct hmac_sha1_ctx sha1;
|
||||
struct hmac_sha224_ctx sha224;
|
||||
struct hmac_sha256_ctx sha256;
|
||||
struct hmac_sha384_ctx sha384;
|
||||
struct hmac_sha512_ctx sha512;
|
||||
struct hmac_ripemd160_ctx ripemd160;
|
||||
} ctx;
|
||||
|
||||
if (iterations > UINT_MAX) {
|
||||
error_setg_errno(errp, ERANGE,
|
||||
"PBKDF iterations %llu must be less than %u",
|
||||
(long long unsigned)iterations, UINT_MAX);
|
||||
return -1;
|
||||
}
|
||||
|
||||
switch (hash) {
|
||||
case QCRYPTO_HASH_ALG_MD5:
|
||||
hmac_md5_set_key(&ctx.md5, nkey, key);
|
||||
PBKDF2(&ctx.md5, hmac_md5_update, hmac_md5_digest,
|
||||
MD5_DIGEST_SIZE, iterations, nsalt, salt, nout, out);
|
||||
break;
|
||||
|
||||
case QCRYPTO_HASH_ALG_SHA1:
|
||||
pbkdf2_hmac_sha1(nkey, key,
|
||||
iterations,
|
||||
nsalt, salt,
|
||||
nout, out);
|
||||
hmac_sha1_set_key(&ctx.sha1, nkey, key);
|
||||
PBKDF2(&ctx.sha1, hmac_sha1_update, hmac_sha1_digest,
|
||||
SHA1_DIGEST_SIZE, iterations, nsalt, salt, nout, out);
|
||||
break;
|
||||
|
||||
case QCRYPTO_HASH_ALG_SHA224:
|
||||
hmac_sha224_set_key(&ctx.sha224, nkey, key);
|
||||
PBKDF2(&ctx.sha224, hmac_sha224_update, hmac_sha224_digest,
|
||||
SHA224_DIGEST_SIZE, iterations, nsalt, salt, nout, out);
|
||||
break;
|
||||
|
||||
case QCRYPTO_HASH_ALG_SHA256:
|
||||
pbkdf2_hmac_sha256(nkey, key,
|
||||
iterations,
|
||||
nsalt, salt,
|
||||
nout, out);
|
||||
hmac_sha256_set_key(&ctx.sha256, nkey, key);
|
||||
PBKDF2(&ctx.sha256, hmac_sha256_update, hmac_sha256_digest,
|
||||
SHA256_DIGEST_SIZE, iterations, nsalt, salt, nout, out);
|
||||
break;
|
||||
|
||||
case QCRYPTO_HASH_ALG_SHA384:
|
||||
hmac_sha384_set_key(&ctx.sha384, nkey, key);
|
||||
PBKDF2(&ctx.sha384, hmac_sha384_update, hmac_sha384_digest,
|
||||
SHA384_DIGEST_SIZE, iterations, nsalt, salt, nout, out);
|
||||
break;
|
||||
|
||||
case QCRYPTO_HASH_ALG_SHA512:
|
||||
hmac_sha512_set_key(&ctx.sha512, nkey, key);
|
||||
PBKDF2(&ctx.sha512, hmac_sha512_update, hmac_sha512_digest,
|
||||
SHA512_DIGEST_SIZE, iterations, nsalt, salt, nout, out);
|
||||
break;
|
||||
|
||||
case QCRYPTO_HASH_ALG_RIPEMD160:
|
||||
hmac_ripemd160_set_key(&ctx.ripemd160, nkey, key);
|
||||
PBKDF2(&ctx.ripemd160, hmac_ripemd160_update, hmac_ripemd160_digest,
|
||||
RIPEMD160_DIGEST_SIZE, iterations, nsalt, salt, nout, out);
|
||||
break;
|
||||
|
||||
default:
|
||||
error_setg_errno(errp, ENOSYS,
|
||||
"PBKDF does not support hash algorithm %d", hash);
|
||||
"PBKDF does not support hash algorithm %s",
|
||||
QCryptoHashAlgorithm_lookup[hash]);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
|
@@ -32,7 +32,7 @@ int qcrypto_pbkdf2(QCryptoHashAlgorithm hash G_GNUC_UNUSED,
|
||||
size_t nkey G_GNUC_UNUSED,
|
||||
const uint8_t *salt G_GNUC_UNUSED,
|
||||
size_t nsalt G_GNUC_UNUSED,
|
||||
unsigned int iterations G_GNUC_UNUSED,
|
||||
uint64_t iterations G_GNUC_UNUSED,
|
||||
uint8_t *out G_GNUC_UNUSED,
|
||||
size_t nout G_GNUC_UNUSED,
|
||||
Error **errp)
|
||||
|
@@ -62,29 +62,33 @@ static int qcrypto_pbkdf2_get_thread_cpu(unsigned long long *val_ms,
|
||||
#endif
|
||||
}
|
||||
|
||||
int qcrypto_pbkdf2_count_iters(QCryptoHashAlgorithm hash,
|
||||
const uint8_t *key, size_t nkey,
|
||||
const uint8_t *salt, size_t nsalt,
|
||||
Error **errp)
|
||||
uint64_t qcrypto_pbkdf2_count_iters(QCryptoHashAlgorithm hash,
|
||||
const uint8_t *key, size_t nkey,
|
||||
const uint8_t *salt, size_t nsalt,
|
||||
size_t nout,
|
||||
Error **errp)
|
||||
{
|
||||
uint8_t out[32];
|
||||
long long int iterations = (1 << 15);
|
||||
uint64_t ret = -1;
|
||||
uint8_t *out;
|
||||
uint64_t iterations = (1 << 15);
|
||||
unsigned long long delta_ms, start_ms, end_ms;
|
||||
|
||||
out = g_new(uint8_t, nout);
|
||||
|
||||
while (1) {
|
||||
if (qcrypto_pbkdf2_get_thread_cpu(&start_ms, errp) < 0) {
|
||||
return -1;
|
||||
goto cleanup;
|
||||
}
|
||||
if (qcrypto_pbkdf2(hash,
|
||||
key, nkey,
|
||||
salt, nsalt,
|
||||
iterations,
|
||||
out, sizeof(out),
|
||||
out, nout,
|
||||
errp) < 0) {
|
||||
return -1;
|
||||
goto cleanup;
|
||||
}
|
||||
if (qcrypto_pbkdf2_get_thread_cpu(&end_ms, errp) < 0) {
|
||||
return -1;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
delta_ms = end_ms - start_ms;
|
||||
@@ -100,11 +104,10 @@ int qcrypto_pbkdf2_count_iters(QCryptoHashAlgorithm hash,
|
||||
|
||||
iterations = iterations * 1000 / delta_ms;
|
||||
|
||||
if (iterations > INT32_MAX) {
|
||||
error_setg(errp, "Iterations %lld too large for a 32-bit int",
|
||||
iterations);
|
||||
return -1;
|
||||
}
|
||||
ret = iterations;
|
||||
|
||||
return iterations;
|
||||
cleanup:
|
||||
memset(out, 0, nout);
|
||||
g_free(out);
|
||||
return ret;
|
||||
}
|
||||
|
@@ -351,16 +351,22 @@ qcrypto_tls_session_check_credentials(QCryptoTLSSession *session,
|
||||
{
|
||||
if (object_dynamic_cast(OBJECT(session->creds),
|
||||
TYPE_QCRYPTO_TLS_CREDS_ANON)) {
|
||||
trace_qcrypto_tls_session_check_creds(session, "nop");
|
||||
return 0;
|
||||
} else if (object_dynamic_cast(OBJECT(session->creds),
|
||||
TYPE_QCRYPTO_TLS_CREDS_X509)) {
|
||||
if (session->creds->verifyPeer) {
|
||||
return qcrypto_tls_session_check_certificate(session,
|
||||
errp);
|
||||
int ret = qcrypto_tls_session_check_certificate(session,
|
||||
errp);
|
||||
trace_qcrypto_tls_session_check_creds(session,
|
||||
ret == 0 ? "pass" : "fail");
|
||||
return ret;
|
||||
} else {
|
||||
trace_qcrypto_tls_session_check_creds(session, "skip");
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
trace_qcrypto_tls_session_check_creds(session, "error");
|
||||
error_setg(errp, "Unexpected credential type %s",
|
||||
object_get_typename(OBJECT(session->creds)));
|
||||
return -1;
|
||||
|
@@ -17,3 +17,4 @@ qcrypto_tls_creds_x509_load_cert_list(void *creds, const char *file) "TLS creds
|
||||
|
||||
# crypto/tlssession.c
|
||||
qcrypto_tls_session_new(void *session, void *creds, const char *hostname, const char *aclname, int endpoint) "TLS session new session=%p creds=%p hostname=%s aclname=%s endpoint=%d"
|
||||
qcrypto_tls_session_check_creds(void *session, const char *status) "TLS session check creds session=%p status=%s"
|
||||
|
2
disas.c
2
disas.c
@@ -310,8 +310,6 @@ void disas(FILE *out, void *code, unsigned long size)
|
||||
print_insn = print_insn_m68k;
|
||||
#elif defined(__s390__)
|
||||
print_insn = print_insn_s390;
|
||||
#elif defined(__hppa__)
|
||||
print_insn = print_insn_hppa;
|
||||
#elif defined(__ia64__)
|
||||
print_insn = print_insn_ia64;
|
||||
#endif
|
||||
|
@@ -9,7 +9,6 @@ libvixldir = $(SRC_PATH)/disas/libvixl
|
||||
# versions do not.
|
||||
arm-a64.o-cflags := -I$(libvixldir) -Wno-sign-compare
|
||||
common-obj-$(CONFIG_CRIS_DIS) += cris.o
|
||||
common-obj-$(CONFIG_HPPA_DIS) += hppa.o
|
||||
common-obj-$(CONFIG_I386_DIS) += i386.o
|
||||
common-obj-$(CONFIG_IA64_DIS) += ia64.o
|
||||
common-obj-$(CONFIG_M68K_DIS) += m68k.o
|
||||
|
11
disas/arm.c
11
disas/arm.c
@@ -24,7 +24,6 @@
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include "disas/bfd.h"
|
||||
#define ISSPACE(x) ((x) == ' ' || (x) == '\t' || (x) == '\n')
|
||||
|
||||
#define ARM_EXT_V1 0
|
||||
#define ARM_EXT_V2 0
|
||||
@@ -73,15 +72,6 @@ static void floatformat_to_double (unsigned char *data, double *dest)
|
||||
|
||||
/* End of qemu specific additions. */
|
||||
|
||||
/* FIXME: Belongs in global header. */
|
||||
#ifndef strneq
|
||||
#define strneq(a,b,n) (strncmp ((a), (b), (n)) == 0)
|
||||
#endif
|
||||
|
||||
#ifndef NUM_ELEM
|
||||
#define NUM_ELEM(a) (sizeof (a) / sizeof (a)[0])
|
||||
#endif
|
||||
|
||||
struct opcode32
|
||||
{
|
||||
unsigned long arch; /* Architecture defining this insn. */
|
||||
@@ -1528,7 +1518,6 @@ static const char *const iwmmxt_cregnames[] =
|
||||
/* Default to GCC register name set. */
|
||||
static unsigned int regname_selected = 1;
|
||||
|
||||
#define NUM_ARM_REGNAMES NUM_ELEM (regnames)
|
||||
#define arm_regnames regnames[regname_selected].reg_names
|
||||
|
||||
static bfd_boolean force_thumb = false;
|
||||
|
2832
disas/hppa.c
2832
disas/hppa.c
File diff suppressed because it is too large
Load Diff
@@ -264,12 +264,6 @@ sh_dsp_reg_nums;
|
||||
be some confusion between DSP and FPU etc. */
|
||||
#define SH_ARCH_UNKNOWN_ARCH 0xffffffff
|
||||
|
||||
/* These are defined in bfd/cpu-sh.c . */
|
||||
unsigned int sh_get_arch_from_bfd_mach (unsigned long mach);
|
||||
unsigned int sh_get_arch_up_from_bfd_mach (unsigned long mach);
|
||||
unsigned long sh_get_bfd_mach_from_arch_set (unsigned int arch_set);
|
||||
/* bfd_boolean sh_merge_bfd_arch (bfd *ibfd, bfd *obfd); */
|
||||
|
||||
/* Below are the 'architecture sets'.
|
||||
They describe the following inheritance graph:
|
||||
|
||||
|
@@ -964,9 +964,9 @@ Example:
|
||||
|
||||
Used to generate the marshaling/dispatch functions for the commands
|
||||
defined in the schema. The generated code implements
|
||||
qmp_marshal_COMMAND() (mentioned in qmp-commands.hx, and registered
|
||||
automatically), and declares qmp_COMMAND() that the user must
|
||||
implement. The following files are generated:
|
||||
qmp_marshal_COMMAND() (registered automatically), and declares
|
||||
qmp_COMMAND() that the user must implement. The following files are
|
||||
generated:
|
||||
|
||||
$(prefix)qmp-marshal.c: command marshal/dispatch functions for each
|
||||
QMP command defined in the schema. Functions
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -119,17 +119,6 @@ There are a few things to be noticed:
|
||||
5. Printing to the terminal is discouraged for QMP commands, we do it here
|
||||
because it's the easiest way to demonstrate a QMP command
|
||||
|
||||
Now a little hack is needed. As we're still using the old QMP server we need
|
||||
to add the new command to its internal dispatch table. This step won't be
|
||||
required in the near future. Open the qmp-commands.hx file and add the
|
||||
following at the bottom:
|
||||
|
||||
{
|
||||
.name = "hello-world",
|
||||
.args_type = "",
|
||||
.mhandler.cmd_new = qmp_marshal_hello_world,
|
||||
},
|
||||
|
||||
You're done. Now build qemu, run it as suggested in the "Testing" section,
|
||||
and then type the following QMP command:
|
||||
|
||||
@@ -174,21 +163,6 @@ There are two important details to be noticed:
|
||||
2. The C implementation signature must follow the schema's argument ordering,
|
||||
which is defined by the "data" member
|
||||
|
||||
The last step is to update the qmp-commands.hx file:
|
||||
|
||||
{
|
||||
.name = "hello-world",
|
||||
.args_type = "message:s?",
|
||||
.mhandler.cmd_new = qmp_marshal_hello_world,
|
||||
},
|
||||
|
||||
Notice that the "args_type" member got our "message" argument. The character
|
||||
"s" stands for "string" and "?" means it's optional. This too must be ordered
|
||||
according to the C implementation and schema file. You can look for more
|
||||
examples in the qmp-commands.hx file if you need to define more arguments.
|
||||
|
||||
Again, this step won't be required in the future.
|
||||
|
||||
Time to test our new version of the "hello-world" command. Build qemu, run it as
|
||||
described in the "Testing" section and then send two commands:
|
||||
|
||||
@@ -337,7 +311,7 @@ we should add it to the hmp-commands.hx file:
|
||||
.args_type = "message:s?",
|
||||
.params = "hello-world [message]",
|
||||
.help = "Print message to the standard output",
|
||||
.mhandler.cmd = hmp_hello_world,
|
||||
.cmd = hmp_hello_world,
|
||||
},
|
||||
|
||||
STEXI
|
||||
@@ -454,14 +428,6 @@ There are a number of things to be noticed:
|
||||
6. You have to include the "qmp-commands.h" header file in qemu-timer.c,
|
||||
otherwise qemu won't build
|
||||
|
||||
The last step is to add the correspoding entry in the qmp-commands.hx file:
|
||||
|
||||
{
|
||||
.name = "query-alarm-clock",
|
||||
.args_type = "",
|
||||
.mhandler.cmd_new = qmp_marshal_query_alarm_clock,
|
||||
},
|
||||
|
||||
Time to test the new command. Build qemu, run it as described in the "Testing"
|
||||
section and try this:
|
||||
|
||||
@@ -518,7 +484,7 @@ in the monitor.c file. The entry for the "info alarmclock" follows:
|
||||
.args_type = "",
|
||||
.params = "",
|
||||
.help = "show information about the alarm clock",
|
||||
.mhandler.info = hmp_info_alarm_clock,
|
||||
.cmd = hmp_info_alarm_clock,
|
||||
},
|
||||
|
||||
To test this, run qemu and type "info alarmclock" in the user monitor.
|
||||
@@ -600,14 +566,6 @@ iteration of the loop. That's because the alarm timer method in use is the
|
||||
first element of the alarm_timers array. Also notice that QAPI lists are handled
|
||||
by hand and we return the head of the list.
|
||||
|
||||
To test this you have to add the corresponding qmp-commands.hx entry:
|
||||
|
||||
{
|
||||
.name = "query-alarm-methods",
|
||||
.args_type = "",
|
||||
.mhandler.cmd_new = qmp_marshal_query_alarm_methods,
|
||||
},
|
||||
|
||||
Now Build qemu, run it as explained in the "Testing" section and try our new
|
||||
command:
|
||||
|
||||
|
@@ -25,11 +25,6 @@ void v9fs_string_free(V9fsString *str)
|
||||
str->size = 0;
|
||||
}
|
||||
|
||||
void v9fs_string_null(V9fsString *str)
|
||||
{
|
||||
v9fs_string_free(str);
|
||||
}
|
||||
|
||||
void GCC_FMT_ATTR(2, 3)
|
||||
v9fs_string_sprintf(V9fsString *str, const char *fmt, ...)
|
||||
{
|
||||
|
@@ -77,7 +77,6 @@ static inline void v9fs_string_init(V9fsString *str)
|
||||
str->size = 0;
|
||||
}
|
||||
extern void v9fs_string_free(V9fsString *str);
|
||||
extern void v9fs_string_null(V9fsString *str);
|
||||
extern void v9fs_string_sprintf(V9fsString *str, const char *fmt, ...);
|
||||
extern void v9fs_string_copy(V9fsString *lhs, V9fsString *rhs);
|
||||
|
||||
|
@@ -18,7 +18,7 @@ ETEXI
|
||||
.args_type = "",
|
||||
.params = "",
|
||||
.help = "show the version of QEMU",
|
||||
.mhandler.cmd = hmp_info_version,
|
||||
.cmd = hmp_info_version,
|
||||
},
|
||||
|
||||
STEXI
|
||||
@@ -32,7 +32,7 @@ ETEXI
|
||||
.args_type = "",
|
||||
.params = "",
|
||||
.help = "show the network state",
|
||||
.mhandler.cmd = hmp_info_network,
|
||||
.cmd = hmp_info_network,
|
||||
},
|
||||
|
||||
STEXI
|
||||
@@ -46,7 +46,7 @@ ETEXI
|
||||
.args_type = "",
|
||||
.params = "",
|
||||
.help = "show the character devices",
|
||||
.mhandler.cmd = hmp_info_chardev,
|
||||
.cmd = hmp_info_chardev,
|
||||
},
|
||||
|
||||
STEXI
|
||||
@@ -61,7 +61,7 @@ ETEXI
|
||||
.params = "[-n] [-v] [device]",
|
||||
.help = "show info of one block device or all block devices "
|
||||
"(-n: show named nodes; -v: show details)",
|
||||
.mhandler.cmd = hmp_info_block,
|
||||
.cmd = hmp_info_block,
|
||||
},
|
||||
|
||||
STEXI
|
||||
@@ -75,7 +75,7 @@ ETEXI
|
||||
.args_type = "",
|
||||
.params = "",
|
||||
.help = "show block device statistics",
|
||||
.mhandler.cmd = hmp_info_blockstats,
|
||||
.cmd = hmp_info_blockstats,
|
||||
},
|
||||
|
||||
STEXI
|
||||
@@ -89,7 +89,7 @@ ETEXI
|
||||
.args_type = "",
|
||||
.params = "",
|
||||
.help = "show progress of ongoing block device operations",
|
||||
.mhandler.cmd = hmp_info_block_jobs,
|
||||
.cmd = hmp_info_block_jobs,
|
||||
},
|
||||
|
||||
STEXI
|
||||
@@ -103,7 +103,7 @@ ETEXI
|
||||
.args_type = "",
|
||||
.params = "",
|
||||
.help = "show the cpu registers",
|
||||
.mhandler.cmd = hmp_info_registers,
|
||||
.cmd = hmp_info_registers,
|
||||
},
|
||||
|
||||
STEXI
|
||||
@@ -118,7 +118,7 @@ ETEXI
|
||||
.args_type = "",
|
||||
.params = "",
|
||||
.help = "show local apic state",
|
||||
.mhandler.cmd = hmp_info_local_apic,
|
||||
.cmd = hmp_info_local_apic,
|
||||
},
|
||||
#endif
|
||||
|
||||
@@ -134,7 +134,7 @@ ETEXI
|
||||
.args_type = "",
|
||||
.params = "",
|
||||
.help = "show io apic state",
|
||||
.mhandler.cmd = hmp_info_io_apic,
|
||||
.cmd = hmp_info_io_apic,
|
||||
},
|
||||
#endif
|
||||
|
||||
@@ -149,7 +149,7 @@ ETEXI
|
||||
.args_type = "",
|
||||
.params = "",
|
||||
.help = "show infos for each CPU",
|
||||
.mhandler.cmd = hmp_info_cpus,
|
||||
.cmd = hmp_info_cpus,
|
||||
},
|
||||
|
||||
STEXI
|
||||
@@ -163,7 +163,7 @@ ETEXI
|
||||
.args_type = "",
|
||||
.params = "",
|
||||
.help = "show the command line history",
|
||||
.mhandler.cmd = hmp_info_history,
|
||||
.cmd = hmp_info_history,
|
||||
},
|
||||
|
||||
STEXI
|
||||
@@ -180,11 +180,11 @@ ETEXI
|
||||
.params = "",
|
||||
.help = "show the interrupts statistics (if available)",
|
||||
#ifdef TARGET_SPARC
|
||||
.mhandler.cmd = sun4m_hmp_info_irq,
|
||||
.cmd = sun4m_hmp_info_irq,
|
||||
#elif defined(TARGET_LM32)
|
||||
.mhandler.cmd = lm32_hmp_info_irq,
|
||||
.cmd = lm32_hmp_info_irq,
|
||||
#else
|
||||
.mhandler.cmd = hmp_info_irq,
|
||||
.cmd = hmp_info_irq,
|
||||
#endif
|
||||
},
|
||||
|
||||
@@ -200,11 +200,11 @@ ETEXI
|
||||
.params = "",
|
||||
.help = "show i8259 (PIC) state",
|
||||
#ifdef TARGET_SPARC
|
||||
.mhandler.cmd = sun4m_hmp_info_pic,
|
||||
.cmd = sun4m_hmp_info_pic,
|
||||
#elif defined(TARGET_LM32)
|
||||
.mhandler.cmd = lm32_hmp_info_pic,
|
||||
.cmd = lm32_hmp_info_pic,
|
||||
#else
|
||||
.mhandler.cmd = hmp_info_pic,
|
||||
.cmd = hmp_info_pic,
|
||||
#endif
|
||||
},
|
||||
#endif
|
||||
@@ -220,7 +220,7 @@ ETEXI
|
||||
.args_type = "",
|
||||
.params = "",
|
||||
.help = "show PCI info",
|
||||
.mhandler.cmd = hmp_info_pci,
|
||||
.cmd = hmp_info_pci,
|
||||
},
|
||||
|
||||
STEXI
|
||||
@@ -236,7 +236,7 @@ ETEXI
|
||||
.args_type = "",
|
||||
.params = "",
|
||||
.help = "show virtual to physical memory mappings",
|
||||
.mhandler.cmd = hmp_info_tlb,
|
||||
.cmd = hmp_info_tlb,
|
||||
},
|
||||
#endif
|
||||
|
||||
@@ -252,7 +252,7 @@ ETEXI
|
||||
.args_type = "",
|
||||
.params = "",
|
||||
.help = "show the active virtual memory mappings",
|
||||
.mhandler.cmd = hmp_info_mem,
|
||||
.cmd = hmp_info_mem,
|
||||
},
|
||||
#endif
|
||||
|
||||
@@ -267,7 +267,7 @@ ETEXI
|
||||
.args_type = "",
|
||||
.params = "",
|
||||
.help = "show memory tree",
|
||||
.mhandler.cmd = hmp_info_mtree,
|
||||
.cmd = hmp_info_mtree,
|
||||
},
|
||||
|
||||
STEXI
|
||||
@@ -281,7 +281,7 @@ ETEXI
|
||||
.args_type = "",
|
||||
.params = "",
|
||||
.help = "show dynamic compiler info",
|
||||
.mhandler.cmd = hmp_info_jit,
|
||||
.cmd = hmp_info_jit,
|
||||
},
|
||||
|
||||
STEXI
|
||||
@@ -295,7 +295,7 @@ ETEXI
|
||||
.args_type = "",
|
||||
.params = "",
|
||||
.help = "show dynamic compiler opcode counters",
|
||||
.mhandler.cmd = hmp_info_opcount,
|
||||
.cmd = hmp_info_opcount,
|
||||
},
|
||||
|
||||
STEXI
|
||||
@@ -309,7 +309,7 @@ ETEXI
|
||||
.args_type = "",
|
||||
.params = "",
|
||||
.help = "show KVM information",
|
||||
.mhandler.cmd = hmp_info_kvm,
|
||||
.cmd = hmp_info_kvm,
|
||||
},
|
||||
|
||||
STEXI
|
||||
@@ -323,7 +323,7 @@ ETEXI
|
||||
.args_type = "",
|
||||
.params = "",
|
||||
.help = "show NUMA information",
|
||||
.mhandler.cmd = hmp_info_numa,
|
||||
.cmd = hmp_info_numa,
|
||||
},
|
||||
|
||||
STEXI
|
||||
@@ -337,7 +337,7 @@ ETEXI
|
||||
.args_type = "",
|
||||
.params = "",
|
||||
.help = "show guest USB devices",
|
||||
.mhandler.cmd = hmp_info_usb,
|
||||
.cmd = hmp_info_usb,
|
||||
},
|
||||
|
||||
STEXI
|
||||
@@ -351,7 +351,7 @@ ETEXI
|
||||
.args_type = "",
|
||||
.params = "",
|
||||
.help = "show host USB devices",
|
||||
.mhandler.cmd = hmp_info_usbhost,
|
||||
.cmd = hmp_info_usbhost,
|
||||
},
|
||||
|
||||
STEXI
|
||||
@@ -365,7 +365,7 @@ ETEXI
|
||||
.args_type = "",
|
||||
.params = "",
|
||||
.help = "show profiling information",
|
||||
.mhandler.cmd = hmp_info_profile,
|
||||
.cmd = hmp_info_profile,
|
||||
},
|
||||
|
||||
STEXI
|
||||
@@ -379,7 +379,7 @@ ETEXI
|
||||
.args_type = "",
|
||||
.params = "",
|
||||
.help = "show capture information",
|
||||
.mhandler.cmd = hmp_info_capture,
|
||||
.cmd = hmp_info_capture,
|
||||
},
|
||||
|
||||
STEXI
|
||||
@@ -393,7 +393,7 @@ ETEXI
|
||||
.args_type = "",
|
||||
.params = "",
|
||||
.help = "show the currently saved VM snapshots",
|
||||
.mhandler.cmd = hmp_info_snapshots,
|
||||
.cmd = hmp_info_snapshots,
|
||||
},
|
||||
|
||||
STEXI
|
||||
@@ -407,7 +407,7 @@ ETEXI
|
||||
.args_type = "",
|
||||
.params = "",
|
||||
.help = "show the current VM status (running|paused)",
|
||||
.mhandler.cmd = hmp_info_status,
|
||||
.cmd = hmp_info_status,
|
||||
},
|
||||
|
||||
STEXI
|
||||
@@ -421,7 +421,7 @@ ETEXI
|
||||
.args_type = "",
|
||||
.params = "",
|
||||
.help = "show which guest mouse is receiving events",
|
||||
.mhandler.cmd = hmp_info_mice,
|
||||
.cmd = hmp_info_mice,
|
||||
},
|
||||
|
||||
STEXI
|
||||
@@ -435,7 +435,7 @@ ETEXI
|
||||
.args_type = "",
|
||||
.params = "",
|
||||
.help = "show the vnc server status",
|
||||
.mhandler.cmd = hmp_info_vnc,
|
||||
.cmd = hmp_info_vnc,
|
||||
},
|
||||
|
||||
STEXI
|
||||
@@ -450,7 +450,7 @@ ETEXI
|
||||
.args_type = "",
|
||||
.params = "",
|
||||
.help = "show the spice server status",
|
||||
.mhandler.cmd = hmp_info_spice,
|
||||
.cmd = hmp_info_spice,
|
||||
},
|
||||
#endif
|
||||
|
||||
@@ -465,7 +465,7 @@ ETEXI
|
||||
.args_type = "",
|
||||
.params = "",
|
||||
.help = "show the current VM name",
|
||||
.mhandler.cmd = hmp_info_name,
|
||||
.cmd = hmp_info_name,
|
||||
},
|
||||
|
||||
STEXI
|
||||
@@ -479,7 +479,7 @@ ETEXI
|
||||
.args_type = "",
|
||||
.params = "",
|
||||
.help = "show the current VM UUID",
|
||||
.mhandler.cmd = hmp_info_uuid,
|
||||
.cmd = hmp_info_uuid,
|
||||
},
|
||||
|
||||
STEXI
|
||||
@@ -493,7 +493,7 @@ ETEXI
|
||||
.args_type = "",
|
||||
.params = "",
|
||||
.help = "show CPU statistics",
|
||||
.mhandler.cmd = hmp_info_cpustats,
|
||||
.cmd = hmp_info_cpustats,
|
||||
},
|
||||
|
||||
STEXI
|
||||
@@ -508,7 +508,7 @@ ETEXI
|
||||
.args_type = "",
|
||||
.params = "",
|
||||
.help = "show user network stack connection states",
|
||||
.mhandler.cmd = hmp_info_usernet,
|
||||
.cmd = hmp_info_usernet,
|
||||
},
|
||||
#endif
|
||||
|
||||
@@ -523,7 +523,7 @@ ETEXI
|
||||
.args_type = "",
|
||||
.params = "",
|
||||
.help = "show migration status",
|
||||
.mhandler.cmd = hmp_info_migrate,
|
||||
.cmd = hmp_info_migrate,
|
||||
},
|
||||
|
||||
STEXI
|
||||
@@ -537,7 +537,7 @@ ETEXI
|
||||
.args_type = "",
|
||||
.params = "",
|
||||
.help = "show current migration capabilities",
|
||||
.mhandler.cmd = hmp_info_migrate_capabilities,
|
||||
.cmd = hmp_info_migrate_capabilities,
|
||||
},
|
||||
|
||||
STEXI
|
||||
@@ -551,7 +551,7 @@ ETEXI
|
||||
.args_type = "",
|
||||
.params = "",
|
||||
.help = "show current migration parameters",
|
||||
.mhandler.cmd = hmp_info_migrate_parameters,
|
||||
.cmd = hmp_info_migrate_parameters,
|
||||
},
|
||||
|
||||
STEXI
|
||||
@@ -565,7 +565,7 @@ ETEXI
|
||||
.args_type = "",
|
||||
.params = "",
|
||||
.help = "show current migration xbzrle cache size",
|
||||
.mhandler.cmd = hmp_info_migrate_cache_size,
|
||||
.cmd = hmp_info_migrate_cache_size,
|
||||
},
|
||||
|
||||
STEXI
|
||||
@@ -579,7 +579,7 @@ ETEXI
|
||||
.args_type = "",
|
||||
.params = "",
|
||||
.help = "show balloon information",
|
||||
.mhandler.cmd = hmp_info_balloon,
|
||||
.cmd = hmp_info_balloon,
|
||||
},
|
||||
|
||||
STEXI
|
||||
@@ -593,7 +593,7 @@ ETEXI
|
||||
.args_type = "",
|
||||
.params = "",
|
||||
.help = "show device tree",
|
||||
.mhandler.cmd = hmp_info_qtree,
|
||||
.cmd = hmp_info_qtree,
|
||||
},
|
||||
|
||||
STEXI
|
||||
@@ -607,7 +607,7 @@ ETEXI
|
||||
.args_type = "",
|
||||
.params = "",
|
||||
.help = "show qdev device model list",
|
||||
.mhandler.cmd = hmp_info_qdm,
|
||||
.cmd = hmp_info_qdm,
|
||||
},
|
||||
|
||||
STEXI
|
||||
@@ -621,7 +621,7 @@ ETEXI
|
||||
.args_type = "path:s?",
|
||||
.params = "[path]",
|
||||
.help = "show QOM composition tree",
|
||||
.mhandler.cmd = hmp_info_qom_tree,
|
||||
.cmd = hmp_info_qom_tree,
|
||||
},
|
||||
|
||||
STEXI
|
||||
@@ -635,7 +635,7 @@ ETEXI
|
||||
.args_type = "",
|
||||
.params = "",
|
||||
.help = "show roms",
|
||||
.mhandler.cmd = hmp_info_roms,
|
||||
.cmd = hmp_info_roms,
|
||||
},
|
||||
|
||||
STEXI
|
||||
@@ -650,7 +650,7 @@ ETEXI
|
||||
.params = "[name] [vcpu]",
|
||||
.help = "show available trace-events & their state "
|
||||
"(name: event name pattern; vcpu: vCPU to query, default is any)",
|
||||
.mhandler.cmd = hmp_info_trace_events,
|
||||
.cmd = hmp_info_trace_events,
|
||||
.command_completion = info_trace_events_completion,
|
||||
},
|
||||
|
||||
@@ -665,7 +665,7 @@ ETEXI
|
||||
.args_type = "",
|
||||
.params = "",
|
||||
.help = "show the TPM device",
|
||||
.mhandler.cmd = hmp_info_tpm,
|
||||
.cmd = hmp_info_tpm,
|
||||
},
|
||||
|
||||
STEXI
|
||||
@@ -679,7 +679,7 @@ ETEXI
|
||||
.args_type = "",
|
||||
.params = "",
|
||||
.help = "show memory backends",
|
||||
.mhandler.cmd = hmp_info_memdev,
|
||||
.cmd = hmp_info_memdev,
|
||||
},
|
||||
|
||||
STEXI
|
||||
@@ -693,7 +693,7 @@ ETEXI
|
||||
.args_type = "",
|
||||
.params = "",
|
||||
.help = "show memory devices",
|
||||
.mhandler.cmd = hmp_info_memory_devices,
|
||||
.cmd = hmp_info_memory_devices,
|
||||
},
|
||||
|
||||
STEXI
|
||||
@@ -707,7 +707,7 @@ ETEXI
|
||||
.args_type = "",
|
||||
.params = "",
|
||||
.help = "show iothreads",
|
||||
.mhandler.cmd = hmp_info_iothreads,
|
||||
.cmd = hmp_info_iothreads,
|
||||
},
|
||||
|
||||
STEXI
|
||||
@@ -721,7 +721,7 @@ ETEXI
|
||||
.args_type = "name:s",
|
||||
.params = "name",
|
||||
.help = "Show rocker switch",
|
||||
.mhandler.cmd = hmp_rocker,
|
||||
.cmd = hmp_rocker,
|
||||
},
|
||||
|
||||
STEXI
|
||||
@@ -735,7 +735,7 @@ ETEXI
|
||||
.args_type = "name:s",
|
||||
.params = "name",
|
||||
.help = "Show rocker ports",
|
||||
.mhandler.cmd = hmp_rocker_ports,
|
||||
.cmd = hmp_rocker_ports,
|
||||
},
|
||||
|
||||
STEXI
|
||||
@@ -749,7 +749,7 @@ ETEXI
|
||||
.args_type = "name:s,tbl_id:i?",
|
||||
.params = "name [tbl_id]",
|
||||
.help = "Show rocker OF-DPA flow tables",
|
||||
.mhandler.cmd = hmp_rocker_of_dpa_flows,
|
||||
.cmd = hmp_rocker_of_dpa_flows,
|
||||
},
|
||||
|
||||
STEXI
|
||||
@@ -763,7 +763,7 @@ ETEXI
|
||||
.args_type = "name:s,type:i?",
|
||||
.params = "name [type]",
|
||||
.help = "Show rocker OF-DPA groups",
|
||||
.mhandler.cmd = hmp_rocker_of_dpa_groups,
|
||||
.cmd = hmp_rocker_of_dpa_groups,
|
||||
},
|
||||
|
||||
STEXI
|
||||
@@ -778,7 +778,7 @@ ETEXI
|
||||
.args_type = "addr:l",
|
||||
.params = "address",
|
||||
.help = "Display the value of a storage key",
|
||||
.mhandler.cmd = hmp_info_skeys,
|
||||
.cmd = hmp_info_skeys,
|
||||
},
|
||||
#endif
|
||||
|
||||
@@ -793,7 +793,7 @@ ETEXI
|
||||
.args_type = "",
|
||||
.params = "",
|
||||
.help = "Display the latest dump status",
|
||||
.mhandler.cmd = hmp_info_dump,
|
||||
.cmd = hmp_info_dump,
|
||||
},
|
||||
|
||||
STEXI
|
||||
@@ -807,7 +807,7 @@ ETEXI
|
||||
.args_type = "",
|
||||
.params = "",
|
||||
.help = "Show information about hotpluggable CPUs",
|
||||
.mhandler.cmd = hmp_hotpluggable_cpus,
|
||||
.cmd = hmp_hotpluggable_cpus,
|
||||
},
|
||||
|
||||
STEXI
|
||||
|
208
hmp-commands.hx
208
hmp-commands.hx
@@ -14,7 +14,7 @@ ETEXI
|
||||
.args_type = "name:S?",
|
||||
.params = "[cmd]",
|
||||
.help = "show the help",
|
||||
.mhandler.cmd = do_help_cmd,
|
||||
.cmd = do_help_cmd,
|
||||
},
|
||||
|
||||
STEXI
|
||||
@@ -28,7 +28,7 @@ ETEXI
|
||||
.args_type = "device:B",
|
||||
.params = "device|all",
|
||||
.help = "commit changes to the disk images (if -snapshot is used) or backing files",
|
||||
.mhandler.cmd = hmp_commit,
|
||||
.cmd = hmp_commit,
|
||||
},
|
||||
|
||||
STEXI
|
||||
@@ -47,7 +47,7 @@ ETEXI
|
||||
.args_type = "",
|
||||
.params = "",
|
||||
.help = "quit the emulator",
|
||||
.mhandler.cmd = hmp_quit,
|
||||
.cmd = hmp_quit,
|
||||
},
|
||||
|
||||
STEXI
|
||||
@@ -61,7 +61,7 @@ ETEXI
|
||||
.args_type = "device:B,size:o",
|
||||
.params = "device size",
|
||||
.help = "resize a block image",
|
||||
.mhandler.cmd = hmp_block_resize,
|
||||
.cmd = hmp_block_resize,
|
||||
},
|
||||
|
||||
STEXI
|
||||
@@ -78,7 +78,7 @@ ETEXI
|
||||
.args_type = "device:B,speed:o?,base:s?",
|
||||
.params = "device [speed [base]]",
|
||||
.help = "copy data from a backing file into a block device",
|
||||
.mhandler.cmd = hmp_block_stream,
|
||||
.cmd = hmp_block_stream,
|
||||
},
|
||||
|
||||
STEXI
|
||||
@@ -92,7 +92,7 @@ ETEXI
|
||||
.args_type = "device:B,speed:o",
|
||||
.params = "device speed",
|
||||
.help = "set maximum speed for a background block operation",
|
||||
.mhandler.cmd = hmp_block_job_set_speed,
|
||||
.cmd = hmp_block_job_set_speed,
|
||||
},
|
||||
|
||||
STEXI
|
||||
@@ -107,7 +107,7 @@ ETEXI
|
||||
.params = "[-f] device",
|
||||
.help = "stop an active background block operation (use -f"
|
||||
"\n\t\t\t if the operation is currently paused)",
|
||||
.mhandler.cmd = hmp_block_job_cancel,
|
||||
.cmd = hmp_block_job_cancel,
|
||||
},
|
||||
|
||||
STEXI
|
||||
@@ -121,7 +121,7 @@ ETEXI
|
||||
.args_type = "device:B",
|
||||
.params = "device",
|
||||
.help = "stop an active background block operation",
|
||||
.mhandler.cmd = hmp_block_job_complete,
|
||||
.cmd = hmp_block_job_complete,
|
||||
},
|
||||
|
||||
STEXI
|
||||
@@ -136,7 +136,7 @@ ETEXI
|
||||
.args_type = "device:B",
|
||||
.params = "device",
|
||||
.help = "pause an active background block operation",
|
||||
.mhandler.cmd = hmp_block_job_pause,
|
||||
.cmd = hmp_block_job_pause,
|
||||
},
|
||||
|
||||
STEXI
|
||||
@@ -150,7 +150,7 @@ ETEXI
|
||||
.args_type = "device:B",
|
||||
.params = "device",
|
||||
.help = "resume a paused background block operation",
|
||||
.mhandler.cmd = hmp_block_job_resume,
|
||||
.cmd = hmp_block_job_resume,
|
||||
},
|
||||
|
||||
STEXI
|
||||
@@ -164,7 +164,7 @@ ETEXI
|
||||
.args_type = "force:-f,device:B",
|
||||
.params = "[-f] device",
|
||||
.help = "eject a removable medium (use -f to force it)",
|
||||
.mhandler.cmd = hmp_eject,
|
||||
.cmd = hmp_eject,
|
||||
},
|
||||
|
||||
STEXI
|
||||
@@ -178,7 +178,7 @@ ETEXI
|
||||
.args_type = "id:B",
|
||||
.params = "device",
|
||||
.help = "remove host block device",
|
||||
.mhandler.cmd = hmp_drive_del,
|
||||
.cmd = hmp_drive_del,
|
||||
},
|
||||
|
||||
STEXI
|
||||
@@ -197,7 +197,7 @@ ETEXI
|
||||
.args_type = "device:B,target:F,arg:s?,read-only-mode:s?",
|
||||
.params = "device filename [format [read-only-mode]]",
|
||||
.help = "change a removable medium, optional format",
|
||||
.mhandler.cmd = hmp_change,
|
||||
.cmd = hmp_change,
|
||||
},
|
||||
|
||||
STEXI
|
||||
@@ -256,7 +256,7 @@ ETEXI
|
||||
.args_type = "filename:F",
|
||||
.params = "filename",
|
||||
.help = "save screen into PPM image 'filename'",
|
||||
.mhandler.cmd = hmp_screendump,
|
||||
.cmd = hmp_screendump,
|
||||
},
|
||||
|
||||
STEXI
|
||||
@@ -270,7 +270,7 @@ ETEXI
|
||||
.args_type = "filename:F",
|
||||
.params = "filename",
|
||||
.help = "output logs to 'filename'",
|
||||
.mhandler.cmd = hmp_logfile,
|
||||
.cmd = hmp_logfile,
|
||||
},
|
||||
|
||||
STEXI
|
||||
@@ -285,7 +285,7 @@ ETEXI
|
||||
.params = "name on|off [vcpu]",
|
||||
.help = "changes status of a specific trace event "
|
||||
"(vcpu: vCPU to set, default is all)",
|
||||
.mhandler.cmd = hmp_trace_event,
|
||||
.cmd = hmp_trace_event,
|
||||
.command_completion = trace_event_completion,
|
||||
},
|
||||
|
||||
@@ -301,7 +301,7 @@ ETEXI
|
||||
.args_type = "op:s?,arg:F?",
|
||||
.params = "on|off|flush|set [arg]",
|
||||
.help = "open, close, or flush trace file, or set a new file name",
|
||||
.mhandler.cmd = hmp_trace_file,
|
||||
.cmd = hmp_trace_file,
|
||||
},
|
||||
|
||||
STEXI
|
||||
@@ -316,7 +316,7 @@ ETEXI
|
||||
.args_type = "items:s",
|
||||
.params = "item1[,...]",
|
||||
.help = "activate logging of the specified items",
|
||||
.mhandler.cmd = hmp_log,
|
||||
.cmd = hmp_log,
|
||||
},
|
||||
|
||||
STEXI
|
||||
@@ -330,7 +330,7 @@ ETEXI
|
||||
.args_type = "name:s?",
|
||||
.params = "[tag|id]",
|
||||
.help = "save a VM snapshot. If no tag or id are provided, a new snapshot is created",
|
||||
.mhandler.cmd = hmp_savevm,
|
||||
.cmd = hmp_savevm,
|
||||
},
|
||||
|
||||
STEXI
|
||||
@@ -347,7 +347,7 @@ ETEXI
|
||||
.args_type = "name:s",
|
||||
.params = "tag|id",
|
||||
.help = "restore a VM snapshot from its tag or id",
|
||||
.mhandler.cmd = hmp_loadvm,
|
||||
.cmd = hmp_loadvm,
|
||||
.command_completion = loadvm_completion,
|
||||
},
|
||||
|
||||
@@ -363,7 +363,7 @@ ETEXI
|
||||
.args_type = "name:s",
|
||||
.params = "tag|id",
|
||||
.help = "delete a VM snapshot from its tag or id",
|
||||
.mhandler.cmd = hmp_delvm,
|
||||
.cmd = hmp_delvm,
|
||||
.command_completion = delvm_completion,
|
||||
},
|
||||
|
||||
@@ -378,7 +378,7 @@ ETEXI
|
||||
.args_type = "option:s?",
|
||||
.params = "[on|off]",
|
||||
.help = "run emulation in singlestep mode or switch to normal mode",
|
||||
.mhandler.cmd = hmp_singlestep,
|
||||
.cmd = hmp_singlestep,
|
||||
},
|
||||
|
||||
STEXI
|
||||
@@ -393,7 +393,7 @@ ETEXI
|
||||
.args_type = "",
|
||||
.params = "",
|
||||
.help = "stop emulation",
|
||||
.mhandler.cmd = hmp_stop,
|
||||
.cmd = hmp_stop,
|
||||
},
|
||||
|
||||
STEXI
|
||||
@@ -407,7 +407,7 @@ ETEXI
|
||||
.args_type = "",
|
||||
.params = "",
|
||||
.help = "resume emulation",
|
||||
.mhandler.cmd = hmp_cont,
|
||||
.cmd = hmp_cont,
|
||||
},
|
||||
|
||||
STEXI
|
||||
@@ -421,7 +421,7 @@ ETEXI
|
||||
.args_type = "",
|
||||
.params = "",
|
||||
.help = "wakeup guest from suspend",
|
||||
.mhandler.cmd = hmp_system_wakeup,
|
||||
.cmd = hmp_system_wakeup,
|
||||
},
|
||||
|
||||
STEXI
|
||||
@@ -435,7 +435,7 @@ ETEXI
|
||||
.args_type = "device:s?",
|
||||
.params = "[device]",
|
||||
.help = "start gdbserver on given device (default 'tcp::1234'), stop with 'none'",
|
||||
.mhandler.cmd = hmp_gdbserver,
|
||||
.cmd = hmp_gdbserver,
|
||||
},
|
||||
|
||||
STEXI
|
||||
@@ -449,7 +449,7 @@ ETEXI
|
||||
.args_type = "fmt:/,addr:l",
|
||||
.params = "/fmt addr",
|
||||
.help = "virtual memory dump starting at 'addr'",
|
||||
.mhandler.cmd = hmp_memory_dump,
|
||||
.cmd = hmp_memory_dump,
|
||||
},
|
||||
|
||||
STEXI
|
||||
@@ -463,7 +463,7 @@ ETEXI
|
||||
.args_type = "fmt:/,addr:l",
|
||||
.params = "/fmt addr",
|
||||
.help = "physical memory dump starting at 'addr'",
|
||||
.mhandler.cmd = hmp_physical_memory_dump,
|
||||
.cmd = hmp_physical_memory_dump,
|
||||
},
|
||||
|
||||
STEXI
|
||||
@@ -530,7 +530,7 @@ ETEXI
|
||||
.args_type = "fmt:/,val:l",
|
||||
.params = "/fmt expr",
|
||||
.help = "print expression value (use $reg for CPU register access)",
|
||||
.mhandler.cmd = do_print,
|
||||
.cmd = do_print,
|
||||
},
|
||||
|
||||
STEXI
|
||||
@@ -545,7 +545,7 @@ ETEXI
|
||||
.args_type = "fmt:/,addr:i,index:i.",
|
||||
.params = "/fmt addr",
|
||||
.help = "I/O port read",
|
||||
.mhandler.cmd = hmp_ioport_read,
|
||||
.cmd = hmp_ioport_read,
|
||||
},
|
||||
|
||||
STEXI
|
||||
@@ -559,7 +559,7 @@ ETEXI
|
||||
.args_type = "fmt:/,addr:i,val:i",
|
||||
.params = "/fmt addr value",
|
||||
.help = "I/O port write",
|
||||
.mhandler.cmd = hmp_ioport_write,
|
||||
.cmd = hmp_ioport_write,
|
||||
},
|
||||
|
||||
STEXI
|
||||
@@ -573,7 +573,7 @@ ETEXI
|
||||
.args_type = "keys:s,hold-time:i?",
|
||||
.params = "keys [hold_ms]",
|
||||
.help = "send keys to the VM (e.g. 'sendkey ctrl-alt-f1', default hold time=100 ms)",
|
||||
.mhandler.cmd = hmp_sendkey,
|
||||
.cmd = hmp_sendkey,
|
||||
.command_completion = sendkey_completion,
|
||||
},
|
||||
|
||||
@@ -596,7 +596,7 @@ ETEXI
|
||||
.args_type = "",
|
||||
.params = "",
|
||||
.help = "reset the system",
|
||||
.mhandler.cmd = hmp_system_reset,
|
||||
.cmd = hmp_system_reset,
|
||||
},
|
||||
|
||||
STEXI
|
||||
@@ -610,7 +610,7 @@ ETEXI
|
||||
.args_type = "",
|
||||
.params = "",
|
||||
.help = "send system power down event",
|
||||
.mhandler.cmd = hmp_system_powerdown,
|
||||
.cmd = hmp_system_powerdown,
|
||||
},
|
||||
|
||||
STEXI
|
||||
@@ -624,7 +624,7 @@ ETEXI
|
||||
.args_type = "start:i,size:i",
|
||||
.params = "addr size",
|
||||
.help = "compute the checksum of a memory region",
|
||||
.mhandler.cmd = hmp_sum,
|
||||
.cmd = hmp_sum,
|
||||
},
|
||||
|
||||
STEXI
|
||||
@@ -638,7 +638,7 @@ ETEXI
|
||||
.args_type = "devname:s",
|
||||
.params = "device",
|
||||
.help = "add USB device (e.g. 'host:bus.addr' or 'host:vendor_id:product_id')",
|
||||
.mhandler.cmd = hmp_usb_add,
|
||||
.cmd = hmp_usb_add,
|
||||
},
|
||||
|
||||
STEXI
|
||||
@@ -653,7 +653,7 @@ ETEXI
|
||||
.args_type = "devname:s",
|
||||
.params = "device",
|
||||
.help = "remove USB device 'bus.addr'",
|
||||
.mhandler.cmd = hmp_usb_del,
|
||||
.cmd = hmp_usb_del,
|
||||
},
|
||||
|
||||
STEXI
|
||||
@@ -669,7 +669,7 @@ ETEXI
|
||||
.args_type = "device:O",
|
||||
.params = "driver[,prop=value][,...]",
|
||||
.help = "add device, like -device on the command line",
|
||||
.mhandler.cmd = hmp_device_add,
|
||||
.cmd = hmp_device_add,
|
||||
.command_completion = device_add_completion,
|
||||
},
|
||||
|
||||
@@ -684,7 +684,7 @@ ETEXI
|
||||
.args_type = "id:s",
|
||||
.params = "device",
|
||||
.help = "remove device",
|
||||
.mhandler.cmd = hmp_device_del,
|
||||
.cmd = hmp_device_del,
|
||||
.command_completion = device_del_completion,
|
||||
},
|
||||
|
||||
@@ -700,7 +700,7 @@ ETEXI
|
||||
.args_type = "index:i",
|
||||
.params = "index",
|
||||
.help = "set the default CPU",
|
||||
.mhandler.cmd = hmp_cpu,
|
||||
.cmd = hmp_cpu,
|
||||
},
|
||||
|
||||
STEXI
|
||||
@@ -714,7 +714,7 @@ ETEXI
|
||||
.args_type = "dx_str:s,dy_str:s,dz_str:s?",
|
||||
.params = "dx dy [dz]",
|
||||
.help = "send mouse move events",
|
||||
.mhandler.cmd = hmp_mouse_move,
|
||||
.cmd = hmp_mouse_move,
|
||||
},
|
||||
|
||||
STEXI
|
||||
@@ -729,7 +729,7 @@ ETEXI
|
||||
.args_type = "button_state:i",
|
||||
.params = "state",
|
||||
.help = "change mouse button state (1=L, 2=M, 4=R)",
|
||||
.mhandler.cmd = hmp_mouse_button,
|
||||
.cmd = hmp_mouse_button,
|
||||
},
|
||||
|
||||
STEXI
|
||||
@@ -743,7 +743,7 @@ ETEXI
|
||||
.args_type = "index:i",
|
||||
.params = "index",
|
||||
.help = "set which mouse device receives events",
|
||||
.mhandler.cmd = hmp_mouse_set,
|
||||
.cmd = hmp_mouse_set,
|
||||
},
|
||||
|
||||
STEXI
|
||||
@@ -761,7 +761,7 @@ ETEXI
|
||||
.args_type = "path:F,freq:i?,bits:i?,nchannels:i?",
|
||||
.params = "path [frequency [bits [channels]]]",
|
||||
.help = "capture audio to a wave file (default frequency=44100 bits=16 channels=2)",
|
||||
.mhandler.cmd = hmp_wavcapture,
|
||||
.cmd = hmp_wavcapture,
|
||||
},
|
||||
STEXI
|
||||
@item wavcapture @var{filename} [@var{frequency} [@var{bits} [@var{channels}]]]
|
||||
@@ -782,7 +782,7 @@ ETEXI
|
||||
.args_type = "n:i",
|
||||
.params = "capture index",
|
||||
.help = "stop capture",
|
||||
.mhandler.cmd = hmp_stopcapture,
|
||||
.cmd = hmp_stopcapture,
|
||||
},
|
||||
STEXI
|
||||
@item stopcapture @var{index}
|
||||
@@ -798,7 +798,7 @@ ETEXI
|
||||
.args_type = "val:l,size:i,filename:s",
|
||||
.params = "addr size file",
|
||||
.help = "save to disk virtual memory dump starting at 'addr' of size 'size'",
|
||||
.mhandler.cmd = hmp_memsave,
|
||||
.cmd = hmp_memsave,
|
||||
},
|
||||
|
||||
STEXI
|
||||
@@ -812,7 +812,7 @@ ETEXI
|
||||
.args_type = "val:l,size:i,filename:s",
|
||||
.params = "addr size file",
|
||||
.help = "save to disk physical memory dump starting at 'addr' of size 'size'",
|
||||
.mhandler.cmd = hmp_pmemsave,
|
||||
.cmd = hmp_pmemsave,
|
||||
},
|
||||
|
||||
STEXI
|
||||
@@ -826,7 +826,7 @@ ETEXI
|
||||
.args_type = "bootdevice:s",
|
||||
.params = "bootdevice",
|
||||
.help = "define new values for the boot device list",
|
||||
.mhandler.cmd = hmp_boot_set,
|
||||
.cmd = hmp_boot_set,
|
||||
},
|
||||
|
||||
STEXI
|
||||
@@ -844,7 +844,7 @@ ETEXI
|
||||
.args_type = "",
|
||||
.params = "",
|
||||
.help = "inject an NMI",
|
||||
.mhandler.cmd = hmp_nmi,
|
||||
.cmd = hmp_nmi,
|
||||
},
|
||||
STEXI
|
||||
@item nmi @var{cpu}
|
||||
@@ -858,7 +858,7 @@ ETEXI
|
||||
.args_type = "device:s,data:s",
|
||||
.params = "device data",
|
||||
.help = "Write to a ring buffer character device",
|
||||
.mhandler.cmd = hmp_ringbuf_write,
|
||||
.cmd = hmp_ringbuf_write,
|
||||
.command_completion = ringbuf_write_completion,
|
||||
},
|
||||
|
||||
@@ -875,7 +875,7 @@ ETEXI
|
||||
.args_type = "device:s,size:i",
|
||||
.params = "device size",
|
||||
.help = "Read from a ring buffer character device",
|
||||
.mhandler.cmd = hmp_ringbuf_read,
|
||||
.cmd = hmp_ringbuf_read,
|
||||
.command_completion = ringbuf_write_completion,
|
||||
},
|
||||
|
||||
@@ -901,7 +901,7 @@ ETEXI
|
||||
" full copy of disk\n\t\t\t -i for migration without "
|
||||
"shared storage with incremental copy of disk "
|
||||
"(base image shared between src and destination)",
|
||||
.mhandler.cmd = hmp_migrate,
|
||||
.cmd = hmp_migrate,
|
||||
},
|
||||
|
||||
|
||||
@@ -918,7 +918,7 @@ ETEXI
|
||||
.args_type = "",
|
||||
.params = "",
|
||||
.help = "cancel the current VM migration",
|
||||
.mhandler.cmd = hmp_migrate_cancel,
|
||||
.cmd = hmp_migrate_cancel,
|
||||
},
|
||||
|
||||
STEXI
|
||||
@@ -933,7 +933,7 @@ ETEXI
|
||||
.args_type = "uri:s",
|
||||
.params = "uri",
|
||||
.help = "Continue an incoming migration from an -incoming defer",
|
||||
.mhandler.cmd = hmp_migrate_incoming,
|
||||
.cmd = hmp_migrate_incoming,
|
||||
},
|
||||
|
||||
STEXI
|
||||
@@ -954,7 +954,7 @@ ETEXI
|
||||
"The cache size affects the number of cache misses."
|
||||
"In case of a high cache miss ratio you need to increase"
|
||||
" the cache size",
|
||||
.mhandler.cmd = hmp_migrate_set_cache_size,
|
||||
.cmd = hmp_migrate_set_cache_size,
|
||||
},
|
||||
|
||||
STEXI
|
||||
@@ -969,7 +969,7 @@ ETEXI
|
||||
.params = "value",
|
||||
.help = "set maximum speed (in bytes) for migrations. "
|
||||
"Defaults to MB if no size suffix is specified, ie. B/K/M/G/T",
|
||||
.mhandler.cmd = hmp_migrate_set_speed,
|
||||
.cmd = hmp_migrate_set_speed,
|
||||
},
|
||||
|
||||
STEXI
|
||||
@@ -983,7 +983,7 @@ ETEXI
|
||||
.args_type = "value:T",
|
||||
.params = "value",
|
||||
.help = "set maximum tolerated downtime (in seconds) for migrations",
|
||||
.mhandler.cmd = hmp_migrate_set_downtime,
|
||||
.cmd = hmp_migrate_set_downtime,
|
||||
},
|
||||
|
||||
STEXI
|
||||
@@ -997,7 +997,7 @@ ETEXI
|
||||
.args_type = "capability:s,state:b",
|
||||
.params = "capability state",
|
||||
.help = "Enable/Disable the usage of a capability for migration",
|
||||
.mhandler.cmd = hmp_migrate_set_capability,
|
||||
.cmd = hmp_migrate_set_capability,
|
||||
.command_completion = migrate_set_capability_completion,
|
||||
},
|
||||
|
||||
@@ -1012,7 +1012,7 @@ ETEXI
|
||||
.args_type = "parameter:s,value:s",
|
||||
.params = "parameter value",
|
||||
.help = "Set the parameter for migration",
|
||||
.mhandler.cmd = hmp_migrate_set_parameter,
|
||||
.cmd = hmp_migrate_set_parameter,
|
||||
.command_completion = migrate_set_parameter_completion,
|
||||
},
|
||||
|
||||
@@ -1029,7 +1029,7 @@ ETEXI
|
||||
.help = "Followup to a migration command to switch the migration"
|
||||
" to postcopy mode. The postcopy-ram capability must "
|
||||
"be set before the original migration command.",
|
||||
.mhandler.cmd = hmp_migrate_start_postcopy,
|
||||
.cmd = hmp_migrate_start_postcopy,
|
||||
},
|
||||
|
||||
STEXI
|
||||
@@ -1044,7 +1044,7 @@ ETEXI
|
||||
.args_type = "protocol:s,hostname:s,port:i?,tls-port:i?,cert-subject:s?",
|
||||
.params = "protocol hostname port tls-port cert-subject",
|
||||
.help = "set migration information for remote display",
|
||||
.mhandler.cmd = hmp_client_migrate_info,
|
||||
.cmd = hmp_client_migrate_info,
|
||||
},
|
||||
|
||||
STEXI
|
||||
@@ -1067,7 +1067,7 @@ ETEXI
|
||||
"-s: dump in kdump-compressed format, with snappy compression.\n\t\t\t"
|
||||
"begin: the starting physical address.\n\t\t\t"
|
||||
"length: the memory size, in bytes.",
|
||||
.mhandler.cmd = hmp_dump_guest_memory,
|
||||
.cmd = hmp_dump_guest_memory,
|
||||
},
|
||||
|
||||
|
||||
@@ -1094,7 +1094,7 @@ ETEXI
|
||||
.args_type = "filename:F",
|
||||
.params = "",
|
||||
.help = "Save guest storage keys into file 'filename'.\n",
|
||||
.mhandler.cmd = hmp_dump_skeys,
|
||||
.cmd = hmp_dump_skeys,
|
||||
},
|
||||
#endif
|
||||
|
||||
@@ -1116,7 +1116,7 @@ ETEXI
|
||||
"The default format is qcow2. The -n flag requests QEMU\n\t\t\t"
|
||||
"to reuse the image found in new-image-file, instead of\n\t\t\t"
|
||||
"recreating it from scratch.",
|
||||
.mhandler.cmd = hmp_snapshot_blkdev,
|
||||
.cmd = hmp_snapshot_blkdev,
|
||||
},
|
||||
|
||||
STEXI
|
||||
@@ -1132,7 +1132,7 @@ ETEXI
|
||||
.help = "take an internal snapshot of device.\n\t\t\t"
|
||||
"The format of the image used by device must\n\t\t\t"
|
||||
"support it, such as qcow2.\n\t\t\t",
|
||||
.mhandler.cmd = hmp_snapshot_blkdev_internal,
|
||||
.cmd = hmp_snapshot_blkdev_internal,
|
||||
},
|
||||
|
||||
STEXI
|
||||
@@ -1150,7 +1150,7 @@ ETEXI
|
||||
"the snapshot matching both id and name.\n\t\t\t"
|
||||
"The format of the image used by device must\n\t\t\t"
|
||||
"support it, such as qcow2.\n\t\t\t",
|
||||
.mhandler.cmd = hmp_snapshot_delete_blkdev_internal,
|
||||
.cmd = hmp_snapshot_delete_blkdev_internal,
|
||||
},
|
||||
|
||||
STEXI
|
||||
@@ -1171,7 +1171,7 @@ ETEXI
|
||||
"in new-image-file, instead of recreating it from scratch.\n\t\t\t"
|
||||
"The -f flag requests QEMU to copy the whole disk,\n\t\t\t"
|
||||
"so that the result does not need a backing file.\n\t\t\t",
|
||||
.mhandler.cmd = hmp_drive_mirror,
|
||||
.cmd = hmp_drive_mirror,
|
||||
},
|
||||
STEXI
|
||||
@item drive_mirror
|
||||
@@ -1194,7 +1194,7 @@ ETEXI
|
||||
"so that the result does not need a backing file.\n\t\t\t"
|
||||
"The -c flag requests QEMU to compress backup data\n\t\t\t"
|
||||
"(if the target format supports it).\n\t\t\t",
|
||||
.mhandler.cmd = hmp_drive_backup,
|
||||
.cmd = hmp_drive_backup,
|
||||
},
|
||||
STEXI
|
||||
@item drive_backup
|
||||
@@ -1212,7 +1212,7 @@ ETEXI
|
||||
"[,snapshot=on|off][,cache=on|off]\n"
|
||||
"[,readonly=on|off][,copy-on-read=on|off]",
|
||||
.help = "add drive to PCI storage controller",
|
||||
.mhandler.cmd = hmp_drive_add,
|
||||
.cmd = hmp_drive_add,
|
||||
},
|
||||
|
||||
STEXI
|
||||
@@ -1236,7 +1236,7 @@ ETEXI
|
||||
"<error_status> = error string or 32bit\n\t\t\t"
|
||||
"<tlb header> = 32bit x 4\n\t\t\t"
|
||||
"<tlb header prefix> = 32bit x 4",
|
||||
.mhandler.cmd = hmp_pcie_aer_inject_error,
|
||||
.cmd = hmp_pcie_aer_inject_error,
|
||||
},
|
||||
|
||||
STEXI
|
||||
@@ -1250,7 +1250,7 @@ ETEXI
|
||||
.args_type = "device:s,opts:s?",
|
||||
.params = "tap|user|socket|vde|netmap|bridge|vhost-user|dump [options]",
|
||||
.help = "add host VLAN client",
|
||||
.mhandler.cmd = hmp_host_net_add,
|
||||
.cmd = hmp_host_net_add,
|
||||
.command_completion = host_net_add_completion,
|
||||
},
|
||||
|
||||
@@ -1265,7 +1265,7 @@ ETEXI
|
||||
.args_type = "vlan_id:i,device:s",
|
||||
.params = "vlan_id name",
|
||||
.help = "remove host VLAN client",
|
||||
.mhandler.cmd = hmp_host_net_remove,
|
||||
.cmd = hmp_host_net_remove,
|
||||
.command_completion = host_net_remove_completion,
|
||||
},
|
||||
|
||||
@@ -1280,7 +1280,7 @@ ETEXI
|
||||
.args_type = "netdev:O",
|
||||
.params = "[user|tap|socket|vde|bridge|hubport|netmap|vhost-user],id=str[,prop=value][,...]",
|
||||
.help = "add host network device",
|
||||
.mhandler.cmd = hmp_netdev_add,
|
||||
.cmd = hmp_netdev_add,
|
||||
.command_completion = netdev_add_completion,
|
||||
},
|
||||
|
||||
@@ -1295,7 +1295,7 @@ ETEXI
|
||||
.args_type = "id:s",
|
||||
.params = "id",
|
||||
.help = "remove host network device",
|
||||
.mhandler.cmd = hmp_netdev_del,
|
||||
.cmd = hmp_netdev_del,
|
||||
.command_completion = netdev_del_completion,
|
||||
},
|
||||
|
||||
@@ -1310,7 +1310,7 @@ ETEXI
|
||||
.args_type = "object:O",
|
||||
.params = "[qom-type=]type,id=str[,prop=value][,...]",
|
||||
.help = "create QOM object",
|
||||
.mhandler.cmd = hmp_object_add,
|
||||
.cmd = hmp_object_add,
|
||||
.command_completion = object_add_completion,
|
||||
},
|
||||
|
||||
@@ -1325,7 +1325,7 @@ ETEXI
|
||||
.args_type = "id:s",
|
||||
.params = "id",
|
||||
.help = "destroy QOM object",
|
||||
.mhandler.cmd = hmp_object_del,
|
||||
.cmd = hmp_object_del,
|
||||
.command_completion = object_del_completion,
|
||||
},
|
||||
|
||||
@@ -1341,7 +1341,7 @@ ETEXI
|
||||
.args_type = "arg1:s,arg2:s?,arg3:s?",
|
||||
.params = "[vlan_id name] [tcp|udp]:[hostaddr]:hostport-[guestaddr]:guestport",
|
||||
.help = "redirect TCP or UDP connections from host to guest (requires -net user)",
|
||||
.mhandler.cmd = hmp_hostfwd_add,
|
||||
.cmd = hmp_hostfwd_add,
|
||||
},
|
||||
#endif
|
||||
STEXI
|
||||
@@ -1356,7 +1356,7 @@ ETEXI
|
||||
.args_type = "arg1:s,arg2:s?,arg3:s?",
|
||||
.params = "[vlan_id name] [tcp|udp]:[hostaddr]:hostport",
|
||||
.help = "remove host-to-guest TCP or UDP redirection",
|
||||
.mhandler.cmd = hmp_hostfwd_remove,
|
||||
.cmd = hmp_hostfwd_remove,
|
||||
},
|
||||
|
||||
#endif
|
||||
@@ -1371,7 +1371,7 @@ ETEXI
|
||||
.args_type = "value:M",
|
||||
.params = "target",
|
||||
.help = "request VM to change its memory allocation (in MB)",
|
||||
.mhandler.cmd = hmp_balloon,
|
||||
.cmd = hmp_balloon,
|
||||
},
|
||||
|
||||
STEXI
|
||||
@@ -1385,7 +1385,7 @@ ETEXI
|
||||
.args_type = "name:s,up:b",
|
||||
.params = "name on|off",
|
||||
.help = "change the link status of a network adapter",
|
||||
.mhandler.cmd = hmp_set_link,
|
||||
.cmd = hmp_set_link,
|
||||
.command_completion = set_link_completion,
|
||||
},
|
||||
|
||||
@@ -1400,7 +1400,7 @@ ETEXI
|
||||
.args_type = "action:s",
|
||||
.params = "[reset|shutdown|poweroff|pause|debug|none]",
|
||||
.help = "change watchdog action",
|
||||
.mhandler.cmd = hmp_watchdog_action,
|
||||
.cmd = hmp_watchdog_action,
|
||||
.command_completion = watchdog_action_completion,
|
||||
},
|
||||
|
||||
@@ -1415,7 +1415,7 @@ ETEXI
|
||||
.args_type = "aclname:s",
|
||||
.params = "aclname",
|
||||
.help = "list rules in the access control list",
|
||||
.mhandler.cmd = hmp_acl_show,
|
||||
.cmd = hmp_acl_show,
|
||||
},
|
||||
|
||||
STEXI
|
||||
@@ -1432,7 +1432,7 @@ ETEXI
|
||||
.args_type = "aclname:s,policy:s",
|
||||
.params = "aclname allow|deny",
|
||||
.help = "set default access control list policy",
|
||||
.mhandler.cmd = hmp_acl_policy,
|
||||
.cmd = hmp_acl_policy,
|
||||
},
|
||||
|
||||
STEXI
|
||||
@@ -1448,7 +1448,7 @@ ETEXI
|
||||
.args_type = "aclname:s,match:s,policy:s,index:i?",
|
||||
.params = "aclname match allow|deny [index]",
|
||||
.help = "add a match rule to the access control list",
|
||||
.mhandler.cmd = hmp_acl_add,
|
||||
.cmd = hmp_acl_add,
|
||||
},
|
||||
|
||||
STEXI
|
||||
@@ -1467,7 +1467,7 @@ ETEXI
|
||||
.args_type = "aclname:s,match:s",
|
||||
.params = "aclname match",
|
||||
.help = "remove a match rule from the access control list",
|
||||
.mhandler.cmd = hmp_acl_remove,
|
||||
.cmd = hmp_acl_remove,
|
||||
},
|
||||
|
||||
STEXI
|
||||
@@ -1481,7 +1481,7 @@ ETEXI
|
||||
.args_type = "aclname:s",
|
||||
.params = "aclname",
|
||||
.help = "reset the access control list",
|
||||
.mhandler.cmd = hmp_acl_reset,
|
||||
.cmd = hmp_acl_reset,
|
||||
},
|
||||
|
||||
STEXI
|
||||
@@ -1496,7 +1496,7 @@ ETEXI
|
||||
.args_type = "all:-a,writable:-w,uri:s",
|
||||
.params = "nbd_server_start [-a] [-w] host:port",
|
||||
.help = "serve block devices on the given host and port",
|
||||
.mhandler.cmd = hmp_nbd_server_start,
|
||||
.cmd = hmp_nbd_server_start,
|
||||
},
|
||||
STEXI
|
||||
@item nbd_server_start @var{host}:@var{port}
|
||||
@@ -1512,7 +1512,7 @@ ETEXI
|
||||
.args_type = "writable:-w,device:B",
|
||||
.params = "nbd_server_add [-w] device",
|
||||
.help = "export a block device via NBD",
|
||||
.mhandler.cmd = hmp_nbd_server_add,
|
||||
.cmd = hmp_nbd_server_add,
|
||||
},
|
||||
STEXI
|
||||
@item nbd_server_add @var{device}
|
||||
@@ -1527,7 +1527,7 @@ ETEXI
|
||||
.args_type = "",
|
||||
.params = "nbd_server_stop",
|
||||
.help = "stop serving block devices using the NBD protocol",
|
||||
.mhandler.cmd = hmp_nbd_server_stop,
|
||||
.cmd = hmp_nbd_server_stop,
|
||||
},
|
||||
STEXI
|
||||
@item nbd_server_stop
|
||||
@@ -1543,7 +1543,7 @@ ETEXI
|
||||
.args_type = "broadcast:-b,cpu_index:i,bank:i,status:l,mcg_status:l,addr:l,misc:l",
|
||||
.params = "[-b] cpu bank status mcgstatus addr misc",
|
||||
.help = "inject a MCE on the given CPU [and broadcast to other CPUs with -b option]",
|
||||
.mhandler.cmd = hmp_mce,
|
||||
.cmd = hmp_mce,
|
||||
},
|
||||
|
||||
#endif
|
||||
@@ -1558,7 +1558,7 @@ ETEXI
|
||||
.args_type = "fdname:s",
|
||||
.params = "getfd name",
|
||||
.help = "receive a file descriptor via SCM rights and assign it a name",
|
||||
.mhandler.cmd = hmp_getfd,
|
||||
.cmd = hmp_getfd,
|
||||
},
|
||||
|
||||
STEXI
|
||||
@@ -1574,7 +1574,7 @@ ETEXI
|
||||
.args_type = "fdname:s",
|
||||
.params = "closefd name",
|
||||
.help = "close a file descriptor previously passed via SCM rights",
|
||||
.mhandler.cmd = hmp_closefd,
|
||||
.cmd = hmp_closefd,
|
||||
},
|
||||
|
||||
STEXI
|
||||
@@ -1590,7 +1590,7 @@ ETEXI
|
||||
.args_type = "device:B,password:s",
|
||||
.params = "block_passwd device password",
|
||||
.help = "set the password of encrypted block devices",
|
||||
.mhandler.cmd = hmp_block_passwd,
|
||||
.cmd = hmp_block_passwd,
|
||||
},
|
||||
|
||||
STEXI
|
||||
@@ -1604,7 +1604,7 @@ ETEXI
|
||||
.args_type = "device:B,bps:l,bps_rd:l,bps_wr:l,iops:l,iops_rd:l,iops_wr:l",
|
||||
.params = "device bps bps_rd bps_wr iops iops_rd iops_wr",
|
||||
.help = "change I/O throttle limits for a block drive",
|
||||
.mhandler.cmd = hmp_block_set_io_throttle,
|
||||
.cmd = hmp_block_set_io_throttle,
|
||||
},
|
||||
|
||||
STEXI
|
||||
@@ -1618,7 +1618,7 @@ ETEXI
|
||||
.args_type = "protocol:s,password:s,connected:s?",
|
||||
.params = "protocol password action-if-connected",
|
||||
.help = "set spice/vnc password",
|
||||
.mhandler.cmd = hmp_set_password,
|
||||
.cmd = hmp_set_password,
|
||||
},
|
||||
|
||||
STEXI
|
||||
@@ -1637,7 +1637,7 @@ ETEXI
|
||||
.args_type = "protocol:s,time:s",
|
||||
.params = "protocol time",
|
||||
.help = "set spice/vnc password expire-time",
|
||||
.mhandler.cmd = hmp_expire_password,
|
||||
.cmd = hmp_expire_password,
|
||||
},
|
||||
|
||||
STEXI
|
||||
@@ -1668,7 +1668,7 @@ ETEXI
|
||||
.args_type = "args:s",
|
||||
.params = "args",
|
||||
.help = "add chardev",
|
||||
.mhandler.cmd = hmp_chardev_add,
|
||||
.cmd = hmp_chardev_add,
|
||||
.command_completion = chardev_add_completion,
|
||||
},
|
||||
|
||||
@@ -1684,7 +1684,7 @@ ETEXI
|
||||
.args_type = "id:s",
|
||||
.params = "id",
|
||||
.help = "remove chardev",
|
||||
.mhandler.cmd = hmp_chardev_remove,
|
||||
.cmd = hmp_chardev_remove,
|
||||
.command_completion = chardev_remove_completion,
|
||||
},
|
||||
|
||||
@@ -1700,7 +1700,7 @@ ETEXI
|
||||
.args_type = "device:B,command:s",
|
||||
.params = "[device] \"[command]\"",
|
||||
.help = "run a qemu-io command on a block device",
|
||||
.mhandler.cmd = hmp_qemu_io,
|
||||
.cmd = hmp_qemu_io,
|
||||
},
|
||||
|
||||
STEXI
|
||||
@@ -1715,7 +1715,7 @@ ETEXI
|
||||
.args_type = "id:i",
|
||||
.params = "id",
|
||||
.help = "add cpu",
|
||||
.mhandler.cmd = hmp_cpu_add,
|
||||
.cmd = hmp_cpu_add,
|
||||
},
|
||||
|
||||
STEXI
|
||||
@@ -1729,7 +1729,7 @@ ETEXI
|
||||
.args_type = "path:s?",
|
||||
.params = "path",
|
||||
.help = "list QOM properties",
|
||||
.mhandler.cmd = hmp_qom_list,
|
||||
.cmd = hmp_qom_list,
|
||||
},
|
||||
|
||||
STEXI
|
||||
@@ -1742,7 +1742,7 @@ ETEXI
|
||||
.args_type = "path:s,property:s,value:s",
|
||||
.params = "path property value",
|
||||
.help = "set QOM property",
|
||||
.mhandler.cmd = hmp_qom_set,
|
||||
.cmd = hmp_qom_set,
|
||||
},
|
||||
|
||||
STEXI
|
||||
@@ -1755,8 +1755,8 @@ ETEXI
|
||||
.args_type = "item:s?",
|
||||
.params = "[subcommand]",
|
||||
.help = "show various information about the system state",
|
||||
.mhandler.cmd = hmp_info_help,
|
||||
.sub_table = info_cmds,
|
||||
.cmd = hmp_info_help,
|
||||
.sub_table = info_cmds,
|
||||
},
|
||||
|
||||
STEXI
|
||||
|
21
hmp.c
21
hmp.c
@@ -1376,7 +1376,7 @@ void hmp_eject(Monitor *mon, const QDict *qdict)
|
||||
const char *device = qdict_get_str(qdict, "device");
|
||||
Error *err = NULL;
|
||||
|
||||
qmp_eject(device, true, force, &err);
|
||||
qmp_eject(true, device, false, NULL, true, force, &err);
|
||||
hmp_handle_error(mon, &err);
|
||||
}
|
||||
|
||||
@@ -1422,8 +1422,9 @@ void hmp_change(Monitor *mon, const QDict *qdict)
|
||||
}
|
||||
}
|
||||
|
||||
qmp_blockdev_change_medium(device, target, !!arg, arg,
|
||||
!!read_only, read_only_mode, &err);
|
||||
qmp_blockdev_change_medium(true, device, false, NULL, target,
|
||||
!!arg, arg, !!read_only, read_only_mode,
|
||||
&err);
|
||||
if (err &&
|
||||
error_get_class(err) == ERROR_CLASS_DEVICE_ENCRYPTED) {
|
||||
error_free(err);
|
||||
@@ -1924,6 +1925,7 @@ void hmp_qemu_io(Monitor *mon, const QDict *qdict)
|
||||
{
|
||||
BlockBackend *blk;
|
||||
BlockBackend *local_blk = NULL;
|
||||
AioContext *aio_context;
|
||||
const char* device = qdict_get_str(qdict, "device");
|
||||
const char* command = qdict_get_str(qdict, "command");
|
||||
Error *err = NULL;
|
||||
@@ -1939,17 +1941,12 @@ void hmp_qemu_io(Monitor *mon, const QDict *qdict)
|
||||
}
|
||||
}
|
||||
|
||||
if (blk) {
|
||||
AioContext *aio_context = blk_get_aio_context(blk);
|
||||
aio_context_acquire(aio_context);
|
||||
aio_context = blk_get_aio_context(blk);
|
||||
aio_context_acquire(aio_context);
|
||||
|
||||
qemuio_command(blk, command);
|
||||
qemuio_command(blk, command);
|
||||
|
||||
aio_context_release(aio_context);
|
||||
} else {
|
||||
error_set(&err, ERROR_CLASS_DEVICE_NOT_FOUND,
|
||||
"Device '%s' not found", device);
|
||||
}
|
||||
aio_context_release(aio_context);
|
||||
|
||||
fail:
|
||||
blk_unref(local_blk);
|
||||
|
@@ -1060,13 +1060,10 @@ static int local_name_to_path(FsContext *ctx, V9fsPath *dir_path,
|
||||
const char *name, V9fsPath *target)
|
||||
{
|
||||
if (dir_path) {
|
||||
v9fs_string_sprintf((V9fsString *)target, "%s/%s",
|
||||
dir_path->data, name);
|
||||
v9fs_path_sprintf(target, "%s/%s", dir_path->data, name);
|
||||
} else {
|
||||
v9fs_string_sprintf((V9fsString *)target, "%s", name);
|
||||
v9fs_path_sprintf(target, "%s", name);
|
||||
}
|
||||
/* Bump the size for including terminating NULL */
|
||||
target->size++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@@ -294,8 +294,7 @@ static int v9fs_receive_status(V9fsProxy *proxy,
|
||||
* This request read by proxy helper process
|
||||
* returns 0 on success and -errno on error
|
||||
*/
|
||||
static int v9fs_request(V9fsProxy *proxy, int type,
|
||||
void *response, const char *fmt, ...)
|
||||
static int v9fs_request(V9fsProxy *proxy, int type, void *response, ...)
|
||||
{
|
||||
dev_t rdev;
|
||||
va_list ap;
|
||||
@@ -317,7 +316,7 @@ static int v9fs_request(V9fsProxy *proxy, int type,
|
||||
}
|
||||
iovec = &proxy->out_iovec;
|
||||
reply = &proxy->in_iovec;
|
||||
va_start(ap, fmt);
|
||||
va_start(ap, response);
|
||||
switch (type) {
|
||||
case T_OPEN:
|
||||
path = va_arg(ap, V9fsString *);
|
||||
@@ -605,7 +604,7 @@ close_error:
|
||||
static int proxy_lstat(FsContext *fs_ctx, V9fsPath *fs_path, struct stat *stbuf)
|
||||
{
|
||||
int retval;
|
||||
retval = v9fs_request(fs_ctx->private, T_LSTAT, stbuf, "s", fs_path);
|
||||
retval = v9fs_request(fs_ctx->private, T_LSTAT, stbuf, fs_path);
|
||||
if (retval < 0) {
|
||||
errno = -retval;
|
||||
return -1;
|
||||
@@ -617,8 +616,7 @@ static ssize_t proxy_readlink(FsContext *fs_ctx, V9fsPath *fs_path,
|
||||
char *buf, size_t bufsz)
|
||||
{
|
||||
int retval;
|
||||
retval = v9fs_request(fs_ctx->private, T_READLINK, buf, "sd",
|
||||
fs_path, bufsz);
|
||||
retval = v9fs_request(fs_ctx->private, T_READLINK, buf, fs_path, bufsz);
|
||||
if (retval < 0) {
|
||||
errno = -retval;
|
||||
return -1;
|
||||
@@ -639,7 +637,7 @@ static int proxy_closedir(FsContext *ctx, V9fsFidOpenState *fs)
|
||||
static int proxy_open(FsContext *ctx, V9fsPath *fs_path,
|
||||
int flags, V9fsFidOpenState *fs)
|
||||
{
|
||||
fs->fd = v9fs_request(ctx->private, T_OPEN, NULL, "sd", fs_path, flags);
|
||||
fs->fd = v9fs_request(ctx->private, T_OPEN, NULL, fs_path, flags);
|
||||
if (fs->fd < 0) {
|
||||
errno = -fs->fd;
|
||||
fs->fd = -1;
|
||||
@@ -653,7 +651,7 @@ static int proxy_opendir(FsContext *ctx,
|
||||
int serrno, fd;
|
||||
|
||||
fs->dir.stream = NULL;
|
||||
fd = v9fs_request(ctx->private, T_OPEN, NULL, "sd", fs_path, O_DIRECTORY);
|
||||
fd = v9fs_request(ctx->private, T_OPEN, NULL, fs_path, O_DIRECTORY);
|
||||
if (fd < 0) {
|
||||
errno = -fd;
|
||||
return -1;
|
||||
@@ -735,8 +733,8 @@ static ssize_t proxy_pwritev(FsContext *ctx, V9fsFidOpenState *fs,
|
||||
static int proxy_chmod(FsContext *fs_ctx, V9fsPath *fs_path, FsCred *credp)
|
||||
{
|
||||
int retval;
|
||||
retval = v9fs_request(fs_ctx->private, T_CHMOD, NULL, "sd",
|
||||
fs_path, credp->fc_mode);
|
||||
retval = v9fs_request(fs_ctx->private, T_CHMOD, NULL, fs_path,
|
||||
credp->fc_mode);
|
||||
if (retval < 0) {
|
||||
errno = -retval;
|
||||
}
|
||||
@@ -752,8 +750,8 @@ static int proxy_mknod(FsContext *fs_ctx, V9fsPath *dir_path,
|
||||
v9fs_string_init(&fullname);
|
||||
v9fs_string_sprintf(&fullname, "%s/%s", dir_path->data, name);
|
||||
|
||||
retval = v9fs_request(fs_ctx->private, T_MKNOD, NULL, "sdqdd",
|
||||
&fullname, credp->fc_mode, credp->fc_rdev,
|
||||
retval = v9fs_request(fs_ctx->private, T_MKNOD, NULL, &fullname,
|
||||
credp->fc_mode, credp->fc_rdev,
|
||||
credp->fc_uid, credp->fc_gid);
|
||||
v9fs_string_free(&fullname);
|
||||
if (retval < 0) {
|
||||
@@ -772,14 +770,13 @@ static int proxy_mkdir(FsContext *fs_ctx, V9fsPath *dir_path,
|
||||
v9fs_string_init(&fullname);
|
||||
v9fs_string_sprintf(&fullname, "%s/%s", dir_path->data, name);
|
||||
|
||||
retval = v9fs_request(fs_ctx->private, T_MKDIR, NULL, "sddd", &fullname,
|
||||
retval = v9fs_request(fs_ctx->private, T_MKDIR, NULL, &fullname,
|
||||
credp->fc_mode, credp->fc_uid, credp->fc_gid);
|
||||
v9fs_string_free(&fullname);
|
||||
if (retval < 0) {
|
||||
errno = -retval;
|
||||
retval = -1;
|
||||
}
|
||||
v9fs_string_free(&fullname);
|
||||
return retval;
|
||||
}
|
||||
|
||||
@@ -804,9 +801,8 @@ static int proxy_open2(FsContext *fs_ctx, V9fsPath *dir_path, const char *name,
|
||||
v9fs_string_init(&fullname);
|
||||
v9fs_string_sprintf(&fullname, "%s/%s", dir_path->data, name);
|
||||
|
||||
fs->fd = v9fs_request(fs_ctx->private, T_CREATE, NULL, "sdddd",
|
||||
&fullname, flags, credp->fc_mode,
|
||||
credp->fc_uid, credp->fc_gid);
|
||||
fs->fd = v9fs_request(fs_ctx->private, T_CREATE, NULL, &fullname, flags,
|
||||
credp->fc_mode, credp->fc_uid, credp->fc_gid);
|
||||
v9fs_string_free(&fullname);
|
||||
if (fs->fd < 0) {
|
||||
errno = -fs->fd;
|
||||
@@ -827,8 +823,8 @@ static int proxy_symlink(FsContext *fs_ctx, const char *oldpath,
|
||||
v9fs_string_sprintf(&fullname, "%s/%s", dir_path->data, name);
|
||||
v9fs_string_sprintf(&target, "%s", oldpath);
|
||||
|
||||
retval = v9fs_request(fs_ctx->private, T_SYMLINK, NULL, "ssdd",
|
||||
&target, &fullname, credp->fc_uid, credp->fc_gid);
|
||||
retval = v9fs_request(fs_ctx->private, T_SYMLINK, NULL, &target, &fullname,
|
||||
credp->fc_uid, credp->fc_gid);
|
||||
v9fs_string_free(&fullname);
|
||||
v9fs_string_free(&target);
|
||||
if (retval < 0) {
|
||||
@@ -847,7 +843,7 @@ static int proxy_link(FsContext *ctx, V9fsPath *oldpath,
|
||||
v9fs_string_init(&newpath);
|
||||
v9fs_string_sprintf(&newpath, "%s/%s", dirpath->data, name);
|
||||
|
||||
retval = v9fs_request(ctx->private, T_LINK, NULL, "ss", oldpath, &newpath);
|
||||
retval = v9fs_request(ctx->private, T_LINK, NULL, oldpath, &newpath);
|
||||
v9fs_string_free(&newpath);
|
||||
if (retval < 0) {
|
||||
errno = -retval;
|
||||
@@ -860,7 +856,7 @@ static int proxy_truncate(FsContext *ctx, V9fsPath *fs_path, off_t size)
|
||||
{
|
||||
int retval;
|
||||
|
||||
retval = v9fs_request(ctx->private, T_TRUNCATE, NULL, "sq", fs_path, size);
|
||||
retval = v9fs_request(ctx->private, T_TRUNCATE, NULL, fs_path, size);
|
||||
if (retval < 0) {
|
||||
errno = -retval;
|
||||
return -1;
|
||||
@@ -879,8 +875,7 @@ static int proxy_rename(FsContext *ctx, const char *oldpath,
|
||||
|
||||
v9fs_string_sprintf(&oldname, "%s", oldpath);
|
||||
v9fs_string_sprintf(&newname, "%s", newpath);
|
||||
retval = v9fs_request(ctx->private, T_RENAME, NULL, "ss",
|
||||
&oldname, &newname);
|
||||
retval = v9fs_request(ctx->private, T_RENAME, NULL, &oldname, &newname);
|
||||
v9fs_string_free(&oldname);
|
||||
v9fs_string_free(&newname);
|
||||
if (retval < 0) {
|
||||
@@ -892,8 +887,8 @@ static int proxy_rename(FsContext *ctx, const char *oldpath,
|
||||
static int proxy_chown(FsContext *fs_ctx, V9fsPath *fs_path, FsCred *credp)
|
||||
{
|
||||
int retval;
|
||||
retval = v9fs_request(fs_ctx->private, T_CHOWN, NULL, "sdd",
|
||||
fs_path, credp->fc_uid, credp->fc_gid);
|
||||
retval = v9fs_request(fs_ctx->private, T_CHOWN, NULL, fs_path,
|
||||
credp->fc_uid, credp->fc_gid);
|
||||
if (retval < 0) {
|
||||
errno = -retval;
|
||||
}
|
||||
@@ -904,8 +899,7 @@ static int proxy_utimensat(FsContext *s, V9fsPath *fs_path,
|
||||
const struct timespec *buf)
|
||||
{
|
||||
int retval;
|
||||
retval = v9fs_request(s->private, T_UTIME, NULL, "sqqqq",
|
||||
fs_path,
|
||||
retval = v9fs_request(s->private, T_UTIME, NULL, fs_path,
|
||||
buf[0].tv_sec, buf[0].tv_nsec,
|
||||
buf[1].tv_sec, buf[1].tv_nsec);
|
||||
if (retval < 0) {
|
||||
@@ -920,7 +914,7 @@ static int proxy_remove(FsContext *ctx, const char *path)
|
||||
V9fsString name;
|
||||
v9fs_string_init(&name);
|
||||
v9fs_string_sprintf(&name, "%s", path);
|
||||
retval = v9fs_request(ctx->private, T_REMOVE, NULL, "s", &name);
|
||||
retval = v9fs_request(ctx->private, T_REMOVE, NULL, &name);
|
||||
v9fs_string_free(&name);
|
||||
if (retval < 0) {
|
||||
errno = -retval;
|
||||
@@ -949,7 +943,7 @@ static int proxy_fsync(FsContext *ctx, int fid_type,
|
||||
static int proxy_statfs(FsContext *s, V9fsPath *fs_path, struct statfs *stbuf)
|
||||
{
|
||||
int retval;
|
||||
retval = v9fs_request(s->private, T_STATFS, stbuf, "s", fs_path);
|
||||
retval = v9fs_request(s->private, T_STATFS, stbuf, fs_path);
|
||||
if (retval < 0) {
|
||||
errno = -retval;
|
||||
return -1;
|
||||
@@ -965,8 +959,8 @@ static ssize_t proxy_lgetxattr(FsContext *ctx, V9fsPath *fs_path,
|
||||
|
||||
v9fs_string_init(&xname);
|
||||
v9fs_string_sprintf(&xname, "%s", name);
|
||||
retval = v9fs_request(ctx->private, T_LGETXATTR, value, "dss", size,
|
||||
fs_path, &xname);
|
||||
retval = v9fs_request(ctx->private, T_LGETXATTR, value, size, fs_path,
|
||||
&xname);
|
||||
v9fs_string_free(&xname);
|
||||
if (retval < 0) {
|
||||
errno = -retval;
|
||||
@@ -978,8 +972,7 @@ static ssize_t proxy_llistxattr(FsContext *ctx, V9fsPath *fs_path,
|
||||
void *value, size_t size)
|
||||
{
|
||||
int retval;
|
||||
retval = v9fs_request(ctx->private, T_LLISTXATTR, value, "ds", size,
|
||||
fs_path);
|
||||
retval = v9fs_request(ctx->private, T_LLISTXATTR, value, size, fs_path);
|
||||
if (retval < 0) {
|
||||
errno = -retval;
|
||||
}
|
||||
@@ -1000,8 +993,8 @@ static int proxy_lsetxattr(FsContext *ctx, V9fsPath *fs_path, const char *name,
|
||||
xvalue.data = g_malloc(size);
|
||||
memcpy(xvalue.data, value, size);
|
||||
|
||||
retval = v9fs_request(ctx->private, T_LSETXATTR, value, "sssdd",
|
||||
fs_path, &xname, &xvalue, size, flags);
|
||||
retval = v9fs_request(ctx->private, T_LSETXATTR, value, fs_path, &xname,
|
||||
&xvalue, size, flags);
|
||||
v9fs_string_free(&xname);
|
||||
v9fs_string_free(&xvalue);
|
||||
if (retval < 0) {
|
||||
@@ -1018,8 +1011,7 @@ static int proxy_lremovexattr(FsContext *ctx, V9fsPath *fs_path,
|
||||
|
||||
v9fs_string_init(&xname);
|
||||
v9fs_string_sprintf(&xname, "%s", name);
|
||||
retval = v9fs_request(ctx->private, T_LREMOVEXATTR, NULL, "ss",
|
||||
fs_path, &xname);
|
||||
retval = v9fs_request(ctx->private, T_LREMOVEXATTR, NULL, fs_path, &xname);
|
||||
v9fs_string_free(&xname);
|
||||
if (retval < 0) {
|
||||
errno = -retval;
|
||||
@@ -1031,13 +1023,10 @@ static int proxy_name_to_path(FsContext *ctx, V9fsPath *dir_path,
|
||||
const char *name, V9fsPath *target)
|
||||
{
|
||||
if (dir_path) {
|
||||
v9fs_string_sprintf((V9fsString *)target, "%s/%s",
|
||||
dir_path->data, name);
|
||||
v9fs_path_sprintf(target, "%s/%s", dir_path->data, name);
|
||||
} else {
|
||||
v9fs_string_sprintf((V9fsString *)target, "%s", name);
|
||||
v9fs_path_sprintf(target, "%s", name);
|
||||
}
|
||||
/* Bump the size for including terminating NULL */
|
||||
target->size++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1086,7 +1075,7 @@ static int proxy_ioc_getversion(FsContext *fs_ctx, V9fsPath *path,
|
||||
errno = ENOTTY;
|
||||
return -1;
|
||||
}
|
||||
err = v9fs_request(fs_ctx->private, T_GETVERSION, st_gen, "s", path);
|
||||
err = v9fs_request(fs_ctx->private, T_GETVERSION, st_gen, path);
|
||||
if (err < 0) {
|
||||
errno = -err;
|
||||
err = -1;
|
||||
|
32
hw/9pfs/9p.c
32
hw/9pfs/9p.c
@@ -12,6 +12,7 @@
|
||||
*/
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include <glib/gprintf.h>
|
||||
#include "hw/virtio/virtio.h"
|
||||
#include "qapi/error.h"
|
||||
#include "qemu/error-report.h"
|
||||
@@ -179,6 +180,20 @@ void v9fs_path_free(V9fsPath *path)
|
||||
path->size = 0;
|
||||
}
|
||||
|
||||
|
||||
void GCC_FMT_ATTR(2, 3)
|
||||
v9fs_path_sprintf(V9fsPath *path, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
v9fs_path_free(path);
|
||||
|
||||
va_start(ap, fmt);
|
||||
/* Bump the size for including terminating NULL */
|
||||
path->size = g_vasprintf(&path->data, fmt, ap) + 1;
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
void v9fs_path_copy(V9fsPath *lhs, V9fsPath *rhs)
|
||||
{
|
||||
v9fs_path_free(lhs);
|
||||
@@ -810,15 +825,15 @@ static int stat_to_v9stat(V9fsPDU *pdu, V9fsPath *name,
|
||||
v9stat->mtime = stbuf->st_mtime;
|
||||
v9stat->length = stbuf->st_size;
|
||||
|
||||
v9fs_string_null(&v9stat->uid);
|
||||
v9fs_string_null(&v9stat->gid);
|
||||
v9fs_string_null(&v9stat->muid);
|
||||
v9fs_string_free(&v9stat->uid);
|
||||
v9fs_string_free(&v9stat->gid);
|
||||
v9fs_string_free(&v9stat->muid);
|
||||
|
||||
v9stat->n_uid = stbuf->st_uid;
|
||||
v9stat->n_gid = stbuf->st_gid;
|
||||
v9stat->n_muid = 0;
|
||||
|
||||
v9fs_string_null(&v9stat->extension);
|
||||
v9fs_string_free(&v9stat->extension);
|
||||
|
||||
if (v9stat->mode & P9_STAT_MODE_SYMLINK) {
|
||||
err = v9fs_co_readlink(pdu, name, &v9stat->extension);
|
||||
@@ -917,10 +932,8 @@ static void v9fs_fix_path(V9fsPath *dst, V9fsPath *src, int len)
|
||||
V9fsPath str;
|
||||
v9fs_path_init(&str);
|
||||
v9fs_path_copy(&str, dst);
|
||||
v9fs_string_sprintf((V9fsString *)dst, "%s%s", src->data, str.data+len);
|
||||
v9fs_path_sprintf(dst, "%s%s", src->data, str.data + len);
|
||||
v9fs_path_free(&str);
|
||||
/* +1 to include terminating NULL */
|
||||
dst->size++;
|
||||
}
|
||||
|
||||
static inline bool is_ro_export(FsContext *ctx)
|
||||
@@ -1320,13 +1333,14 @@ static void v9fs_walk(void *opaque)
|
||||
goto out_nofid;
|
||||
}
|
||||
|
||||
v9fs_path_init(&dpath);
|
||||
v9fs_path_init(&path);
|
||||
|
||||
err = fid_to_qid(pdu, fidp, &qid);
|
||||
if (err < 0) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
v9fs_path_init(&dpath);
|
||||
v9fs_path_init(&path);
|
||||
/*
|
||||
* Both dpath and path initially poin to fidp.
|
||||
* Needed to handle request with nwnames == 0
|
||||
|
@@ -327,6 +327,7 @@ static inline uint8_t v9fs_request_cancelled(V9fsPDU *pdu)
|
||||
extern void v9fs_reclaim_fd(V9fsPDU *pdu);
|
||||
extern void v9fs_path_init(V9fsPath *path);
|
||||
extern void v9fs_path_free(V9fsPath *path);
|
||||
extern void v9fs_path_sprintf(V9fsPath *path, const char *fmt, ...);
|
||||
extern void v9fs_path_copy(V9fsPath *lhs, V9fsPath *rhs);
|
||||
extern int v9fs_name_to_path(V9fsState *s, V9fsPath *dirpath,
|
||||
const char *name, V9fsPath *path);
|
||||
|
@@ -226,7 +226,7 @@ static void build_extop_package(GArray *package, uint8_t op)
|
||||
build_prepend_byte(package, 0x5B); /* ExtOpPrefix */
|
||||
}
|
||||
|
||||
static void build_append_int_noprefix(GArray *table, uint64_t value, int size)
|
||||
void build_append_int_noprefix(GArray *table, uint64_t value, int size)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
@@ -17,4 +17,4 @@ obj-$(CONFIG_XLNX_ZYNQMP) += xlnx-zynqmp.o xlnx-ep108.o
|
||||
obj-$(CONFIG_FSL_IMX25) += fsl-imx25.o imx25_pdk.o
|
||||
obj-$(CONFIG_FSL_IMX31) += fsl-imx31.o kzm.o
|
||||
obj-$(CONFIG_FSL_IMX6) += fsl-imx6.o sabrelite.o
|
||||
obj-$(CONFIG_ASPEED_SOC) += ast2400.o palmetto-bmc.o
|
||||
obj-$(CONFIG_ASPEED_SOC) += aspeed_soc.o aspeed.o
|
||||
|
197
hw/arm/aspeed.c
Normal file
197
hw/arm/aspeed.c
Normal file
@@ -0,0 +1,197 @@
|
||||
/*
|
||||
* OpenPOWER Palmetto BMC
|
||||
*
|
||||
* Andrew Jeffery <andrew@aj.id.au>
|
||||
*
|
||||
* Copyright 2016 IBM Corp.
|
||||
*
|
||||
* This code is licensed under the GPL version 2 or later. See
|
||||
* the COPYING file in the top-level directory.
|
||||
*/
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include "qapi/error.h"
|
||||
#include "qemu-common.h"
|
||||
#include "cpu.h"
|
||||
#include "exec/address-spaces.h"
|
||||
#include "hw/arm/arm.h"
|
||||
#include "hw/arm/aspeed_soc.h"
|
||||
#include "hw/boards.h"
|
||||
#include "qemu/log.h"
|
||||
#include "sysemu/block-backend.h"
|
||||
#include "sysemu/blockdev.h"
|
||||
|
||||
static struct arm_boot_info aspeed_board_binfo = {
|
||||
.board_id = -1, /* device-tree-only board */
|
||||
.nb_cpus = 1,
|
||||
};
|
||||
|
||||
typedef struct AspeedBoardState {
|
||||
AspeedSoCState soc;
|
||||
MemoryRegion ram;
|
||||
} AspeedBoardState;
|
||||
|
||||
typedef struct AspeedBoardConfig {
|
||||
const char *soc_name;
|
||||
uint32_t hw_strap1;
|
||||
} AspeedBoardConfig;
|
||||
|
||||
enum {
|
||||
PALMETTO_BMC,
|
||||
AST2500_EVB,
|
||||
};
|
||||
|
||||
#define PALMETTO_BMC_HW_STRAP1 ( \
|
||||
SCU_AST2400_HW_STRAP_DRAM_SIZE(DRAM_SIZE_256MB) | \
|
||||
SCU_AST2400_HW_STRAP_DRAM_CONFIG(2 /* DDR3 with CL=6, CWL=5 */) | \
|
||||
SCU_AST2400_HW_STRAP_ACPI_DIS | \
|
||||
SCU_AST2400_HW_STRAP_SET_CLK_SOURCE(AST2400_CLK_48M_IN) | \
|
||||
SCU_HW_STRAP_VGA_CLASS_CODE | \
|
||||
SCU_HW_STRAP_LPC_RESET_PIN | \
|
||||
SCU_HW_STRAP_SPI_MODE(SCU_HW_STRAP_SPI_M_S_EN) | \
|
||||
SCU_AST2400_HW_STRAP_SET_CPU_AHB_RATIO(AST2400_CPU_AHB_RATIO_2_1) | \
|
||||
SCU_HW_STRAP_SPI_WIDTH | \
|
||||
SCU_HW_STRAP_VGA_SIZE_SET(VGA_16M_DRAM) | \
|
||||
SCU_AST2400_HW_STRAP_BOOT_MODE(AST2400_SPI_BOOT))
|
||||
|
||||
#define AST2500_EVB_HW_STRAP1 (( \
|
||||
AST2500_HW_STRAP1_DEFAULTS | \
|
||||
SCU_AST2500_HW_STRAP_SPI_AUTOFETCH_ENABLE | \
|
||||
SCU_AST2500_HW_STRAP_GPIO_STRAP_ENABLE | \
|
||||
SCU_AST2500_HW_STRAP_UART_DEBUG | \
|
||||
SCU_AST2500_HW_STRAP_DDR4_ENABLE | \
|
||||
SCU_HW_STRAP_MAC1_RGMII | \
|
||||
SCU_HW_STRAP_MAC0_RGMII) & \
|
||||
~SCU_HW_STRAP_2ND_BOOT_WDT)
|
||||
|
||||
static const AspeedBoardConfig aspeed_boards[] = {
|
||||
[PALMETTO_BMC] = { "ast2400-a0", PALMETTO_BMC_HW_STRAP1 },
|
||||
[AST2500_EVB] = { "ast2500-a1", AST2500_EVB_HW_STRAP1 },
|
||||
};
|
||||
|
||||
static void aspeed_board_init_flashes(AspeedSMCState *s, const char *flashtype,
|
||||
Error **errp)
|
||||
{
|
||||
int i ;
|
||||
|
||||
for (i = 0; i < s->num_cs; ++i) {
|
||||
AspeedSMCFlash *fl = &s->flashes[i];
|
||||
DriveInfo *dinfo = drive_get_next(IF_MTD);
|
||||
qemu_irq cs_line;
|
||||
|
||||
/*
|
||||
* FIXME: check that we are not using a flash module exceeding
|
||||
* the controller segment size
|
||||
*/
|
||||
fl->flash = ssi_create_slave_no_init(s->spi, flashtype);
|
||||
if (dinfo) {
|
||||
qdev_prop_set_drive(fl->flash, "drive", blk_by_legacy_dinfo(dinfo),
|
||||
errp);
|
||||
}
|
||||
qdev_init_nofail(fl->flash);
|
||||
|
||||
cs_line = qdev_get_gpio_in_named(fl->flash, SSI_GPIO_CS, 0);
|
||||
sysbus_connect_irq(SYS_BUS_DEVICE(s), i + 1, cs_line);
|
||||
}
|
||||
}
|
||||
|
||||
static void aspeed_board_init(MachineState *machine,
|
||||
const AspeedBoardConfig *cfg)
|
||||
{
|
||||
AspeedBoardState *bmc;
|
||||
AspeedSoCClass *sc;
|
||||
|
||||
bmc = g_new0(AspeedBoardState, 1);
|
||||
object_initialize(&bmc->soc, (sizeof(bmc->soc)), cfg->soc_name);
|
||||
object_property_add_child(OBJECT(machine), "soc", OBJECT(&bmc->soc),
|
||||
&error_abort);
|
||||
|
||||
sc = ASPEED_SOC_GET_CLASS(&bmc->soc);
|
||||
|
||||
object_property_set_int(OBJECT(&bmc->soc), ram_size, "ram-size",
|
||||
&error_abort);
|
||||
object_property_set_int(OBJECT(&bmc->soc), cfg->hw_strap1, "hw-strap1",
|
||||
&error_abort);
|
||||
object_property_set_bool(OBJECT(&bmc->soc), true, "realized",
|
||||
&error_abort);
|
||||
|
||||
/*
|
||||
* Allocate RAM after the memory controller has checked the size
|
||||
* was valid. If not, a default value is used.
|
||||
*/
|
||||
ram_size = object_property_get_int(OBJECT(&bmc->soc), "ram-size",
|
||||
&error_abort);
|
||||
|
||||
memory_region_allocate_system_memory(&bmc->ram, NULL, "ram", ram_size);
|
||||
memory_region_add_subregion(get_system_memory(), sc->info->sdram_base,
|
||||
&bmc->ram);
|
||||
object_property_add_const_link(OBJECT(&bmc->soc), "ram", OBJECT(&bmc->ram),
|
||||
&error_abort);
|
||||
|
||||
aspeed_board_init_flashes(&bmc->soc.smc, "n25q256a", &error_abort);
|
||||
aspeed_board_init_flashes(&bmc->soc.spi, "mx25l25635e", &error_abort);
|
||||
|
||||
aspeed_board_binfo.kernel_filename = machine->kernel_filename;
|
||||
aspeed_board_binfo.initrd_filename = machine->initrd_filename;
|
||||
aspeed_board_binfo.kernel_cmdline = machine->kernel_cmdline;
|
||||
aspeed_board_binfo.ram_size = ram_size;
|
||||
aspeed_board_binfo.loader_start = sc->info->sdram_base;
|
||||
|
||||
arm_load_kernel(ARM_CPU(first_cpu), &aspeed_board_binfo);
|
||||
}
|
||||
|
||||
static void palmetto_bmc_init(MachineState *machine)
|
||||
{
|
||||
aspeed_board_init(machine, &aspeed_boards[PALMETTO_BMC]);
|
||||
}
|
||||
|
||||
static void palmetto_bmc_class_init(ObjectClass *oc, void *data)
|
||||
{
|
||||
MachineClass *mc = MACHINE_CLASS(oc);
|
||||
|
||||
mc->desc = "OpenPOWER Palmetto BMC (ARM926EJ-S)";
|
||||
mc->init = palmetto_bmc_init;
|
||||
mc->max_cpus = 1;
|
||||
mc->no_sdcard = 1;
|
||||
mc->no_floppy = 1;
|
||||
mc->no_cdrom = 1;
|
||||
mc->no_parallel = 1;
|
||||
}
|
||||
|
||||
static const TypeInfo palmetto_bmc_type = {
|
||||
.name = MACHINE_TYPE_NAME("palmetto-bmc"),
|
||||
.parent = TYPE_MACHINE,
|
||||
.class_init = palmetto_bmc_class_init,
|
||||
};
|
||||
|
||||
static void ast2500_evb_init(MachineState *machine)
|
||||
{
|
||||
aspeed_board_init(machine, &aspeed_boards[AST2500_EVB]);
|
||||
}
|
||||
|
||||
static void ast2500_evb_class_init(ObjectClass *oc, void *data)
|
||||
{
|
||||
MachineClass *mc = MACHINE_CLASS(oc);
|
||||
|
||||
mc->desc = "Aspeed AST2500 EVB (ARM1176)";
|
||||
mc->init = ast2500_evb_init;
|
||||
mc->max_cpus = 1;
|
||||
mc->no_sdcard = 1;
|
||||
mc->no_floppy = 1;
|
||||
mc->no_cdrom = 1;
|
||||
mc->no_parallel = 1;
|
||||
}
|
||||
|
||||
static const TypeInfo ast2500_evb_type = {
|
||||
.name = MACHINE_TYPE_NAME("ast2500-evb"),
|
||||
.parent = TYPE_MACHINE,
|
||||
.class_init = ast2500_evb_class_init,
|
||||
};
|
||||
|
||||
static void aspeed_machine_init(void)
|
||||
{
|
||||
type_register_static(&palmetto_bmc_type);
|
||||
type_register_static(&ast2500_evb_type);
|
||||
}
|
||||
|
||||
type_init(aspeed_machine_init)
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* AST2400 SoC
|
||||
* ASPEED SoC family
|
||||
*
|
||||
* Andrew Jeffery <andrew@aj.id.au>
|
||||
* Jeremy Kerr <jk@ozlabs.org>
|
||||
@@ -15,59 +15,68 @@
|
||||
#include "qemu-common.h"
|
||||
#include "cpu.h"
|
||||
#include "exec/address-spaces.h"
|
||||
#include "hw/arm/ast2400.h"
|
||||
#include "hw/arm/aspeed_soc.h"
|
||||
#include "hw/char/serial.h"
|
||||
#include "qemu/log.h"
|
||||
#include "hw/i2c/aspeed_i2c.h"
|
||||
|
||||
#define AST2400_UART_5_BASE 0x00184000
|
||||
#define AST2400_IOMEM_SIZE 0x00200000
|
||||
#define AST2400_IOMEM_BASE 0x1E600000
|
||||
#define AST2400_SMC_BASE AST2400_IOMEM_BASE /* Legacy SMC */
|
||||
#define AST2400_FMC_BASE 0X1E620000
|
||||
#define AST2400_SPI_BASE 0X1E630000
|
||||
#define AST2400_VIC_BASE 0x1E6C0000
|
||||
#define AST2400_SDMC_BASE 0x1E6E0000
|
||||
#define AST2400_SCU_BASE 0x1E6E2000
|
||||
#define AST2400_TIMER_BASE 0x1E782000
|
||||
#define AST2400_I2C_BASE 0x1E78A000
|
||||
#define ASPEED_SOC_UART_5_BASE 0x00184000
|
||||
#define ASPEED_SOC_IOMEM_SIZE 0x00200000
|
||||
#define ASPEED_SOC_IOMEM_BASE 0x1E600000
|
||||
#define ASPEED_SOC_FMC_BASE 0x1E620000
|
||||
#define ASPEED_SOC_SPI_BASE 0x1E630000
|
||||
#define ASPEED_SOC_VIC_BASE 0x1E6C0000
|
||||
#define ASPEED_SOC_SDMC_BASE 0x1E6E0000
|
||||
#define ASPEED_SOC_SCU_BASE 0x1E6E2000
|
||||
#define ASPEED_SOC_TIMER_BASE 0x1E782000
|
||||
#define ASPEED_SOC_I2C_BASE 0x1E78A000
|
||||
|
||||
#define AST2400_FMC_FLASH_BASE 0x20000000
|
||||
#define AST2400_SPI_FLASH_BASE 0x30000000
|
||||
#define ASPEED_SOC_FMC_FLASH_BASE 0x20000000
|
||||
#define ASPEED_SOC_SPI_FLASH_BASE 0x30000000
|
||||
|
||||
static const int uart_irqs[] = { 9, 32, 33, 34, 10 };
|
||||
static const int timer_irqs[] = { 16, 17, 18, 35, 36, 37, 38, 39, };
|
||||
|
||||
#define AST2400_SDRAM_BASE 0x40000000
|
||||
#define AST2500_SDRAM_BASE 0x80000000
|
||||
|
||||
static const AspeedSoCInfo aspeed_socs[] = {
|
||||
{ "ast2400-a0", "arm926", AST2400_A0_SILICON_REV, AST2400_SDRAM_BASE },
|
||||
{ "ast2400", "arm926", AST2400_A0_SILICON_REV, AST2400_SDRAM_BASE },
|
||||
{ "ast2500-a1", "arm1176", AST2500_A1_SILICON_REV, AST2500_SDRAM_BASE },
|
||||
};
|
||||
|
||||
/*
|
||||
* IO handlers: simply catch any reads/writes to IO addresses that aren't
|
||||
* handled by a device mapping.
|
||||
*/
|
||||
|
||||
static uint64_t ast2400_io_read(void *p, hwaddr offset, unsigned size)
|
||||
static uint64_t aspeed_soc_io_read(void *p, hwaddr offset, unsigned size)
|
||||
{
|
||||
qemu_log_mask(LOG_UNIMP, "%s: 0x%" HWADDR_PRIx " [%u]\n",
|
||||
__func__, offset, size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void ast2400_io_write(void *opaque, hwaddr offset, uint64_t value,
|
||||
static void aspeed_soc_io_write(void *opaque, hwaddr offset, uint64_t value,
|
||||
unsigned size)
|
||||
{
|
||||
qemu_log_mask(LOG_UNIMP, "%s: 0x%" HWADDR_PRIx " <- 0x%" PRIx64 " [%u]\n",
|
||||
__func__, offset, value, size);
|
||||
}
|
||||
|
||||
static const MemoryRegionOps ast2400_io_ops = {
|
||||
.read = ast2400_io_read,
|
||||
.write = ast2400_io_write,
|
||||
static const MemoryRegionOps aspeed_soc_io_ops = {
|
||||
.read = aspeed_soc_io_read,
|
||||
.write = aspeed_soc_io_write,
|
||||
.endianness = DEVICE_LITTLE_ENDIAN,
|
||||
};
|
||||
|
||||
static void ast2400_init(Object *obj)
|
||||
static void aspeed_soc_init(Object *obj)
|
||||
{
|
||||
AST2400State *s = AST2400(obj);
|
||||
AspeedSoCState *s = ASPEED_SOC(obj);
|
||||
AspeedSoCClass *sc = ASPEED_SOC_GET_CLASS(s);
|
||||
|
||||
s->cpu = cpu_arm_init("arm926");
|
||||
s->cpu = cpu_arm_init(sc->info->cpu_model);
|
||||
|
||||
object_initialize(&s->vic, sizeof(s->vic), TYPE_ASPEED_VIC);
|
||||
object_property_add_child(obj, "vic", OBJECT(&s->vic), NULL);
|
||||
@@ -85,7 +94,7 @@ static void ast2400_init(Object *obj)
|
||||
object_property_add_child(obj, "scu", OBJECT(&s->scu), NULL);
|
||||
qdev_set_parent_bus(DEVICE(&s->scu), sysbus_get_default());
|
||||
qdev_prop_set_uint32(DEVICE(&s->scu), "silicon-rev",
|
||||
AST2400_A0_SILICON_REV);
|
||||
sc->info->silicon_rev);
|
||||
object_property_add_alias(obj, "hw-strap1", OBJECT(&s->scu),
|
||||
"hw-strap1", &error_abort);
|
||||
object_property_add_alias(obj, "hw-strap2", OBJECT(&s->scu),
|
||||
@@ -103,20 +112,22 @@ static void ast2400_init(Object *obj)
|
||||
object_property_add_child(obj, "sdmc", OBJECT(&s->sdmc), NULL);
|
||||
qdev_set_parent_bus(DEVICE(&s->sdmc), sysbus_get_default());
|
||||
qdev_prop_set_uint32(DEVICE(&s->sdmc), "silicon-rev",
|
||||
AST2400_A0_SILICON_REV);
|
||||
sc->info->silicon_rev);
|
||||
object_property_add_alias(obj, "ram-size", OBJECT(&s->sdmc),
|
||||
"ram-size", &error_abort);
|
||||
}
|
||||
|
||||
static void ast2400_realize(DeviceState *dev, Error **errp)
|
||||
static void aspeed_soc_realize(DeviceState *dev, Error **errp)
|
||||
{
|
||||
int i;
|
||||
AST2400State *s = AST2400(dev);
|
||||
AspeedSoCState *s = ASPEED_SOC(dev);
|
||||
Error *err = NULL, *local_err = NULL;
|
||||
|
||||
/* IO space */
|
||||
memory_region_init_io(&s->iomem, NULL, &ast2400_io_ops, NULL,
|
||||
"ast2400.io", AST2400_IOMEM_SIZE);
|
||||
memory_region_add_subregion_overlap(get_system_memory(), AST2400_IOMEM_BASE,
|
||||
&s->iomem, -1);
|
||||
memory_region_init_io(&s->iomem, NULL, &aspeed_soc_io_ops, NULL,
|
||||
"aspeed_soc.io", ASPEED_SOC_IOMEM_SIZE);
|
||||
memory_region_add_subregion_overlap(get_system_memory(),
|
||||
ASPEED_SOC_IOMEM_BASE, &s->iomem, -1);
|
||||
|
||||
/* VIC */
|
||||
object_property_set_bool(OBJECT(&s->vic), true, "realized", &err);
|
||||
@@ -124,7 +135,7 @@ static void ast2400_realize(DeviceState *dev, Error **errp)
|
||||
error_propagate(errp, err);
|
||||
return;
|
||||
}
|
||||
sysbus_mmio_map(SYS_BUS_DEVICE(&s->vic), 0, AST2400_VIC_BASE);
|
||||
sysbus_mmio_map(SYS_BUS_DEVICE(&s->vic), 0, ASPEED_SOC_VIC_BASE);
|
||||
sysbus_connect_irq(SYS_BUS_DEVICE(&s->vic), 0,
|
||||
qdev_get_gpio_in(DEVICE(s->cpu), ARM_CPU_IRQ));
|
||||
sysbus_connect_irq(SYS_BUS_DEVICE(&s->vic), 1,
|
||||
@@ -136,7 +147,7 @@ static void ast2400_realize(DeviceState *dev, Error **errp)
|
||||
error_propagate(errp, err);
|
||||
return;
|
||||
}
|
||||
sysbus_mmio_map(SYS_BUS_DEVICE(&s->timerctrl), 0, AST2400_TIMER_BASE);
|
||||
sysbus_mmio_map(SYS_BUS_DEVICE(&s->timerctrl), 0, ASPEED_SOC_TIMER_BASE);
|
||||
for (i = 0; i < ARRAY_SIZE(timer_irqs); i++) {
|
||||
qemu_irq irq = qdev_get_gpio_in(DEVICE(&s->vic), timer_irqs[i]);
|
||||
sysbus_connect_irq(SYS_BUS_DEVICE(&s->timerctrl), i, irq);
|
||||
@@ -148,12 +159,12 @@ static void ast2400_realize(DeviceState *dev, Error **errp)
|
||||
error_propagate(errp, err);
|
||||
return;
|
||||
}
|
||||
sysbus_mmio_map(SYS_BUS_DEVICE(&s->scu), 0, AST2400_SCU_BASE);
|
||||
sysbus_mmio_map(SYS_BUS_DEVICE(&s->scu), 0, ASPEED_SOC_SCU_BASE);
|
||||
|
||||
/* UART - attach an 8250 to the IO space as our UART5 */
|
||||
if (serial_hds[0]) {
|
||||
qemu_irq uart5 = qdev_get_gpio_in(DEVICE(&s->vic), uart_irqs[4]);
|
||||
serial_mm_init(&s->iomem, AST2400_UART_5_BASE, 2,
|
||||
serial_mm_init(&s->iomem, ASPEED_SOC_UART_5_BASE, 2,
|
||||
uart5, 38400, serial_hds[0], DEVICE_LITTLE_ENDIAN);
|
||||
}
|
||||
|
||||
@@ -163,7 +174,7 @@ static void ast2400_realize(DeviceState *dev, Error **errp)
|
||||
error_propagate(errp, err);
|
||||
return;
|
||||
}
|
||||
sysbus_mmio_map(SYS_BUS_DEVICE(&s->i2c), 0, AST2400_I2C_BASE);
|
||||
sysbus_mmio_map(SYS_BUS_DEVICE(&s->i2c), 0, ASPEED_SOC_I2C_BASE);
|
||||
sysbus_connect_irq(SYS_BUS_DEVICE(&s->i2c), 0,
|
||||
qdev_get_gpio_in(DEVICE(&s->vic), 12));
|
||||
|
||||
@@ -175,8 +186,8 @@ static void ast2400_realize(DeviceState *dev, Error **errp)
|
||||
error_propagate(errp, err);
|
||||
return;
|
||||
}
|
||||
sysbus_mmio_map(SYS_BUS_DEVICE(&s->smc), 0, AST2400_FMC_BASE);
|
||||
sysbus_mmio_map(SYS_BUS_DEVICE(&s->smc), 1, AST2400_FMC_FLASH_BASE);
|
||||
sysbus_mmio_map(SYS_BUS_DEVICE(&s->smc), 0, ASPEED_SOC_FMC_BASE);
|
||||
sysbus_mmio_map(SYS_BUS_DEVICE(&s->smc), 1, ASPEED_SOC_FMC_FLASH_BASE);
|
||||
sysbus_connect_irq(SYS_BUS_DEVICE(&s->smc), 0,
|
||||
qdev_get_gpio_in(DEVICE(&s->vic), 19));
|
||||
|
||||
@@ -188,8 +199,8 @@ static void ast2400_realize(DeviceState *dev, Error **errp)
|
||||
error_propagate(errp, err);
|
||||
return;
|
||||
}
|
||||
sysbus_mmio_map(SYS_BUS_DEVICE(&s->spi), 0, AST2400_SPI_BASE);
|
||||
sysbus_mmio_map(SYS_BUS_DEVICE(&s->spi), 1, AST2400_SPI_FLASH_BASE);
|
||||
sysbus_mmio_map(SYS_BUS_DEVICE(&s->spi), 0, ASPEED_SOC_SPI_BASE);
|
||||
sysbus_mmio_map(SYS_BUS_DEVICE(&s->spi), 1, ASPEED_SOC_SPI_FLASH_BASE);
|
||||
|
||||
/* SDMC - SDRAM Memory Controller */
|
||||
object_property_set_bool(OBJECT(&s->sdmc), true, "realized", &err);
|
||||
@@ -197,14 +208,16 @@ static void ast2400_realize(DeviceState *dev, Error **errp)
|
||||
error_propagate(errp, err);
|
||||
return;
|
||||
}
|
||||
sysbus_mmio_map(SYS_BUS_DEVICE(&s->sdmc), 0, AST2400_SDMC_BASE);
|
||||
sysbus_mmio_map(SYS_BUS_DEVICE(&s->sdmc), 0, ASPEED_SOC_SDMC_BASE);
|
||||
}
|
||||
|
||||
static void ast2400_class_init(ObjectClass *oc, void *data)
|
||||
static void aspeed_soc_class_init(ObjectClass *oc, void *data)
|
||||
{
|
||||
DeviceClass *dc = DEVICE_CLASS(oc);
|
||||
AspeedSoCClass *sc = ASPEED_SOC_CLASS(oc);
|
||||
|
||||
dc->realize = ast2400_realize;
|
||||
sc->info = (AspeedSoCInfo *) data;
|
||||
dc->realize = aspeed_soc_realize;
|
||||
|
||||
/*
|
||||
* Reason: creates an ARM CPU, thus use after free(), see
|
||||
@@ -213,17 +226,29 @@ static void ast2400_class_init(ObjectClass *oc, void *data)
|
||||
dc->cannot_destroy_with_object_finalize_yet = true;
|
||||
}
|
||||
|
||||
static const TypeInfo ast2400_type_info = {
|
||||
.name = TYPE_AST2400,
|
||||
.parent = TYPE_SYS_BUS_DEVICE,
|
||||
.instance_size = sizeof(AST2400State),
|
||||
.instance_init = ast2400_init,
|
||||
.class_init = ast2400_class_init,
|
||||
static const TypeInfo aspeed_soc_type_info = {
|
||||
.name = TYPE_ASPEED_SOC,
|
||||
.parent = TYPE_DEVICE,
|
||||
.instance_init = aspeed_soc_init,
|
||||
.instance_size = sizeof(AspeedSoCState),
|
||||
.class_size = sizeof(AspeedSoCClass),
|
||||
.abstract = true,
|
||||
};
|
||||
|
||||
static void ast2400_register_types(void)
|
||||
static void aspeed_soc_register_types(void)
|
||||
{
|
||||
type_register_static(&ast2400_type_info);
|
||||
int i;
|
||||
|
||||
type_register_static(&aspeed_soc_type_info);
|
||||
for (i = 0; i < ARRAY_SIZE(aspeed_socs); ++i) {
|
||||
TypeInfo ti = {
|
||||
.name = aspeed_socs[i].name,
|
||||
.parent = TYPE_ASPEED_SOC,
|
||||
.class_init = aspeed_soc_class_init,
|
||||
.class_data = (void *) &aspeed_socs[i],
|
||||
};
|
||||
type_register(&ti);
|
||||
}
|
||||
}
|
||||
|
||||
type_init(ast2400_register_types)
|
||||
type_init(aspeed_soc_register_types)
|
@@ -837,7 +837,7 @@ static void mv88w8618_timer_init(SysBusDevice *dev, mv88w8618_timer_state *s,
|
||||
s->freq = freq;
|
||||
|
||||
bh = qemu_bh_new(mv88w8618_timer_tick, s);
|
||||
s->ptimer = ptimer_init(bh);
|
||||
s->ptimer = ptimer_init(bh, PTIMER_POLICY_DEFAULT);
|
||||
}
|
||||
|
||||
static uint64_t mv88w8618_pit_read(void *opaque, hwaddr offset,
|
||||
|
@@ -1,102 +0,0 @@
|
||||
/*
|
||||
* OpenPOWER Palmetto BMC
|
||||
*
|
||||
* Andrew Jeffery <andrew@aj.id.au>
|
||||
*
|
||||
* Copyright 2016 IBM Corp.
|
||||
*
|
||||
* This code is licensed under the GPL version 2 or later. See
|
||||
* the COPYING file in the top-level directory.
|
||||
*/
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include "qapi/error.h"
|
||||
#include "qemu-common.h"
|
||||
#include "cpu.h"
|
||||
#include "exec/address-spaces.h"
|
||||
#include "hw/arm/arm.h"
|
||||
#include "hw/arm/ast2400.h"
|
||||
#include "hw/boards.h"
|
||||
#include "qemu/log.h"
|
||||
#include "sysemu/block-backend.h"
|
||||
#include "sysemu/blockdev.h"
|
||||
|
||||
static struct arm_boot_info palmetto_bmc_binfo = {
|
||||
.loader_start = AST2400_SDRAM_BASE,
|
||||
.board_id = 0,
|
||||
.nb_cpus = 1,
|
||||
};
|
||||
|
||||
typedef struct PalmettoBMCState {
|
||||
AST2400State soc;
|
||||
MemoryRegion ram;
|
||||
} PalmettoBMCState;
|
||||
|
||||
static void palmetto_bmc_init_flashes(AspeedSMCState *s, const char *flashtype,
|
||||
Error **errp)
|
||||
{
|
||||
int i ;
|
||||
|
||||
for (i = 0; i < s->num_cs; ++i) {
|
||||
AspeedSMCFlash *fl = &s->flashes[i];
|
||||
DriveInfo *dinfo = drive_get_next(IF_MTD);
|
||||
qemu_irq cs_line;
|
||||
|
||||
/*
|
||||
* FIXME: check that we are not using a flash module exceeding
|
||||
* the controller segment size
|
||||
*/
|
||||
fl->flash = ssi_create_slave_no_init(s->spi, flashtype);
|
||||
if (dinfo) {
|
||||
qdev_prop_set_drive(fl->flash, "drive", blk_by_legacy_dinfo(dinfo),
|
||||
errp);
|
||||
}
|
||||
qdev_init_nofail(fl->flash);
|
||||
|
||||
cs_line = qdev_get_gpio_in_named(fl->flash, SSI_GPIO_CS, 0);
|
||||
sysbus_connect_irq(SYS_BUS_DEVICE(s), i + 1, cs_line);
|
||||
}
|
||||
}
|
||||
|
||||
static void palmetto_bmc_init(MachineState *machine)
|
||||
{
|
||||
PalmettoBMCState *bmc;
|
||||
|
||||
bmc = g_new0(PalmettoBMCState, 1);
|
||||
object_initialize(&bmc->soc, (sizeof(bmc->soc)), TYPE_AST2400);
|
||||
object_property_add_child(OBJECT(machine), "soc", OBJECT(&bmc->soc),
|
||||
&error_abort);
|
||||
|
||||
memory_region_allocate_system_memory(&bmc->ram, NULL, "ram", ram_size);
|
||||
memory_region_add_subregion(get_system_memory(), AST2400_SDRAM_BASE,
|
||||
&bmc->ram);
|
||||
object_property_add_const_link(OBJECT(&bmc->soc), "ram", OBJECT(&bmc->ram),
|
||||
&error_abort);
|
||||
object_property_set_int(OBJECT(&bmc->soc), 0x120CE416, "hw-strap1",
|
||||
&error_abort);
|
||||
object_property_set_bool(OBJECT(&bmc->soc), true, "realized",
|
||||
&error_abort);
|
||||
|
||||
palmetto_bmc_init_flashes(&bmc->soc.smc, "n25q256a", &error_abort);
|
||||
palmetto_bmc_init_flashes(&bmc->soc.spi, "mx25l25635e", &error_abort);
|
||||
|
||||
palmetto_bmc_binfo.kernel_filename = machine->kernel_filename;
|
||||
palmetto_bmc_binfo.initrd_filename = machine->initrd_filename;
|
||||
palmetto_bmc_binfo.kernel_cmdline = machine->kernel_cmdline;
|
||||
palmetto_bmc_binfo.ram_size = ram_size;
|
||||
arm_load_kernel(ARM_CPU(first_cpu), &palmetto_bmc_binfo);
|
||||
}
|
||||
|
||||
static void palmetto_bmc_machine_init(MachineClass *mc)
|
||||
{
|
||||
mc->desc = "OpenPOWER Palmetto BMC";
|
||||
mc->init = palmetto_bmc_init;
|
||||
mc->max_cpus = 1;
|
||||
mc->no_sdcard = 1;
|
||||
mc->no_floppy = 1;
|
||||
mc->no_cdrom = 1;
|
||||
mc->no_sdcard = 1;
|
||||
mc->no_parallel = 1;
|
||||
}
|
||||
|
||||
DEFINE_MACHINE("palmetto-bmc", palmetto_bmc_machine_init);
|
@@ -332,6 +332,8 @@ static void xlnx_zynqmp_realize(DeviceState *dev, Error **errp)
|
||||
qemu_check_nic_model(nd, TYPE_CADENCE_GEM);
|
||||
qdev_set_nic_properties(DEVICE(&s->gem[i]), nd);
|
||||
}
|
||||
object_property_set_int(OBJECT(&s->gem[i]), 2, "num-priority-queues",
|
||||
&error_abort);
|
||||
object_property_set_bool(OBJECT(&s->gem[i]), true, "realized", &err);
|
||||
if (err) {
|
||||
error_propagate(errp, err);
|
||||
|
@@ -52,8 +52,8 @@ typedef struct {
|
||||
unsigned int pit_count;
|
||||
unsigned int samples;
|
||||
unsigned int play_pos;
|
||||
int data_on;
|
||||
int dummy_refresh_clock;
|
||||
uint8_t data_on;
|
||||
uint8_t dummy_refresh_clock;
|
||||
} PCSpkState;
|
||||
|
||||
static const char *s_spk = "pcspk";
|
||||
@@ -187,6 +187,18 @@ static void pcspk_realizefn(DeviceState *dev, Error **errp)
|
||||
pcspk_state = s;
|
||||
}
|
||||
|
||||
static const VMStateDescription vmstate_spk = {
|
||||
.name = "pcspk",
|
||||
.version_id = 1,
|
||||
.minimum_version_id = 1,
|
||||
.minimum_version_id_old = 1,
|
||||
.fields = (VMStateField[]) {
|
||||
VMSTATE_UINT8(data_on, PCSpkState),
|
||||
VMSTATE_UINT8(dummy_refresh_clock, PCSpkState),
|
||||
VMSTATE_END_OF_LIST()
|
||||
}
|
||||
};
|
||||
|
||||
static Property pcspk_properties[] = {
|
||||
DEFINE_PROP_UINT32("iobase", PCSpkState, iobase, -1),
|
||||
DEFINE_PROP_END_OF_LIST(),
|
||||
@@ -198,6 +210,7 @@ static void pcspk_class_initfn(ObjectClass *klass, void *data)
|
||||
|
||||
dc->realize = pcspk_realizefn;
|
||||
set_bit(DEVICE_CATEGORY_SOUND, dc->categories);
|
||||
dc->vmsd = &vmstate_spk;
|
||||
dc->props = pcspk_properties;
|
||||
/* Reason: realize sets global pcspk_state */
|
||||
dc->cannot_instantiate_with_device_add_yet = true;
|
||||
|
@@ -133,9 +133,15 @@ ssize_t read_targphys(const char *name,
|
||||
return did;
|
||||
}
|
||||
|
||||
/* return the size or -1 if error */
|
||||
int load_image_targphys(const char *filename,
|
||||
hwaddr addr, uint64_t max_sz)
|
||||
{
|
||||
return load_image_targphys_as(filename, addr, max_sz, NULL);
|
||||
}
|
||||
|
||||
/* return the size or -1 if error */
|
||||
int load_image_targphys_as(const char *filename,
|
||||
hwaddr addr, uint64_t max_sz, AddressSpace *as)
|
||||
{
|
||||
int size;
|
||||
|
||||
@@ -144,7 +150,7 @@ int load_image_targphys(const char *filename,
|
||||
return -1;
|
||||
}
|
||||
if (size > 0) {
|
||||
rom_add_file_fixed(filename, addr, -1);
|
||||
rom_add_file_fixed_as(filename, addr, -1, as);
|
||||
}
|
||||
return size;
|
||||
}
|
||||
@@ -416,6 +422,18 @@ int load_elf(const char *filename, uint64_t (*translate_fn)(void *, uint64_t),
|
||||
void *translate_opaque, uint64_t *pentry, uint64_t *lowaddr,
|
||||
uint64_t *highaddr, int big_endian, int elf_machine,
|
||||
int clear_lsb, int data_swab)
|
||||
{
|
||||
return load_elf_as(filename, translate_fn, translate_opaque, pentry,
|
||||
lowaddr, highaddr, big_endian, elf_machine, clear_lsb,
|
||||
data_swab, NULL);
|
||||
}
|
||||
|
||||
/* return < 0 if error, otherwise the number of bytes loaded in memory */
|
||||
int load_elf_as(const char *filename,
|
||||
uint64_t (*translate_fn)(void *, uint64_t),
|
||||
void *translate_opaque, uint64_t *pentry, uint64_t *lowaddr,
|
||||
uint64_t *highaddr, int big_endian, int elf_machine,
|
||||
int clear_lsb, int data_swab, AddressSpace *as)
|
||||
{
|
||||
int fd, data_order, target_data_order, must_swab, ret = ELF_LOAD_FAILED;
|
||||
uint8_t e_ident[EI_NIDENT];
|
||||
@@ -455,11 +473,11 @@ int load_elf(const char *filename, uint64_t (*translate_fn)(void *, uint64_t),
|
||||
if (e_ident[EI_CLASS] == ELFCLASS64) {
|
||||
ret = load_elf64(filename, fd, translate_fn, translate_opaque, must_swab,
|
||||
pentry, lowaddr, highaddr, elf_machine, clear_lsb,
|
||||
data_swab);
|
||||
data_swab, as);
|
||||
} else {
|
||||
ret = load_elf32(filename, fd, translate_fn, translate_opaque, must_swab,
|
||||
pentry, lowaddr, highaddr, elf_machine, clear_lsb,
|
||||
data_swab);
|
||||
data_swab, as);
|
||||
}
|
||||
|
||||
fail:
|
||||
@@ -569,7 +587,7 @@ static ssize_t gunzip(void *dst, size_t dstlen, uint8_t *src,
|
||||
static int load_uboot_image(const char *filename, hwaddr *ep, hwaddr *loadaddr,
|
||||
int *is_linux, uint8_t image_type,
|
||||
uint64_t (*translate_fn)(void *, uint64_t),
|
||||
void *translate_opaque)
|
||||
void *translate_opaque, AddressSpace *as)
|
||||
{
|
||||
int fd;
|
||||
int size;
|
||||
@@ -670,7 +688,7 @@ static int load_uboot_image(const char *filename, hwaddr *ep, hwaddr *loadaddr,
|
||||
hdr->ih_size = bytes;
|
||||
}
|
||||
|
||||
rom_add_blob_fixed(filename, data, hdr->ih_size, address);
|
||||
rom_add_blob_fixed_as(filename, data, hdr->ih_size, address, as);
|
||||
|
||||
ret = hdr->ih_size;
|
||||
|
||||
@@ -686,14 +704,23 @@ int load_uimage(const char *filename, hwaddr *ep, hwaddr *loadaddr,
|
||||
void *translate_opaque)
|
||||
{
|
||||
return load_uboot_image(filename, ep, loadaddr, is_linux, IH_TYPE_KERNEL,
|
||||
translate_fn, translate_opaque);
|
||||
translate_fn, translate_opaque, NULL);
|
||||
}
|
||||
|
||||
int load_uimage_as(const char *filename, hwaddr *ep, hwaddr *loadaddr,
|
||||
int *is_linux,
|
||||
uint64_t (*translate_fn)(void *, uint64_t),
|
||||
void *translate_opaque, AddressSpace *as)
|
||||
{
|
||||
return load_uboot_image(filename, ep, loadaddr, is_linux, IH_TYPE_KERNEL,
|
||||
translate_fn, translate_opaque, as);
|
||||
}
|
||||
|
||||
/* Load a ramdisk. */
|
||||
int load_ramdisk(const char *filename, hwaddr addr, uint64_t max_sz)
|
||||
{
|
||||
return load_uboot_image(filename, NULL, &addr, NULL, IH_TYPE_RAMDISK,
|
||||
NULL, NULL);
|
||||
NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
/* Load a gzip-compressed kernel to a dynamically allocated buffer. */
|
||||
@@ -777,6 +804,7 @@ struct Rom {
|
||||
|
||||
uint8_t *data;
|
||||
MemoryRegion *mr;
|
||||
AddressSpace *as;
|
||||
int isrom;
|
||||
char *fw_dir;
|
||||
char *fw_file;
|
||||
@@ -788,6 +816,12 @@ struct Rom {
|
||||
static FWCfgState *fw_cfg;
|
||||
static QTAILQ_HEAD(, Rom) roms = QTAILQ_HEAD_INITIALIZER(roms);
|
||||
|
||||
static inline bool rom_order_compare(Rom *rom, Rom *item)
|
||||
{
|
||||
return (rom->as > item->as) ||
|
||||
(rom->as == item->as && rom->addr >= item->addr);
|
||||
}
|
||||
|
||||
static void rom_insert(Rom *rom)
|
||||
{
|
||||
Rom *item;
|
||||
@@ -796,10 +830,16 @@ static void rom_insert(Rom *rom)
|
||||
hw_error ("ROM images must be loaded at startup\n");
|
||||
}
|
||||
|
||||
/* list is ordered by load address */
|
||||
/* The user didn't specify an address space, this is the default */
|
||||
if (!rom->as) {
|
||||
rom->as = &address_space_memory;
|
||||
}
|
||||
|
||||
/* List is ordered by load address in the same address space */
|
||||
QTAILQ_FOREACH(item, &roms, next) {
|
||||
if (rom->addr >= item->addr)
|
||||
if (rom_order_compare(rom, item)) {
|
||||
continue;
|
||||
}
|
||||
QTAILQ_INSERT_BEFORE(item, rom, next);
|
||||
return;
|
||||
}
|
||||
@@ -833,16 +873,25 @@ 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,
|
||||
bool option_rom, MemoryRegion *mr)
|
||||
bool option_rom, MemoryRegion *mr,
|
||||
AddressSpace *as)
|
||||
{
|
||||
MachineClass *mc = MACHINE_GET_CLASS(qdev_get_machine());
|
||||
Rom *rom;
|
||||
int rc, fd = -1;
|
||||
char devpath[100];
|
||||
|
||||
if (as && mr) {
|
||||
fprintf(stderr, "Specifying an Address Space and Memory Region is " \
|
||||
"not valid when loading a rom\n");
|
||||
/* We haven't allocated anything so we don't need any cleanup */
|
||||
return -1;
|
||||
}
|
||||
|
||||
rom = g_malloc0(sizeof(*rom));
|
||||
rom->name = g_strdup(file);
|
||||
rom->path = qemu_find_file(QEMU_FILE_TYPE_BIOS, rom->name);
|
||||
rom->as = as;
|
||||
if (rom->path == NULL) {
|
||||
rom->path = g_strdup(file);
|
||||
}
|
||||
@@ -969,7 +1018,7 @@ MemoryRegion *rom_add_blob(const char *name, const void *blob, size_t len,
|
||||
* memory ownership of "data", so we don't have to allocate and copy the buffer.
|
||||
*/
|
||||
int rom_add_elf_program(const char *name, void *data, size_t datasize,
|
||||
size_t romsize, hwaddr addr)
|
||||
size_t romsize, hwaddr addr, AddressSpace *as)
|
||||
{
|
||||
Rom *rom;
|
||||
|
||||
@@ -979,18 +1028,19 @@ int rom_add_elf_program(const char *name, void *data, size_t datasize,
|
||||
rom->datasize = datasize;
|
||||
rom->romsize = romsize;
|
||||
rom->data = data;
|
||||
rom->as = as;
|
||||
rom_insert(rom);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rom_add_vga(const char *file)
|
||||
{
|
||||
return rom_add_file(file, "vgaroms", 0, -1, true, NULL);
|
||||
return rom_add_file(file, "vgaroms", 0, -1, true, NULL, NULL);
|
||||
}
|
||||
|
||||
int rom_add_option(const char *file, int32_t bootindex)
|
||||
{
|
||||
return rom_add_file(file, "genroms", 0, bootindex, true, NULL);
|
||||
return rom_add_file(file, "genroms", 0, bootindex, true, NULL, NULL);
|
||||
}
|
||||
|
||||
static void rom_reset(void *unused)
|
||||
@@ -1008,8 +1058,8 @@ static void rom_reset(void *unused)
|
||||
void *host = memory_region_get_ram_ptr(rom->mr);
|
||||
memcpy(host, rom->data, rom->datasize);
|
||||
} else {
|
||||
cpu_physical_memory_write_rom(&address_space_memory,
|
||||
rom->addr, rom->data, rom->datasize);
|
||||
cpu_physical_memory_write_rom(rom->as, rom->addr, rom->data,
|
||||
rom->datasize);
|
||||
}
|
||||
if (rom->isrom) {
|
||||
/* rom needs to be written only once */
|
||||
@@ -1031,12 +1081,13 @@ int rom_check_and_register_reset(void)
|
||||
hwaddr addr = 0;
|
||||
MemoryRegionSection section;
|
||||
Rom *rom;
|
||||
AddressSpace *as = NULL;
|
||||
|
||||
QTAILQ_FOREACH(rom, &roms, next) {
|
||||
if (rom->fw_file) {
|
||||
continue;
|
||||
}
|
||||
if (addr > rom->addr) {
|
||||
if ((addr > rom->addr) && (as == rom->as)) {
|
||||
fprintf(stderr, "rom: requested regions overlap "
|
||||
"(rom %s. free=0x" TARGET_FMT_plx
|
||||
", addr=0x" TARGET_FMT_plx ")\n",
|
||||
@@ -1045,9 +1096,11 @@ int rom_check_and_register_reset(void)
|
||||
}
|
||||
addr = rom->addr;
|
||||
addr += rom->romsize;
|
||||
section = memory_region_find(get_system_memory(), rom->addr, 1);
|
||||
section = memory_region_find(rom->mr ? rom->mr : get_system_memory(),
|
||||
rom->addr, 1);
|
||||
rom->isrom = int128_nz(section.size) && memory_region_is_rom(section.mr);
|
||||
memory_region_unref(section.mr);
|
||||
as = rom->as;
|
||||
}
|
||||
qemu_register_reset(rom_reset, NULL);
|
||||
roms_loaded = 1;
|
||||
|
@@ -11,6 +11,7 @@
|
||||
#include "hw/ptimer.h"
|
||||
#include "qemu/host-utils.h"
|
||||
#include "sysemu/replay.h"
|
||||
#include "sysemu/qtest.h"
|
||||
|
||||
struct ptimer_state
|
||||
{
|
||||
@@ -21,6 +22,7 @@ struct ptimer_state
|
||||
int64_t period;
|
||||
int64_t last_event;
|
||||
int64_t next_event;
|
||||
uint8_t policy_mask;
|
||||
QEMUBH *bh;
|
||||
QEMUTimer *timer;
|
||||
};
|
||||
@@ -43,7 +45,10 @@ static void ptimer_reload(ptimer_state *s)
|
||||
s->delta = s->limit;
|
||||
}
|
||||
if (s->delta == 0 || s->period == 0) {
|
||||
fprintf(stderr, "Timer with period zero, disabling\n");
|
||||
if (!qtest_enabled()) {
|
||||
fprintf(stderr, "Timer with period zero, disabling\n");
|
||||
}
|
||||
timer_del(s->timer);
|
||||
s->enabled = 0;
|
||||
return;
|
||||
}
|
||||
@@ -161,7 +166,9 @@ void ptimer_run(ptimer_state *s, int oneshot)
|
||||
bool was_disabled = !s->enabled;
|
||||
|
||||
if (was_disabled && s->period == 0) {
|
||||
fprintf(stderr, "Timer with period zero, disabling\n");
|
||||
if (!qtest_enabled()) {
|
||||
fprintf(stderr, "Timer with period zero, disabling\n");
|
||||
}
|
||||
return;
|
||||
}
|
||||
s->enabled = oneshot ? 2 : 1;
|
||||
@@ -242,12 +249,13 @@ const VMStateDescription vmstate_ptimer = {
|
||||
}
|
||||
};
|
||||
|
||||
ptimer_state *ptimer_init(QEMUBH *bh)
|
||||
ptimer_state *ptimer_init(QEMUBH *bh, uint8_t policy_mask)
|
||||
{
|
||||
ptimer_state *s;
|
||||
|
||||
s = (ptimer_state *)g_malloc0(sizeof(ptimer_state));
|
||||
s->bh = bh;
|
||||
s->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, ptimer_tick, s);
|
||||
s->policy_mask = policy_mask;
|
||||
return s;
|
||||
}
|
||||
|
@@ -48,18 +48,18 @@ typedef struct {
|
||||
SSISlave ssidev;
|
||||
QemuConsole *con;
|
||||
|
||||
int cmd_len;
|
||||
int cmd;
|
||||
int cmd_data[8];
|
||||
int row;
|
||||
int row_start;
|
||||
int row_end;
|
||||
int col;
|
||||
int col_start;
|
||||
int col_end;
|
||||
int redraw;
|
||||
int remap;
|
||||
enum ssd0323_mode mode;
|
||||
uint32_t cmd_len;
|
||||
int32_t cmd;
|
||||
int32_t cmd_data[8];
|
||||
int32_t row;
|
||||
int32_t row_start;
|
||||
int32_t row_end;
|
||||
int32_t col;
|
||||
int32_t col_start;
|
||||
int32_t col_end;
|
||||
int32_t redraw;
|
||||
int32_t remap;
|
||||
uint32_t mode;
|
||||
uint8_t framebuffer[128 * 80 / 2];
|
||||
} ssd0323_state;
|
||||
|
||||
@@ -279,83 +279,62 @@ static void ssd0323_cd(void *opaque, int n, int level)
|
||||
s->mode = level ? SSD0323_DATA : SSD0323_CMD;
|
||||
}
|
||||
|
||||
static void ssd0323_save(QEMUFile *f, void *opaque)
|
||||
static int ssd0323_post_load(void *opaque, int version_id)
|
||||
{
|
||||
SSISlave *ss = SSI_SLAVE(opaque);
|
||||
ssd0323_state *s = (ssd0323_state *)opaque;
|
||||
int i;
|
||||
|
||||
qemu_put_be32(f, s->cmd_len);
|
||||
qemu_put_be32(f, s->cmd);
|
||||
for (i = 0; i < 8; i++)
|
||||
qemu_put_be32(f, s->cmd_data[i]);
|
||||
qemu_put_be32(f, s->row);
|
||||
qemu_put_be32(f, s->row_start);
|
||||
qemu_put_be32(f, s->row_end);
|
||||
qemu_put_be32(f, s->col);
|
||||
qemu_put_be32(f, s->col_start);
|
||||
qemu_put_be32(f, s->col_end);
|
||||
qemu_put_be32(f, s->redraw);
|
||||
qemu_put_be32(f, s->remap);
|
||||
qemu_put_be32(f, s->mode);
|
||||
qemu_put_buffer(f, s->framebuffer, sizeof(s->framebuffer));
|
||||
|
||||
qemu_put_be32(f, ss->cs);
|
||||
}
|
||||
|
||||
static int ssd0323_load(QEMUFile *f, void *opaque, int version_id)
|
||||
{
|
||||
SSISlave *ss = SSI_SLAVE(opaque);
|
||||
ssd0323_state *s = (ssd0323_state *)opaque;
|
||||
int i;
|
||||
|
||||
if (version_id != 1)
|
||||
return -EINVAL;
|
||||
|
||||
s->cmd_len = qemu_get_be32(f);
|
||||
if (s->cmd_len < 0 || s->cmd_len > ARRAY_SIZE(s->cmd_data)) {
|
||||
if (s->cmd_len > ARRAY_SIZE(s->cmd_data)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
s->cmd = qemu_get_be32(f);
|
||||
for (i = 0; i < 8; i++)
|
||||
s->cmd_data[i] = qemu_get_be32(f);
|
||||
s->row = qemu_get_be32(f);
|
||||
if (s->row < 0 || s->row >= 80) {
|
||||
return -EINVAL;
|
||||
}
|
||||
s->row_start = qemu_get_be32(f);
|
||||
if (s->row_start < 0 || s->row_start >= 80) {
|
||||
return -EINVAL;
|
||||
}
|
||||
s->row_end = qemu_get_be32(f);
|
||||
if (s->row_end < 0 || s->row_end >= 80) {
|
||||
return -EINVAL;
|
||||
}
|
||||
s->col = qemu_get_be32(f);
|
||||
if (s->col < 0 || s->col >= 64) {
|
||||
return -EINVAL;
|
||||
}
|
||||
s->col_start = qemu_get_be32(f);
|
||||
if (s->col_start < 0 || s->col_start >= 64) {
|
||||
return -EINVAL;
|
||||
}
|
||||
s->col_end = qemu_get_be32(f);
|
||||
if (s->col_end < 0 || s->col_end >= 64) {
|
||||
return -EINVAL;
|
||||
}
|
||||
s->redraw = qemu_get_be32(f);
|
||||
s->remap = qemu_get_be32(f);
|
||||
s->mode = qemu_get_be32(f);
|
||||
if (s->mode != SSD0323_CMD && s->mode != SSD0323_DATA) {
|
||||
return -EINVAL;
|
||||
}
|
||||
qemu_get_buffer(f, s->framebuffer, sizeof(s->framebuffer));
|
||||
|
||||
ss->cs = qemu_get_be32(f);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const VMStateDescription vmstate_ssd0323 = {
|
||||
.name = "ssd0323_oled",
|
||||
.version_id = 2,
|
||||
.minimum_version_id = 2,
|
||||
.post_load = ssd0323_post_load,
|
||||
.fields = (VMStateField []) {
|
||||
VMSTATE_UINT32(cmd_len, ssd0323_state),
|
||||
VMSTATE_INT32(cmd, ssd0323_state),
|
||||
VMSTATE_INT32_ARRAY(cmd_data, ssd0323_state, 8),
|
||||
VMSTATE_INT32(row, ssd0323_state),
|
||||
VMSTATE_INT32(row_start, ssd0323_state),
|
||||
VMSTATE_INT32(row_end, ssd0323_state),
|
||||
VMSTATE_INT32(col, ssd0323_state),
|
||||
VMSTATE_INT32(col_start, ssd0323_state),
|
||||
VMSTATE_INT32(col_end, ssd0323_state),
|
||||
VMSTATE_INT32(redraw, ssd0323_state),
|
||||
VMSTATE_INT32(remap, ssd0323_state),
|
||||
VMSTATE_UINT32(mode, ssd0323_state),
|
||||
VMSTATE_BUFFER(framebuffer, ssd0323_state),
|
||||
VMSTATE_SSI_SLAVE(ssidev, ssd0323_state),
|
||||
VMSTATE_END_OF_LIST()
|
||||
}
|
||||
};
|
||||
|
||||
static const GraphicHwOps ssd0323_ops = {
|
||||
.invalidate = ssd0323_invalidate_display,
|
||||
.gfx_update = ssd0323_update_display,
|
||||
@@ -372,18 +351,17 @@ static void ssd0323_realize(SSISlave *d, Error **errp)
|
||||
qemu_console_resize(s->con, 128 * MAGNIFY, 64 * MAGNIFY);
|
||||
|
||||
qdev_init_gpio_in(dev, ssd0323_cd, 1);
|
||||
|
||||
register_savevm(dev, "ssd0323_oled", -1, 1,
|
||||
ssd0323_save, ssd0323_load, s);
|
||||
}
|
||||
|
||||
static void ssd0323_class_init(ObjectClass *klass, void *data)
|
||||
{
|
||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||
SSISlaveClass *k = SSI_SLAVE_CLASS(klass);
|
||||
|
||||
k->realize = ssd0323_realize;
|
||||
k->transfer = ssd0323_transfer;
|
||||
k->cs_polarity = SSI_CS_HIGH;
|
||||
dc->vmsd = &vmstate_ssd0323;
|
||||
}
|
||||
|
||||
static const TypeInfo ssd0323_info = {
|
||||
|
@@ -548,7 +548,7 @@ static void xilinx_axidma_realize(DeviceState *dev, Error **errp)
|
||||
|
||||
st->nr = i;
|
||||
st->bh = qemu_bh_new(timer_hit, st);
|
||||
st->ptimer = ptimer_init(st->bh);
|
||||
st->ptimer = ptimer_init(st->bh, PTIMER_POLICY_DEFAULT);
|
||||
ptimer_set_freq(st->ptimer, s->freqhz);
|
||||
}
|
||||
return;
|
||||
|
@@ -3,6 +3,7 @@ obj-y += multiboot.o
|
||||
obj-y += pc.o pc_piix.o pc_q35.o
|
||||
obj-y += pc_sysfw.o
|
||||
obj-y += x86-iommu.o intel_iommu.o
|
||||
obj-y += amd_iommu.o
|
||||
obj-$(CONFIG_XEN) += ../xenpv/ xen/
|
||||
|
||||
obj-y += kvmvapic.o
|
||||
|
@@ -59,7 +59,8 @@
|
||||
|
||||
#include "qapi/qmp/qint.h"
|
||||
#include "qom/qom-qobject.h"
|
||||
#include "hw/i386/x86-iommu.h"
|
||||
#include "hw/i386/amd_iommu.h"
|
||||
#include "hw/i386/intel_iommu.h"
|
||||
|
||||
#include "hw/acpi/ipmi.h"
|
||||
|
||||
@@ -2562,6 +2563,62 @@ build_dmar_q35(GArray *table_data, BIOSLinker *linker)
|
||||
build_header(linker, table_data, (void *)(table_data->data + dmar_start),
|
||||
"DMAR", table_data->len - dmar_start, 1, NULL, NULL);
|
||||
}
|
||||
/*
|
||||
* IVRS table as specified in AMD IOMMU Specification v2.62, Section 5.2
|
||||
* accessible here http://support.amd.com/TechDocs/48882_IOMMU.pdf
|
||||
*/
|
||||
static void
|
||||
build_amd_iommu(GArray *table_data, BIOSLinker *linker)
|
||||
{
|
||||
int iommu_start = table_data->len;
|
||||
AMDVIState *s = AMD_IOMMU_DEVICE(x86_iommu_get_default());
|
||||
|
||||
/* IVRS header */
|
||||
acpi_data_push(table_data, sizeof(AcpiTableHeader));
|
||||
/* IVinfo - IO virtualization information common to all
|
||||
* IOMMU units in a system
|
||||
*/
|
||||
build_append_int_noprefix(table_data, 40UL << 8/* PASize */, 4);
|
||||
/* reserved */
|
||||
build_append_int_noprefix(table_data, 0, 8);
|
||||
|
||||
/* IVHD definition - type 10h */
|
||||
build_append_int_noprefix(table_data, 0x10, 1);
|
||||
/* virtualization flags */
|
||||
build_append_int_noprefix(table_data,
|
||||
(1UL << 0) | /* HtTunEn */
|
||||
(1UL << 4) | /* iotblSup */
|
||||
(1UL << 6) | /* PrefSup */
|
||||
(1UL << 7), /* PPRSup */
|
||||
1);
|
||||
/* IVHD length */
|
||||
build_append_int_noprefix(table_data, 0x24, 2);
|
||||
/* DeviceID */
|
||||
build_append_int_noprefix(table_data, s->devid, 2);
|
||||
/* Capability offset */
|
||||
build_append_int_noprefix(table_data, s->capab_offset, 2);
|
||||
/* IOMMU base address */
|
||||
build_append_int_noprefix(table_data, s->mmio.addr, 8);
|
||||
/* PCI Segment Group */
|
||||
build_append_int_noprefix(table_data, 0, 2);
|
||||
/* IOMMU info */
|
||||
build_append_int_noprefix(table_data, 0, 2);
|
||||
/* IOMMU Feature Reporting */
|
||||
build_append_int_noprefix(table_data,
|
||||
(48UL << 30) | /* HATS */
|
||||
(48UL << 28) | /* GATS */
|
||||
(1UL << 2), /* GTSup */
|
||||
4);
|
||||
/*
|
||||
* Type 1 device entry reporting all devices
|
||||
* These are 4-byte device entries currently reporting the range of
|
||||
* Refer to Spec - Table 95:IVHD Device Entry Type Codes(4-byte)
|
||||
*/
|
||||
build_append_int_noprefix(table_data, 0x0000001, 4);
|
||||
|
||||
build_header(linker, table_data, (void *)(table_data->data + iommu_start),
|
||||
"IVRS", table_data->len - iommu_start, 1, NULL, NULL);
|
||||
}
|
||||
|
||||
static GArray *
|
||||
build_rsdp(GArray *rsdp_table, BIOSLinker *linker, unsigned rsdt_tbl_offset)
|
||||
@@ -2622,11 +2679,6 @@ static bool acpi_get_mcfg(AcpiMcfgInfo *mcfg)
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool acpi_has_iommu(void)
|
||||
{
|
||||
return !!x86_iommu_get_default();
|
||||
}
|
||||
|
||||
static
|
||||
void acpi_build(AcpiBuildTables *tables, MachineState *machine)
|
||||
{
|
||||
@@ -2706,9 +2758,15 @@ void acpi_build(AcpiBuildTables *tables, MachineState *machine)
|
||||
acpi_add_table(table_offsets, tables_blob);
|
||||
build_mcfg_q35(tables_blob, tables->linker, &mcfg);
|
||||
}
|
||||
if (acpi_has_iommu()) {
|
||||
acpi_add_table(table_offsets, tables_blob);
|
||||
build_dmar_q35(tables_blob, tables->linker);
|
||||
if (x86_iommu_get_default()) {
|
||||
IommuType IOMMUType = x86_iommu_get_type();
|
||||
if (IOMMUType == TYPE_AMD) {
|
||||
acpi_add_table(table_offsets, tables_blob);
|
||||
build_amd_iommu(tables_blob, tables->linker);
|
||||
} else if (IOMMUType == TYPE_INTEL) {
|
||||
acpi_add_table(table_offsets, tables_blob);
|
||||
build_dmar_q35(tables_blob, tables->linker);
|
||||
}
|
||||
}
|
||||
if (pcms->acpi_nvdimm_state.is_enabled) {
|
||||
nvdimm_build_acpi(table_offsets, tables_blob, tables->linker,
|
||||
|
1202
hw/i386/amd_iommu.c
Normal file
1202
hw/i386/amd_iommu.c
Normal file
File diff suppressed because it is too large
Load Diff
289
hw/i386/amd_iommu.h
Normal file
289
hw/i386/amd_iommu.h
Normal file
@@ -0,0 +1,289 @@
|
||||
/*
|
||||
* QEMU emulation of an AMD IOMMU (AMD-Vi)
|
||||
*
|
||||
* Copyright (C) 2011 Eduard - Gabriel Munteanu
|
||||
* Copyright (C) 2015 David Kiarie, <davidkiarie4@gmail.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef AMD_IOMMU_H_
|
||||
#define AMD_IOMMU_H_
|
||||
|
||||
#include "hw/hw.h"
|
||||
#include "hw/pci/pci.h"
|
||||
#include "hw/pci/msi.h"
|
||||
#include "hw/sysbus.h"
|
||||
#include "sysemu/dma.h"
|
||||
#include "hw/i386/pc.h"
|
||||
#include "hw/pci/pci_bus.h"
|
||||
#include "hw/i386/x86-iommu.h"
|
||||
|
||||
/* Capability registers */
|
||||
#define AMDVI_CAPAB_BAR_LOW 0x04
|
||||
#define AMDVI_CAPAB_BAR_HIGH 0x08
|
||||
#define AMDVI_CAPAB_RANGE 0x0C
|
||||
#define AMDVI_CAPAB_MISC 0x10
|
||||
|
||||
#define AMDVI_CAPAB_SIZE 0x18
|
||||
#define AMDVI_CAPAB_REG_SIZE 0x04
|
||||
|
||||
/* Capability header data */
|
||||
#define AMDVI_CAPAB_ID_SEC 0xf
|
||||
#define AMDVI_CAPAB_FLAT_EXT (1 << 28)
|
||||
#define AMDVI_CAPAB_EFR_SUP (1 << 27)
|
||||
#define AMDVI_CAPAB_FLAG_NPCACHE (1 << 26)
|
||||
#define AMDVI_CAPAB_FLAG_HTTUNNEL (1 << 25)
|
||||
#define AMDVI_CAPAB_FLAG_IOTLBSUP (1 << 24)
|
||||
#define AMDVI_CAPAB_INIT_TYPE (3 << 16)
|
||||
|
||||
/* No. of used MMIO registers */
|
||||
#define AMDVI_MMIO_REGS_HIGH 8
|
||||
#define AMDVI_MMIO_REGS_LOW 7
|
||||
|
||||
/* MMIO registers */
|
||||
#define AMDVI_MMIO_DEVICE_TABLE 0x0000
|
||||
#define AMDVI_MMIO_COMMAND_BASE 0x0008
|
||||
#define AMDVI_MMIO_EVENT_BASE 0x0010
|
||||
#define AMDVI_MMIO_CONTROL 0x0018
|
||||
#define AMDVI_MMIO_EXCL_BASE 0x0020
|
||||
#define AMDVI_MMIO_EXCL_LIMIT 0x0028
|
||||
#define AMDVI_MMIO_EXT_FEATURES 0x0030
|
||||
#define AMDVI_MMIO_COMMAND_HEAD 0x2000
|
||||
#define AMDVI_MMIO_COMMAND_TAIL 0x2008
|
||||
#define AMDVI_MMIO_EVENT_HEAD 0x2010
|
||||
#define AMDVI_MMIO_EVENT_TAIL 0x2018
|
||||
#define AMDVI_MMIO_STATUS 0x2020
|
||||
#define AMDVI_MMIO_PPR_BASE 0x0038
|
||||
#define AMDVI_MMIO_PPR_HEAD 0x2030
|
||||
#define AMDVI_MMIO_PPR_TAIL 0x2038
|
||||
|
||||
#define AMDVI_MMIO_SIZE 0x4000
|
||||
|
||||
#define AMDVI_MMIO_DEVTAB_SIZE_MASK ((1ULL << 12) - 1)
|
||||
#define AMDVI_MMIO_DEVTAB_BASE_MASK (((1ULL << 52) - 1) & ~ \
|
||||
AMDVI_MMIO_DEVTAB_SIZE_MASK)
|
||||
#define AMDVI_MMIO_DEVTAB_ENTRY_SIZE 32
|
||||
#define AMDVI_MMIO_DEVTAB_SIZE_UNIT 4096
|
||||
|
||||
/* some of this are similar but just for readability */
|
||||
#define AMDVI_MMIO_CMDBUF_SIZE_BYTE (AMDVI_MMIO_COMMAND_BASE + 7)
|
||||
#define AMDVI_MMIO_CMDBUF_SIZE_MASK 0x0f
|
||||
#define AMDVI_MMIO_CMDBUF_BASE_MASK AMDVI_MMIO_DEVTAB_BASE_MASK
|
||||
#define AMDVI_MMIO_CMDBUF_HEAD_MASK (((1ULL << 19) - 1) & ~0x0f)
|
||||
#define AMDVI_MMIO_CMDBUF_TAIL_MASK AMDVI_MMIO_EVTLOG_HEAD_MASK
|
||||
|
||||
#define AMDVI_MMIO_EVTLOG_SIZE_BYTE (AMDVI_MMIO_EVENT_BASE + 7)
|
||||
#define AMDVI_MMIO_EVTLOG_SIZE_MASK AMDVI_MMIO_CMDBUF_SIZE_MASK
|
||||
#define AMDVI_MMIO_EVTLOG_BASE_MASK AMDVI_MMIO_CMDBUF_BASE_MASK
|
||||
#define AMDVI_MMIO_EVTLOG_HEAD_MASK (((1ULL << 19) - 1) & ~0x0f)
|
||||
#define AMDVI_MMIO_EVTLOG_TAIL_MASK AMDVI_MMIO_EVTLOG_HEAD_MASK
|
||||
|
||||
#define AMDVI_MMIO_PPRLOG_SIZE_BYTE (AMDVI_MMIO_EVENT_BASE + 7)
|
||||
#define AMDVI_MMIO_PPRLOG_HEAD_MASK AMDVI_MMIO_EVTLOG_HEAD_MASK
|
||||
#define AMDVI_MMIO_PPRLOG_TAIL_MASK AMDVI_MMIO_EVTLOG_HEAD_MASK
|
||||
#define AMDVI_MMIO_PPRLOG_BASE_MASK AMDVI_MMIO_EVTLOG_BASE_MASK
|
||||
#define AMDVI_MMIO_PPRLOG_SIZE_MASK AMDVI_MMIO_EVTLOG_SIZE_MASK
|
||||
|
||||
#define AMDVI_MMIO_EXCL_ENABLED_MASK (1ULL << 0)
|
||||
#define AMDVI_MMIO_EXCL_ALLOW_MASK (1ULL << 1)
|
||||
#define AMDVI_MMIO_EXCL_LIMIT_MASK AMDVI_MMIO_DEVTAB_BASE_MASK
|
||||
#define AMDVI_MMIO_EXCL_LIMIT_LOW 0xfff
|
||||
|
||||
/* mmio control register flags */
|
||||
#define AMDVI_MMIO_CONTROL_AMDVIEN (1ULL << 0)
|
||||
#define AMDVI_MMIO_CONTROL_HTTUNEN (1ULL << 1)
|
||||
#define AMDVI_MMIO_CONTROL_EVENTLOGEN (1ULL << 2)
|
||||
#define AMDVI_MMIO_CONTROL_EVENTINTEN (1ULL << 3)
|
||||
#define AMDVI_MMIO_CONTROL_COMWAITINTEN (1ULL << 4)
|
||||
#define AMDVI_MMIO_CONTROL_CMDBUFLEN (1ULL << 12)
|
||||
|
||||
/* MMIO status register bits */
|
||||
#define AMDVI_MMIO_STATUS_CMDBUF_RUN (1 << 4)
|
||||
#define AMDVI_MMIO_STATUS_EVT_RUN (1 << 3)
|
||||
#define AMDVI_MMIO_STATUS_COMP_INT (1 << 2)
|
||||
#define AMDVI_MMIO_STATUS_EVT_OVF (1 << 0)
|
||||
|
||||
#define AMDVI_CMDBUF_ID_BYTE 0x07
|
||||
#define AMDVI_CMDBUF_ID_RSHIFT 4
|
||||
|
||||
#define AMDVI_CMD_COMPLETION_WAIT 0x01
|
||||
#define AMDVI_CMD_INVAL_DEVTAB_ENTRY 0x02
|
||||
#define AMDVI_CMD_INVAL_AMDVI_PAGES 0x03
|
||||
#define AMDVI_CMD_INVAL_IOTLB_PAGES 0x04
|
||||
#define AMDVI_CMD_INVAL_INTR_TABLE 0x05
|
||||
#define AMDVI_CMD_PREFETCH_AMDVI_PAGES 0x06
|
||||
#define AMDVI_CMD_COMPLETE_PPR_REQUEST 0x07
|
||||
#define AMDVI_CMD_INVAL_AMDVI_ALL 0x08
|
||||
|
||||
#define AMDVI_DEVTAB_ENTRY_SIZE 32
|
||||
|
||||
/* Device table entry bits 0:63 */
|
||||
#define AMDVI_DEV_VALID (1ULL << 0)
|
||||
#define AMDVI_DEV_TRANSLATION_VALID (1ULL << 1)
|
||||
#define AMDVI_DEV_MODE_MASK 0x7
|
||||
#define AMDVI_DEV_MODE_RSHIFT 9
|
||||
#define AMDVI_DEV_PT_ROOT_MASK 0xffffffffff000
|
||||
#define AMDVI_DEV_PT_ROOT_RSHIFT 12
|
||||
#define AMDVI_DEV_PERM_SHIFT 61
|
||||
#define AMDVI_DEV_PERM_READ (1ULL << 61)
|
||||
#define AMDVI_DEV_PERM_WRITE (1ULL << 62)
|
||||
|
||||
/* Device table entry bits 64:127 */
|
||||
#define AMDVI_DEV_DOMID_ID_MASK ((1ULL << 16) - 1)
|
||||
|
||||
/* Event codes and flags, as stored in the info field */
|
||||
#define AMDVI_EVENT_ILLEGAL_DEVTAB_ENTRY (0x1U << 12)
|
||||
#define AMDVI_EVENT_IOPF (0x2U << 12)
|
||||
#define AMDVI_EVENT_IOPF_I (1U << 3)
|
||||
#define AMDVI_EVENT_DEV_TAB_HW_ERROR (0x3U << 12)
|
||||
#define AMDVI_EVENT_PAGE_TAB_HW_ERROR (0x4U << 12)
|
||||
#define AMDVI_EVENT_ILLEGAL_COMMAND_ERROR (0x5U << 12)
|
||||
#define AMDVI_EVENT_COMMAND_HW_ERROR (0x6U << 12)
|
||||
|
||||
#define AMDVI_EVENT_LEN 16
|
||||
#define AMDVI_PERM_READ (1 << 0)
|
||||
#define AMDVI_PERM_WRITE (1 << 1)
|
||||
|
||||
#define AMDVI_FEATURE_PREFETCH (1ULL << 0) /* page prefetch */
|
||||
#define AMDVI_FEATURE_PPR (1ULL << 1) /* PPR Support */
|
||||
#define AMDVI_FEATURE_GT (1ULL << 4) /* Guest Translation */
|
||||
#define AMDVI_FEATURE_IA (1ULL << 6) /* inval all support */
|
||||
#define AMDVI_FEATURE_GA (1ULL << 7) /* guest VAPIC support */
|
||||
#define AMDVI_FEATURE_HE (1ULL << 8) /* hardware error regs */
|
||||
#define AMDVI_FEATURE_PC (1ULL << 9) /* Perf counters */
|
||||
|
||||
/* reserved DTE bits */
|
||||
#define AMDVI_DTE_LOWER_QUAD_RESERVED 0x80300000000000fc
|
||||
#define AMDVI_DTE_MIDDLE_QUAD_RESERVED 0x0000000000000100
|
||||
#define AMDVI_DTE_UPPER_QUAD_RESERVED 0x08f0000000000000
|
||||
|
||||
/* AMDVI paging mode */
|
||||
#define AMDVI_GATS_MODE (6ULL << 12)
|
||||
#define AMDVI_HATS_MODE (6ULL << 10)
|
||||
|
||||
/* IOTLB */
|
||||
#define AMDVI_IOTLB_MAX_SIZE 1024
|
||||
#define AMDVI_DEVID_SHIFT 36
|
||||
|
||||
/* extended feature support */
|
||||
#define AMDVI_EXT_FEATURES (AMDVI_FEATURE_PREFETCH | AMDVI_FEATURE_PPR | \
|
||||
AMDVI_FEATURE_IA | AMDVI_FEATURE_GT | AMDVI_FEATURE_HE | \
|
||||
AMDVI_GATS_MODE | AMDVI_HATS_MODE)
|
||||
|
||||
/* capabilities header */
|
||||
#define AMDVI_CAPAB_FEATURES (AMDVI_CAPAB_FLAT_EXT | \
|
||||
AMDVI_CAPAB_FLAG_NPCACHE | AMDVI_CAPAB_FLAG_IOTLBSUP \
|
||||
| AMDVI_CAPAB_ID_SEC | AMDVI_CAPAB_INIT_TYPE | \
|
||||
AMDVI_CAPAB_FLAG_HTTUNNEL | AMDVI_CAPAB_EFR_SUP)
|
||||
|
||||
/* AMDVI default address */
|
||||
#define AMDVI_BASE_ADDR 0xfed80000
|
||||
|
||||
/* page management constants */
|
||||
#define AMDVI_PAGE_SHIFT 12
|
||||
#define AMDVI_PAGE_SIZE (1ULL << AMDVI_PAGE_SHIFT)
|
||||
|
||||
#define AMDVI_PAGE_SHIFT_4K 12
|
||||
#define AMDVI_PAGE_MASK_4K (~((1ULL << AMDVI_PAGE_SHIFT_4K) - 1))
|
||||
|
||||
#define AMDVI_MAX_VA_ADDR (48UL << 5)
|
||||
#define AMDVI_MAX_PH_ADDR (40UL << 8)
|
||||
#define AMDVI_MAX_GVA_ADDR (48UL << 15)
|
||||
|
||||
/* Completion Wait data size */
|
||||
#define AMDVI_COMPLETION_DATA_SIZE 8
|
||||
|
||||
#define AMDVI_COMMAND_SIZE 16
|
||||
/* Completion Wait data size */
|
||||
#define AMDVI_COMPLETION_DATA_SIZE 8
|
||||
|
||||
#define AMDVI_COMMAND_SIZE 16
|
||||
|
||||
#define AMDVI_INT_ADDR_FIRST 0xfee00000
|
||||
#define AMDVI_INT_ADDR_LAST 0xfeefffff
|
||||
|
||||
#define TYPE_AMD_IOMMU_DEVICE "amd-iommu"
|
||||
#define AMD_IOMMU_DEVICE(obj)\
|
||||
OBJECT_CHECK(AMDVIState, (obj), TYPE_AMD_IOMMU_DEVICE)
|
||||
|
||||
#define TYPE_AMD_IOMMU_PCI "AMDVI-PCI"
|
||||
|
||||
typedef struct AMDVIAddressSpace AMDVIAddressSpace;
|
||||
|
||||
/* functions to steal PCI config space */
|
||||
typedef struct AMDVIPCIState {
|
||||
PCIDevice dev; /* The PCI device itself */
|
||||
} AMDVIPCIState;
|
||||
|
||||
typedef struct AMDVIState {
|
||||
X86IOMMUState iommu; /* IOMMU bus device */
|
||||
AMDVIPCIState pci; /* IOMMU PCI device */
|
||||
|
||||
uint32_t version;
|
||||
uint32_t capab_offset; /* capability offset pointer */
|
||||
|
||||
uint64_t mmio_addr;
|
||||
|
||||
uint32_t devid; /* auto-assigned devid */
|
||||
|
||||
bool enabled; /* IOMMU enabled */
|
||||
bool ats_enabled; /* address translation enabled */
|
||||
bool cmdbuf_enabled; /* command buffer enabled */
|
||||
bool evtlog_enabled; /* event log enabled */
|
||||
bool excl_enabled;
|
||||
|
||||
hwaddr devtab; /* base address device table */
|
||||
size_t devtab_len; /* device table length */
|
||||
|
||||
hwaddr cmdbuf; /* command buffer base address */
|
||||
uint64_t cmdbuf_len; /* command buffer length */
|
||||
uint32_t cmdbuf_head; /* current IOMMU read position */
|
||||
uint32_t cmdbuf_tail; /* next Software write position */
|
||||
bool completion_wait_intr;
|
||||
|
||||
hwaddr evtlog; /* base address event log */
|
||||
bool evtlog_intr;
|
||||
uint32_t evtlog_len; /* event log length */
|
||||
uint32_t evtlog_head; /* current IOMMU write position */
|
||||
uint32_t evtlog_tail; /* current Software read position */
|
||||
|
||||
/* unused for now */
|
||||
hwaddr excl_base; /* base DVA - IOMMU exclusion range */
|
||||
hwaddr excl_limit; /* limit of IOMMU exclusion range */
|
||||
bool excl_allow; /* translate accesses to the exclusion range */
|
||||
bool excl_enable; /* exclusion range enabled */
|
||||
|
||||
hwaddr ppr_log; /* base address ppr log */
|
||||
uint32_t pprlog_len; /* ppr log len */
|
||||
uint32_t pprlog_head; /* ppr log head */
|
||||
uint32_t pprlog_tail; /* ppr log tail */
|
||||
|
||||
MemoryRegion mmio; /* MMIO region */
|
||||
uint8_t mmior[AMDVI_MMIO_SIZE]; /* read/write MMIO */
|
||||
uint8_t w1cmask[AMDVI_MMIO_SIZE]; /* read/write 1 clear mask */
|
||||
uint8_t romask[AMDVI_MMIO_SIZE]; /* MMIO read/only mask */
|
||||
bool mmio_enabled;
|
||||
|
||||
/* IOMMU function */
|
||||
MemoryRegionIOMMUOps iommu_ops;
|
||||
|
||||
/* for each served device */
|
||||
AMDVIAddressSpace **address_spaces[PCI_BUS_MAX];
|
||||
|
||||
/* IOTLB */
|
||||
GHashTable *iotlb;
|
||||
} AMDVIState;
|
||||
|
||||
#endif
|
@@ -2453,6 +2453,7 @@ static void vtd_realize(DeviceState *dev, Error **errp)
|
||||
X86IOMMUState *x86_iommu = X86_IOMMU_DEVICE(dev);
|
||||
|
||||
VTD_DPRINTF(GENERAL, "");
|
||||
x86_iommu->type = TYPE_INTEL;
|
||||
memset(s->vtd_as_by_bus_num, 0, sizeof(s->vtd_as_by_bus_num));
|
||||
memory_region_init_io(&s->csrmem, OBJECT(s), &vtd_mem_ops, s,
|
||||
"intel_iommu", DMAR_REG_SIZE);
|
||||
|
@@ -15,6 +15,7 @@
|
||||
#include "hw/i386/apic_internal.h"
|
||||
#include "hw/pci/msi.h"
|
||||
#include "sysemu/kvm.h"
|
||||
#include "target-i386/kvm_i386.h"
|
||||
|
||||
static inline void kvm_apic_set_reg(struct kvm_lapic_state *kapic,
|
||||
int reg_id, uint32_t val)
|
||||
@@ -130,6 +131,7 @@ static void kvm_apic_put(void *data)
|
||||
struct kvm_lapic_state kapic;
|
||||
int ret;
|
||||
|
||||
kvm_put_apicbase(s->cpu, s->apicbase);
|
||||
kvm_put_apic_state(s, &kapic);
|
||||
|
||||
ret = kvm_vcpu_ioctl(CPU(s->cpu), KVM_SET_LAPIC, &kapic);
|
||||
@@ -141,7 +143,6 @@ static void kvm_apic_put(void *data)
|
||||
|
||||
static void kvm_apic_post_load(APICCommonState *s)
|
||||
{
|
||||
fprintf(stderr, "%s: Yeh\n", __func__);
|
||||
run_on_cpu(CPU(s->cpu), kvm_apic_put, s);
|
||||
}
|
||||
|
||||
|
@@ -768,6 +768,7 @@ static void kvmvapic_vm_state_change(void *opaque, int running,
|
||||
}
|
||||
|
||||
qemu_del_vm_change_state_handler(s->vmsentry);
|
||||
s->vmsentry = NULL;
|
||||
}
|
||||
|
||||
static int vapic_post_load(void *opaque, int version_id)
|
||||
|
18
hw/i386/pc.c
18
hw/i386/pc.c
@@ -161,13 +161,15 @@ int cpu_get_pic_interrupt(CPUX86State *env)
|
||||
X86CPU *cpu = x86_env_get_cpu(env);
|
||||
int intno;
|
||||
|
||||
intno = apic_get_interrupt(cpu->apic_state);
|
||||
if (intno >= 0) {
|
||||
return intno;
|
||||
}
|
||||
/* read the irq from the PIC */
|
||||
if (!apic_accept_pic_intr(cpu->apic_state)) {
|
||||
return -1;
|
||||
if (!kvm_irqchip_in_kernel()) {
|
||||
intno = apic_get_interrupt(cpu->apic_state);
|
||||
if (intno >= 0) {
|
||||
return intno;
|
||||
}
|
||||
/* read the irq from the PIC */
|
||||
if (!apic_accept_pic_intr(cpu->apic_state)) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
intno = pic_read_irq(isa_pic);
|
||||
@@ -180,7 +182,7 @@ static void pic_irq_request(void *opaque, int irq, int level)
|
||||
X86CPU *cpu = X86_CPU(cs);
|
||||
|
||||
DPRINTF("pic_irqs: %s irq %d\n", level? "raise" : "lower", irq);
|
||||
if (cpu->apic_state) {
|
||||
if (cpu->apic_state && !kvm_irqchip_in_kernel()) {
|
||||
CPU_FOREACH(cs) {
|
||||
cpu = X86_CPU(cs);
|
||||
if (apic_accept_pic_intr(cpu->apic_state)) {
|
||||
|
@@ -13,3 +13,32 @@ mhp_pc_dimm_assigned_address(uint64_t addr) "0x%"PRIx64
|
||||
|
||||
# hw/i386/x86-iommu.c
|
||||
x86_iommu_iec_notify(bool global, uint32_t index, uint32_t mask) "Notify IEC invalidation: global=%d index=%" PRIu32 " mask=%" PRIu32
|
||||
|
||||
# hw/i386/amd_iommu.c
|
||||
amdvi_evntlog_fail(uint64_t addr, uint32_t head) "error: fail to write at addr 0x%"PRIx64" + offset 0x%"PRIx32
|
||||
amdvi_cache_update(uint16_t domid, uint8_t bus, uint8_t slot, uint8_t func, uint64_t gpa, uint64_t txaddr) " update iotlb domid 0x%"PRIx16" devid: %02x:%02x.%x gpa 0x%"PRIx64" hpa 0x%"PRIx64
|
||||
amdvi_completion_wait_fail(uint64_t addr) "error: fail to write at address 0x%"PRIx64
|
||||
amdvi_mmio_write(const char *reg, uint64_t addr, unsigned size, uint64_t val, uint64_t offset) "%s write addr 0x%"PRIx64", size %u, val 0x%"PRIx64", offset 0x%"PRIx64
|
||||
amdvi_mmio_read(const char *reg, uint64_t addr, unsigned size, uint64_t offset) "%s read addr 0x%"PRIx64", size %u offset 0x%"PRIx64
|
||||
amdvi_command_error(uint64_t status) "error: Executing commands with command buffer disabled 0x%"PRIx64
|
||||
amdvi_command_read_fail(uint64_t addr, uint32_t head) "error: fail to access memory at 0x%"PRIx64" + 0x%"PRIx32
|
||||
amdvi_command_exec(uint32_t head, uint32_t tail, uint64_t buf) "command buffer head at 0x%"PRIx32" command buffer tail at 0x%"PRIx32" command buffer base at 0x%"PRIx64
|
||||
amdvi_unhandled_command(uint8_t type) "unhandled command 0x%"PRIx8
|
||||
amdvi_intr_inval(void) "Interrupt table invalidated"
|
||||
amdvi_iotlb_inval(void) "IOTLB pages invalidated"
|
||||
amdvi_prefetch_pages(void) "Pre-fetch of AMD-Vi pages requested"
|
||||
amdvi_pages_inval(uint16_t domid) "AMD-Vi pages for domain 0x%"PRIx16 " invalidated"
|
||||
amdvi_all_inval(void) "Invalidation of all AMD-Vi cache requested "
|
||||
amdvi_ppr_exec(void) "Execution of PPR queue requested "
|
||||
amdvi_devtab_inval(uint8_t bus, uint8_t slot, uint8_t func) "device table entry for devid: %02x:%02x.%x invalidated"
|
||||
amdvi_completion_wait(uint64_t addr, uint64_t data) "completion wait requested with store address 0x%"PRIx64" and store data 0x%"PRIx64
|
||||
amdvi_control_status(uint64_t val) "MMIO_STATUS state 0x%"PRIx64
|
||||
amdvi_iotlb_reset(void) "IOTLB exceed size limit - reset "
|
||||
amdvi_completion_wait_exec(uint64_t addr, uint64_t data) "completion wait requested with store address 0x%"PRIx64" and store data 0x%"PRIx64
|
||||
amdvi_dte_get_fail(uint64_t addr, uint32_t offset) "error: failed to access Device Entry devtab 0x%"PRIx64" offset 0x%"PRIx32
|
||||
amdvi_invalid_dte(uint64_t addr) "PTE entry at 0x%"PRIx64" is invalid "
|
||||
amdvi_get_pte_hwerror(uint64_t addr) "hardware error eccessing PTE at addr 0x%"PRIx64
|
||||
amdvi_mode_invalid(uint8_t level, uint64_t addr)"error: translation level 0x%"PRIx8" translating addr 0x%"PRIx64
|
||||
amdvi_page_fault(uint64_t addr) "error: page fault accessing guest physical address 0x%"PRIx64
|
||||
amdvi_iotlb_hit(uint8_t bus, uint8_t slot, uint8_t func, uint64_t addr, uint64_t txaddr) "hit iotlb devid %02x:%02x.%x gpa 0x%"PRIx64" hpa 0x%"PRIx64
|
||||
amdvi_translation_result(uint8_t bus, uint8_t slot, uint8_t func, uint64_t addr, uint64_t txaddr) "devid: %02x:%02x.%x gpa 0x%"PRIx64" hpa 0x%"PRIx64
|
||||
|
@@ -71,6 +71,11 @@ X86IOMMUState *x86_iommu_get_default(void)
|
||||
return x86_iommu_default;
|
||||
}
|
||||
|
||||
IommuType x86_iommu_get_type(void)
|
||||
{
|
||||
return x86_iommu_default->type;
|
||||
}
|
||||
|
||||
static void x86_iommu_realize(DeviceState *dev, Error **errp)
|
||||
{
|
||||
X86IOMMUState *x86_iommu = X86_IOMMU_DEVICE(dev);
|
||||
@@ -79,6 +84,7 @@ static void x86_iommu_realize(DeviceState *dev, Error **errp)
|
||||
if (x86_class->realize) {
|
||||
x86_class->realize(dev, errp);
|
||||
}
|
||||
|
||||
x86_iommu_set_default(X86_IOMMU_DEVICE(dev));
|
||||
}
|
||||
|
||||
|
229
hw/input/adb.c
229
hw/input/adb.c
@@ -25,6 +25,9 @@
|
||||
#include "hw/hw.h"
|
||||
#include "hw/input/adb.h"
|
||||
#include "ui/console.h"
|
||||
#include "include/hw/input/adb-keys.h"
|
||||
#include "ui/input.h"
|
||||
#include "sysemu/sysemu.h"
|
||||
|
||||
/* debug ADB */
|
||||
//#define DEBUG_ADB
|
||||
@@ -59,6 +62,9 @@ do { printf("ADB: " fmt , ## __VA_ARGS__); } while (0)
|
||||
/* error codes */
|
||||
#define ADB_RET_NOTPRESENT (-2)
|
||||
|
||||
/* The adb keyboard doesn't have every key imaginable */
|
||||
#define NO_KEY 0xff
|
||||
|
||||
static void adb_device_reset(ADBDevice *d)
|
||||
{
|
||||
qdev_reset_all(DEVICE(d));
|
||||
@@ -187,23 +193,125 @@ typedef struct ADBKeyboardClass {
|
||||
DeviceRealize parent_realize;
|
||||
} ADBKeyboardClass;
|
||||
|
||||
static const uint8_t pc_to_adb_keycode[256] = {
|
||||
0, 53, 18, 19, 20, 21, 23, 22, 26, 28, 25, 29, 27, 24, 51, 48,
|
||||
12, 13, 14, 15, 17, 16, 32, 34, 31, 35, 33, 30, 36, 54, 0, 1,
|
||||
2, 3, 5, 4, 38, 40, 37, 41, 39, 50, 56, 42, 6, 7, 8, 9,
|
||||
11, 45, 46, 43, 47, 44,123, 67, 58, 49, 57,122,120, 99,118, 96,
|
||||
97, 98,100,101,109, 71,107, 89, 91, 92, 78, 86, 87, 88, 69, 83,
|
||||
84, 85, 82, 65, 0, 0, 10,103,111, 0, 0,110, 81, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 94, 0, 93, 0, 0, 0, 0, 0, 0,104,102, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 76,125, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,105, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 75, 0, 0,124, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0,115, 62,116, 0, 59, 0, 60, 0,119,
|
||||
61,121,114,117, 0, 0, 0, 0, 0, 0, 0, 55,126, 0,127, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 95, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
int qcode_to_adb_keycode[] = {
|
||||
/* Make sure future additions are automatically set to NO_KEY */
|
||||
[0 ... 0xff] = NO_KEY,
|
||||
|
||||
[Q_KEY_CODE_SHIFT] = ADB_KEY_LEFT_SHIFT,
|
||||
[Q_KEY_CODE_SHIFT_R] = ADB_KEY_RIGHT_SHIFT,
|
||||
[Q_KEY_CODE_ALT] = ADB_KEY_LEFT_OPTION,
|
||||
[Q_KEY_CODE_ALT_R] = ADB_KEY_RIGHT_OPTION,
|
||||
[Q_KEY_CODE_ALTGR] = ADB_KEY_RIGHT_OPTION,
|
||||
[Q_KEY_CODE_CTRL] = ADB_KEY_LEFT_CONTROL,
|
||||
[Q_KEY_CODE_CTRL_R] = ADB_KEY_RIGHT_CONTROL,
|
||||
[Q_KEY_CODE_META_L] = ADB_KEY_COMMAND,
|
||||
[Q_KEY_CODE_META_R] = ADB_KEY_COMMAND,
|
||||
[Q_KEY_CODE_SPC] = ADB_KEY_SPACEBAR,
|
||||
|
||||
[Q_KEY_CODE_ESC] = ADB_KEY_ESC,
|
||||
[Q_KEY_CODE_1] = ADB_KEY_1,
|
||||
[Q_KEY_CODE_2] = ADB_KEY_2,
|
||||
[Q_KEY_CODE_3] = ADB_KEY_3,
|
||||
[Q_KEY_CODE_4] = ADB_KEY_4,
|
||||
[Q_KEY_CODE_5] = ADB_KEY_5,
|
||||
[Q_KEY_CODE_6] = ADB_KEY_6,
|
||||
[Q_KEY_CODE_7] = ADB_KEY_7,
|
||||
[Q_KEY_CODE_8] = ADB_KEY_8,
|
||||
[Q_KEY_CODE_9] = ADB_KEY_9,
|
||||
[Q_KEY_CODE_0] = ADB_KEY_0,
|
||||
[Q_KEY_CODE_MINUS] = ADB_KEY_MINUS,
|
||||
[Q_KEY_CODE_EQUAL] = ADB_KEY_EQUAL,
|
||||
[Q_KEY_CODE_BACKSPACE] = ADB_KEY_DELETE,
|
||||
[Q_KEY_CODE_TAB] = ADB_KEY_TAB,
|
||||
[Q_KEY_CODE_Q] = ADB_KEY_Q,
|
||||
[Q_KEY_CODE_W] = ADB_KEY_W,
|
||||
[Q_KEY_CODE_E] = ADB_KEY_E,
|
||||
[Q_KEY_CODE_R] = ADB_KEY_R,
|
||||
[Q_KEY_CODE_T] = ADB_KEY_T,
|
||||
[Q_KEY_CODE_Y] = ADB_KEY_Y,
|
||||
[Q_KEY_CODE_U] = ADB_KEY_U,
|
||||
[Q_KEY_CODE_I] = ADB_KEY_I,
|
||||
[Q_KEY_CODE_O] = ADB_KEY_O,
|
||||
[Q_KEY_CODE_P] = ADB_KEY_P,
|
||||
[Q_KEY_CODE_BRACKET_LEFT] = ADB_KEY_LEFT_BRACKET,
|
||||
[Q_KEY_CODE_BRACKET_RIGHT] = ADB_KEY_RIGHT_BRACKET,
|
||||
[Q_KEY_CODE_RET] = ADB_KEY_RETURN,
|
||||
[Q_KEY_CODE_A] = ADB_KEY_A,
|
||||
[Q_KEY_CODE_S] = ADB_KEY_S,
|
||||
[Q_KEY_CODE_D] = ADB_KEY_D,
|
||||
[Q_KEY_CODE_F] = ADB_KEY_F,
|
||||
[Q_KEY_CODE_G] = ADB_KEY_G,
|
||||
[Q_KEY_CODE_H] = ADB_KEY_H,
|
||||
[Q_KEY_CODE_J] = ADB_KEY_J,
|
||||
[Q_KEY_CODE_K] = ADB_KEY_K,
|
||||
[Q_KEY_CODE_L] = ADB_KEY_L,
|
||||
[Q_KEY_CODE_SEMICOLON] = ADB_KEY_SEMICOLON,
|
||||
[Q_KEY_CODE_APOSTROPHE] = ADB_KEY_APOSTROPHE,
|
||||
[Q_KEY_CODE_GRAVE_ACCENT] = ADB_KEY_GRAVE_ACCENT,
|
||||
[Q_KEY_CODE_BACKSLASH] = ADB_KEY_BACKSLASH,
|
||||
[Q_KEY_CODE_Z] = ADB_KEY_Z,
|
||||
[Q_KEY_CODE_X] = ADB_KEY_X,
|
||||
[Q_KEY_CODE_C] = ADB_KEY_C,
|
||||
[Q_KEY_CODE_V] = ADB_KEY_V,
|
||||
[Q_KEY_CODE_B] = ADB_KEY_B,
|
||||
[Q_KEY_CODE_N] = ADB_KEY_N,
|
||||
[Q_KEY_CODE_M] = ADB_KEY_M,
|
||||
[Q_KEY_CODE_COMMA] = ADB_KEY_COMMA,
|
||||
[Q_KEY_CODE_DOT] = ADB_KEY_PERIOD,
|
||||
[Q_KEY_CODE_SLASH] = ADB_KEY_FORWARD_SLASH,
|
||||
[Q_KEY_CODE_ASTERISK] = ADB_KEY_KP_MULTIPLY,
|
||||
[Q_KEY_CODE_CAPS_LOCK] = ADB_KEY_CAPS_LOCK,
|
||||
|
||||
[Q_KEY_CODE_F1] = ADB_KEY_F1,
|
||||
[Q_KEY_CODE_F2] = ADB_KEY_F2,
|
||||
[Q_KEY_CODE_F3] = ADB_KEY_F3,
|
||||
[Q_KEY_CODE_F4] = ADB_KEY_F4,
|
||||
[Q_KEY_CODE_F5] = ADB_KEY_F5,
|
||||
[Q_KEY_CODE_F6] = ADB_KEY_F6,
|
||||
[Q_KEY_CODE_F7] = ADB_KEY_F7,
|
||||
[Q_KEY_CODE_F8] = ADB_KEY_F8,
|
||||
[Q_KEY_CODE_F9] = ADB_KEY_F9,
|
||||
[Q_KEY_CODE_F10] = ADB_KEY_F10,
|
||||
[Q_KEY_CODE_F11] = ADB_KEY_F11,
|
||||
[Q_KEY_CODE_F12] = ADB_KEY_F12,
|
||||
[Q_KEY_CODE_PRINT] = ADB_KEY_F13,
|
||||
[Q_KEY_CODE_SYSRQ] = ADB_KEY_F13,
|
||||
[Q_KEY_CODE_SCROLL_LOCK] = ADB_KEY_F14,
|
||||
[Q_KEY_CODE_PAUSE] = ADB_KEY_F15,
|
||||
|
||||
[Q_KEY_CODE_NUM_LOCK] = ADB_KEY_KP_CLEAR,
|
||||
[Q_KEY_CODE_KP_EQUALS] = ADB_KEY_KP_EQUAL,
|
||||
[Q_KEY_CODE_KP_DIVIDE] = ADB_KEY_KP_DIVIDE,
|
||||
[Q_KEY_CODE_KP_MULTIPLY] = ADB_KEY_KP_MULTIPLY,
|
||||
[Q_KEY_CODE_KP_SUBTRACT] = ADB_KEY_KP_SUBTRACT,
|
||||
[Q_KEY_CODE_KP_ADD] = ADB_KEY_KP_PLUS,
|
||||
[Q_KEY_CODE_KP_ENTER] = ADB_KEY_KP_ENTER,
|
||||
[Q_KEY_CODE_KP_DECIMAL] = ADB_KEY_KP_PERIOD,
|
||||
[Q_KEY_CODE_KP_0] = ADB_KEY_KP_0,
|
||||
[Q_KEY_CODE_KP_1] = ADB_KEY_KP_1,
|
||||
[Q_KEY_CODE_KP_2] = ADB_KEY_KP_2,
|
||||
[Q_KEY_CODE_KP_3] = ADB_KEY_KP_3,
|
||||
[Q_KEY_CODE_KP_4] = ADB_KEY_KP_4,
|
||||
[Q_KEY_CODE_KP_5] = ADB_KEY_KP_5,
|
||||
[Q_KEY_CODE_KP_6] = ADB_KEY_KP_6,
|
||||
[Q_KEY_CODE_KP_7] = ADB_KEY_KP_7,
|
||||
[Q_KEY_CODE_KP_8] = ADB_KEY_KP_8,
|
||||
[Q_KEY_CODE_KP_9] = ADB_KEY_KP_9,
|
||||
|
||||
[Q_KEY_CODE_UP] = ADB_KEY_UP,
|
||||
[Q_KEY_CODE_DOWN] = ADB_KEY_DOWN,
|
||||
[Q_KEY_CODE_LEFT] = ADB_KEY_LEFT,
|
||||
[Q_KEY_CODE_RIGHT] = ADB_KEY_RIGHT,
|
||||
|
||||
[Q_KEY_CODE_HELP] = ADB_KEY_HELP,
|
||||
[Q_KEY_CODE_INSERT] = ADB_KEY_HELP,
|
||||
[Q_KEY_CODE_DELETE] = ADB_KEY_FORWARD_DELETE,
|
||||
[Q_KEY_CODE_HOME] = ADB_KEY_HOME,
|
||||
[Q_KEY_CODE_END] = ADB_KEY_END,
|
||||
[Q_KEY_CODE_PGUP] = ADB_KEY_PAGE_UP,
|
||||
[Q_KEY_CODE_PGDN] = ADB_KEY_PAGE_DOWN,
|
||||
|
||||
[Q_KEY_CODE_POWER] = ADB_KEY_POWER
|
||||
};
|
||||
|
||||
static void adb_kbd_put_keycode(void *opaque, int keycode)
|
||||
@@ -220,35 +328,40 @@ static void adb_kbd_put_keycode(void *opaque, int keycode)
|
||||
|
||||
static int adb_kbd_poll(ADBDevice *d, uint8_t *obuf)
|
||||
{
|
||||
static int ext_keycode;
|
||||
KBDState *s = ADB_KEYBOARD(d);
|
||||
int adb_keycode, keycode;
|
||||
int keycode;
|
||||
int olen;
|
||||
|
||||
olen = 0;
|
||||
for(;;) {
|
||||
if (s->count == 0)
|
||||
break;
|
||||
keycode = s->data[s->rptr];
|
||||
if (++s->rptr == sizeof(s->data))
|
||||
s->rptr = 0;
|
||||
s->count--;
|
||||
|
||||
if (keycode == 0xe0) {
|
||||
ext_keycode = 1;
|
||||
} else {
|
||||
if (ext_keycode)
|
||||
adb_keycode = pc_to_adb_keycode[keycode | 0x80];
|
||||
else
|
||||
adb_keycode = pc_to_adb_keycode[keycode & 0x7f];
|
||||
obuf[0] = adb_keycode | (keycode & 0x80);
|
||||
/* NOTE: could put a second keycode if needed */
|
||||
obuf[1] = 0xff;
|
||||
olen = 2;
|
||||
ext_keycode = 0;
|
||||
break;
|
||||
}
|
||||
if (s->count == 0) {
|
||||
return 0;
|
||||
}
|
||||
keycode = s->data[s->rptr];
|
||||
s->rptr++;
|
||||
if (s->rptr == sizeof(s->data)) {
|
||||
s->rptr = 0;
|
||||
}
|
||||
s->count--;
|
||||
/*
|
||||
* The power key is the only two byte value key, so it is a special case.
|
||||
* Since 0x7f is not a used keycode for ADB we overload it to indicate the
|
||||
* power button when we're storing keycodes in our internal buffer, and
|
||||
* expand it out to two bytes when we send to the guest.
|
||||
*/
|
||||
if (keycode == 0x7f) {
|
||||
obuf[0] = 0x7f;
|
||||
obuf[1] = 0x7f;
|
||||
olen = 2;
|
||||
} else {
|
||||
obuf[0] = keycode;
|
||||
/* NOTE: the power key key-up is the two byte sequence 0xff 0xff;
|
||||
* otherwise we could in theory send a second keycode in the second
|
||||
* byte, but choose not to bother.
|
||||
*/
|
||||
obuf[1] = 0xff;
|
||||
olen = 2;
|
||||
}
|
||||
|
||||
return olen;
|
||||
}
|
||||
|
||||
@@ -313,6 +426,29 @@ static int adb_kbd_request(ADBDevice *d, uint8_t *obuf,
|
||||
return olen;
|
||||
}
|
||||
|
||||
/* This is where keyboard events enter this file */
|
||||
static void adb_keyboard_event(DeviceState *dev, QemuConsole *src,
|
||||
InputEvent *evt)
|
||||
{
|
||||
KBDState *s = (KBDState *)dev;
|
||||
int qcode, keycode;
|
||||
|
||||
qcode = qemu_input_key_value_to_qcode(evt->u.key.data->key);
|
||||
if (qcode >= ARRAY_SIZE(qcode_to_adb_keycode)) {
|
||||
return;
|
||||
}
|
||||
keycode = qcode_to_adb_keycode[qcode];
|
||||
if (keycode == NO_KEY) { /* We don't want to send this to the guest */
|
||||
ADB_DPRINTF("Ignoring NO_KEY\n");
|
||||
return;
|
||||
}
|
||||
if (evt->u.key.data->down == false) { /* if key release event */
|
||||
keycode = keycode | 0x80; /* create keyboard break code */
|
||||
}
|
||||
|
||||
adb_kbd_put_keycode(s, keycode);
|
||||
}
|
||||
|
||||
static const VMStateDescription vmstate_adb_kbd = {
|
||||
.name = "adb_kbd",
|
||||
.version_id = 2,
|
||||
@@ -340,14 +476,17 @@ static void adb_kbd_reset(DeviceState *dev)
|
||||
s->count = 0;
|
||||
}
|
||||
|
||||
static QemuInputHandler adb_keyboard_handler = {
|
||||
.name = "QEMU ADB Keyboard",
|
||||
.mask = INPUT_EVENT_MASK_KEY,
|
||||
.event = adb_keyboard_event,
|
||||
};
|
||||
|
||||
static void adb_kbd_realizefn(DeviceState *dev, Error **errp)
|
||||
{
|
||||
ADBDevice *d = ADB_DEVICE(dev);
|
||||
ADBKeyboardClass *akc = ADB_KEYBOARD_GET_CLASS(dev);
|
||||
|
||||
akc->parent_realize(dev, errp);
|
||||
|
||||
qemu_add_kbd_event_handler(adb_kbd_put_keycode, d);
|
||||
qemu_input_handler_register(dev, &adb_keyboard_handler);
|
||||
}
|
||||
|
||||
static void adb_kbd_initfn(Object *obj)
|
||||
|
612
hw/input/ps2.c
612
hw/input/ps2.c
@@ -22,6 +22,7 @@
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
#include "qemu/osdep.h"
|
||||
#include "qemu/log.h"
|
||||
#include "hw/hw.h"
|
||||
#include "hw/input/ps2.h"
|
||||
#include "ui/console.h"
|
||||
@@ -94,12 +95,10 @@ typedef struct {
|
||||
typedef struct {
|
||||
PS2State common;
|
||||
int scan_enabled;
|
||||
/* QEMU uses translated PC scancodes internally. To avoid multiple
|
||||
conversions we do the translation (if any) in the PS/2 emulation
|
||||
not the keyboard controller. */
|
||||
int translate;
|
||||
int scancode_set; /* 1=XT, 2=AT, 3=PS/2 */
|
||||
int ledstate;
|
||||
bool need_high_bit;
|
||||
} PS2KbdState;
|
||||
|
||||
typedef struct {
|
||||
@@ -116,26 +115,430 @@ typedef struct {
|
||||
uint8_t mouse_buttons;
|
||||
} PS2MouseState;
|
||||
|
||||
/* Table to convert from PC scancodes to raw scancodes. */
|
||||
static const unsigned char ps2_raw_keycode[128] = {
|
||||
0, 118, 22, 30, 38, 37, 46, 54, 61, 62, 70, 69, 78, 85, 102, 13,
|
||||
21, 29, 36, 45, 44, 53, 60, 67, 68, 77, 84, 91, 90, 20, 28, 27,
|
||||
35, 43, 52, 51, 59, 66, 75, 76, 82, 14, 18, 93, 26, 34, 33, 42,
|
||||
50, 49, 58, 65, 73, 74, 89, 124, 17, 41, 88, 5, 6, 4, 12, 3,
|
||||
11, 2, 10, 1, 9, 119, 126, 108, 117, 125, 123, 107, 115, 116, 121, 105,
|
||||
114, 122, 112, 113, 127, 96, 97, 120, 7, 15, 23, 31, 39, 47, 55, 63,
|
||||
71, 79, 86, 94, 8, 16, 24, 32, 40, 48, 56, 64, 72, 80, 87, 111,
|
||||
19, 25, 57, 81, 83, 92, 95, 98, 99, 100, 101, 103, 104, 106, 109, 110
|
||||
/* Table to convert from QEMU codes to scancodes. */
|
||||
static const uint16_t qcode_to_keycode_set1[Q_KEY_CODE__MAX] = {
|
||||
[0 ... Q_KEY_CODE__MAX - 1] = 0,
|
||||
|
||||
[Q_KEY_CODE_A] = 0x1e,
|
||||
[Q_KEY_CODE_B] = 0x30,
|
||||
[Q_KEY_CODE_C] = 0x2e,
|
||||
[Q_KEY_CODE_D] = 0x20,
|
||||
[Q_KEY_CODE_E] = 0x12,
|
||||
[Q_KEY_CODE_F] = 0x21,
|
||||
[Q_KEY_CODE_G] = 0x22,
|
||||
[Q_KEY_CODE_H] = 0x23,
|
||||
[Q_KEY_CODE_I] = 0x17,
|
||||
[Q_KEY_CODE_J] = 0x24,
|
||||
[Q_KEY_CODE_K] = 0x25,
|
||||
[Q_KEY_CODE_L] = 0x26,
|
||||
[Q_KEY_CODE_M] = 0x32,
|
||||
[Q_KEY_CODE_N] = 0x31,
|
||||
[Q_KEY_CODE_O] = 0x18,
|
||||
[Q_KEY_CODE_P] = 0x19,
|
||||
[Q_KEY_CODE_Q] = 0x10,
|
||||
[Q_KEY_CODE_R] = 0x13,
|
||||
[Q_KEY_CODE_S] = 0x1f,
|
||||
[Q_KEY_CODE_T] = 0x14,
|
||||
[Q_KEY_CODE_U] = 0x16,
|
||||
[Q_KEY_CODE_V] = 0x2f,
|
||||
[Q_KEY_CODE_W] = 0x11,
|
||||
[Q_KEY_CODE_X] = 0x2d,
|
||||
[Q_KEY_CODE_Y] = 0x15,
|
||||
[Q_KEY_CODE_Z] = 0x2c,
|
||||
[Q_KEY_CODE_0] = 0x0b,
|
||||
[Q_KEY_CODE_1] = 0x02,
|
||||
[Q_KEY_CODE_2] = 0x03,
|
||||
[Q_KEY_CODE_3] = 0x04,
|
||||
[Q_KEY_CODE_4] = 0x05,
|
||||
[Q_KEY_CODE_5] = 0x06,
|
||||
[Q_KEY_CODE_6] = 0x07,
|
||||
[Q_KEY_CODE_7] = 0x08,
|
||||
[Q_KEY_CODE_8] = 0x09,
|
||||
[Q_KEY_CODE_9] = 0x0a,
|
||||
[Q_KEY_CODE_GRAVE_ACCENT] = 0x29,
|
||||
[Q_KEY_CODE_MINUS] = 0x0c,
|
||||
[Q_KEY_CODE_EQUAL] = 0x0d,
|
||||
[Q_KEY_CODE_BACKSLASH] = 0x2b,
|
||||
[Q_KEY_CODE_BACKSPACE] = 0x0e,
|
||||
[Q_KEY_CODE_SPC] = 0x39,
|
||||
[Q_KEY_CODE_TAB] = 0x0f,
|
||||
[Q_KEY_CODE_CAPS_LOCK] = 0x3a,
|
||||
[Q_KEY_CODE_SHIFT] = 0x2a,
|
||||
[Q_KEY_CODE_CTRL] = 0x1d,
|
||||
[Q_KEY_CODE_META_L] = 0xe05b,
|
||||
[Q_KEY_CODE_ALT] = 0x38,
|
||||
[Q_KEY_CODE_SHIFT_R] = 0x36,
|
||||
[Q_KEY_CODE_CTRL_R] = 0xe01d,
|
||||
[Q_KEY_CODE_META_R] = 0xe05c,
|
||||
[Q_KEY_CODE_ALT_R] = 0xe038,
|
||||
[Q_KEY_CODE_MENU] = 0xe05d,
|
||||
[Q_KEY_CODE_RET] = 0x1c,
|
||||
[Q_KEY_CODE_ESC] = 0x01,
|
||||
[Q_KEY_CODE_F1] = 0x3b,
|
||||
[Q_KEY_CODE_F2] = 0x3c,
|
||||
[Q_KEY_CODE_F3] = 0x3d,
|
||||
[Q_KEY_CODE_F4] = 0x3e,
|
||||
[Q_KEY_CODE_F5] = 0x3f,
|
||||
[Q_KEY_CODE_F6] = 0x40,
|
||||
[Q_KEY_CODE_F7] = 0x41,
|
||||
[Q_KEY_CODE_F8] = 0x42,
|
||||
[Q_KEY_CODE_F9] = 0x43,
|
||||
[Q_KEY_CODE_F10] = 0x44,
|
||||
[Q_KEY_CODE_F11] = 0x57,
|
||||
[Q_KEY_CODE_F12] = 0x58,
|
||||
/* special handling for Q_KEY_CODE_PRINT */
|
||||
[Q_KEY_CODE_SCROLL_LOCK] = 0x46,
|
||||
/* special handling for Q_KEY_CODE_PAUSE */
|
||||
[Q_KEY_CODE_BRACKET_LEFT] = 0x1a,
|
||||
[Q_KEY_CODE_INSERT] = 0xe052,
|
||||
[Q_KEY_CODE_HOME] = 0xe047,
|
||||
[Q_KEY_CODE_PGUP] = 0xe049,
|
||||
[Q_KEY_CODE_DELETE] = 0xe053,
|
||||
[Q_KEY_CODE_END] = 0xe04f,
|
||||
[Q_KEY_CODE_PGDN] = 0xe051,
|
||||
[Q_KEY_CODE_UP] = 0xe048,
|
||||
[Q_KEY_CODE_LEFT] = 0xe04b,
|
||||
[Q_KEY_CODE_DOWN] = 0xe050,
|
||||
[Q_KEY_CODE_RIGHT] = 0xe04d,
|
||||
[Q_KEY_CODE_NUM_LOCK] = 0x45,
|
||||
[Q_KEY_CODE_KP_DIVIDE] = 0xe035,
|
||||
[Q_KEY_CODE_KP_MULTIPLY] = 0x37,
|
||||
[Q_KEY_CODE_KP_SUBTRACT] = 0x4a,
|
||||
[Q_KEY_CODE_KP_ADD] = 0x4e,
|
||||
[Q_KEY_CODE_KP_ENTER] = 0xe01c,
|
||||
[Q_KEY_CODE_KP_DECIMAL] = 0x53,
|
||||
[Q_KEY_CODE_KP_0] = 0x52,
|
||||
[Q_KEY_CODE_KP_1] = 0x4f,
|
||||
[Q_KEY_CODE_KP_2] = 0x50,
|
||||
[Q_KEY_CODE_KP_3] = 0x51,
|
||||
[Q_KEY_CODE_KP_4] = 0x4b,
|
||||
[Q_KEY_CODE_KP_5] = 0x4c,
|
||||
[Q_KEY_CODE_KP_6] = 0x4d,
|
||||
[Q_KEY_CODE_KP_7] = 0x47,
|
||||
[Q_KEY_CODE_KP_8] = 0x48,
|
||||
[Q_KEY_CODE_KP_9] = 0x49,
|
||||
[Q_KEY_CODE_BRACKET_RIGHT] = 0x1b,
|
||||
[Q_KEY_CODE_SEMICOLON] = 0x27,
|
||||
[Q_KEY_CODE_APOSTROPHE] = 0x28,
|
||||
[Q_KEY_CODE_COMMA] = 0x33,
|
||||
[Q_KEY_CODE_DOT] = 0x34,
|
||||
[Q_KEY_CODE_SLASH] = 0x35,
|
||||
|
||||
#if 0
|
||||
[Q_KEY_CODE_POWER] = 0x0e5e,
|
||||
[Q_KEY_CODE_SLEEP] = 0x0e5f,
|
||||
[Q_KEY_CODE_WAKE] = 0x0e63,
|
||||
|
||||
[Q_KEY_CODE_AUDIONEXT] = 0xe019,
|
||||
[Q_KEY_CODE_AUDIOPREV] = 0xe010,
|
||||
[Q_KEY_CODE_AUDIOSTOP] = 0xe024,
|
||||
[Q_KEY_CODE_AUDIOPLAY] = 0xe022,
|
||||
[Q_KEY_CODE_AUDIOMUTE] = 0xe020,
|
||||
[Q_KEY_CODE_VOLUMEUP] = 0xe030,
|
||||
[Q_KEY_CODE_VOLUMEDOWN] = 0xe02e,
|
||||
[Q_KEY_CODE_MEDIASELECT] = 0xe06d,
|
||||
[Q_KEY_CODE_MAIL] = 0xe06c,
|
||||
[Q_KEY_CODE_CALCULATOR] = 0xe021,
|
||||
[Q_KEY_CODE_COMPUTER] = 0xe06b,
|
||||
[Q_KEY_CODE_AC_SEARCH] = 0xe065,
|
||||
[Q_KEY_CODE_AC_HOME] = 0xe032,
|
||||
[Q_KEY_CODE_AC_BACK] = 0xe06a,
|
||||
[Q_KEY_CODE_AC_FORWARD] = 0xe069,
|
||||
[Q_KEY_CODE_AC_STOP] = 0xe068,
|
||||
[Q_KEY_CODE_AC_REFRESH] = 0xe067,
|
||||
[Q_KEY_CODE_AC_BOOKMARKS] = 0xe066,
|
||||
#endif
|
||||
|
||||
[Q_KEY_CODE_ASTERISK] = 0x37,
|
||||
[Q_KEY_CODE_LESS] = 0x56,
|
||||
[Q_KEY_CODE_RO] = 0x73,
|
||||
[Q_KEY_CODE_KP_COMMA] = 0x7e,
|
||||
};
|
||||
static const unsigned char ps2_raw_keycode_set3[128] = {
|
||||
0, 8, 22, 30, 38, 37, 46, 54, 61, 62, 70, 69, 78, 85, 102, 13,
|
||||
21, 29, 36, 45, 44, 53, 60, 67, 68, 77, 84, 91, 90, 17, 28, 27,
|
||||
35, 43, 52, 51, 59, 66, 75, 76, 82, 14, 18, 92, 26, 34, 33, 42,
|
||||
50, 49, 58, 65, 73, 74, 89, 126, 25, 41, 20, 7, 15, 23, 31, 39,
|
||||
47, 2, 63, 71, 79, 118, 95, 108, 117, 125, 132, 107, 115, 116, 124, 105,
|
||||
114, 122, 112, 113, 127, 96, 97, 86, 94, 15, 23, 31, 39, 47, 55, 63,
|
||||
71, 79, 86, 94, 8, 16, 24, 32, 40, 48, 56, 64, 72, 80, 87, 111,
|
||||
19, 25, 57, 81, 83, 92, 95, 98, 99, 100, 101, 103, 104, 106, 109, 110
|
||||
|
||||
static const uint16_t qcode_to_keycode_set2[Q_KEY_CODE__MAX] = {
|
||||
[0 ... Q_KEY_CODE__MAX - 1] = 0,
|
||||
|
||||
[Q_KEY_CODE_A] = 0x1c,
|
||||
[Q_KEY_CODE_B] = 0x32,
|
||||
[Q_KEY_CODE_C] = 0x21,
|
||||
[Q_KEY_CODE_D] = 0x23,
|
||||
[Q_KEY_CODE_E] = 0x24,
|
||||
[Q_KEY_CODE_F] = 0x2b,
|
||||
[Q_KEY_CODE_G] = 0x34,
|
||||
[Q_KEY_CODE_H] = 0x33,
|
||||
[Q_KEY_CODE_I] = 0x43,
|
||||
[Q_KEY_CODE_J] = 0x3b,
|
||||
[Q_KEY_CODE_K] = 0x42,
|
||||
[Q_KEY_CODE_L] = 0x4b,
|
||||
[Q_KEY_CODE_M] = 0x3a,
|
||||
[Q_KEY_CODE_N] = 0x31,
|
||||
[Q_KEY_CODE_O] = 0x44,
|
||||
[Q_KEY_CODE_P] = 0x4d,
|
||||
[Q_KEY_CODE_Q] = 0x15,
|
||||
[Q_KEY_CODE_R] = 0x2d,
|
||||
[Q_KEY_CODE_S] = 0x1b,
|
||||
[Q_KEY_CODE_T] = 0x2c,
|
||||
[Q_KEY_CODE_U] = 0x3c,
|
||||
[Q_KEY_CODE_V] = 0x2a,
|
||||
[Q_KEY_CODE_W] = 0x1d,
|
||||
[Q_KEY_CODE_X] = 0x22,
|
||||
[Q_KEY_CODE_Y] = 0x35,
|
||||
[Q_KEY_CODE_Z] = 0x1a,
|
||||
[Q_KEY_CODE_0] = 0x45,
|
||||
[Q_KEY_CODE_1] = 0x16,
|
||||
[Q_KEY_CODE_2] = 0x1e,
|
||||
[Q_KEY_CODE_3] = 0x26,
|
||||
[Q_KEY_CODE_4] = 0x25,
|
||||
[Q_KEY_CODE_5] = 0x2e,
|
||||
[Q_KEY_CODE_6] = 0x36,
|
||||
[Q_KEY_CODE_7] = 0x3d,
|
||||
[Q_KEY_CODE_8] = 0x3e,
|
||||
[Q_KEY_CODE_9] = 0x46,
|
||||
[Q_KEY_CODE_GRAVE_ACCENT] = 0x0e,
|
||||
[Q_KEY_CODE_MINUS] = 0x4e,
|
||||
[Q_KEY_CODE_EQUAL] = 0x55,
|
||||
[Q_KEY_CODE_BACKSLASH] = 0x5d,
|
||||
[Q_KEY_CODE_BACKSPACE] = 0x66,
|
||||
[Q_KEY_CODE_SPC] = 0x29,
|
||||
[Q_KEY_CODE_TAB] = 0x0d,
|
||||
[Q_KEY_CODE_CAPS_LOCK] = 0x58,
|
||||
[Q_KEY_CODE_SHIFT] = 0x12,
|
||||
[Q_KEY_CODE_CTRL] = 0x14,
|
||||
[Q_KEY_CODE_META_L] = 0xe01f,
|
||||
[Q_KEY_CODE_ALT] = 0x11,
|
||||
[Q_KEY_CODE_SHIFT_R] = 0x59,
|
||||
[Q_KEY_CODE_CTRL_R] = 0xe014,
|
||||
[Q_KEY_CODE_META_R] = 0xe027,
|
||||
[Q_KEY_CODE_ALT_R] = 0xe011,
|
||||
[Q_KEY_CODE_MENU] = 0xe02f,
|
||||
[Q_KEY_CODE_RET] = 0x5a,
|
||||
[Q_KEY_CODE_ESC] = 0x76,
|
||||
[Q_KEY_CODE_F1] = 0x05,
|
||||
[Q_KEY_CODE_F2] = 0x06,
|
||||
[Q_KEY_CODE_F3] = 0x04,
|
||||
[Q_KEY_CODE_F4] = 0x0c,
|
||||
[Q_KEY_CODE_F5] = 0x03,
|
||||
[Q_KEY_CODE_F6] = 0x0b,
|
||||
[Q_KEY_CODE_F7] = 0x83,
|
||||
[Q_KEY_CODE_F8] = 0x0a,
|
||||
[Q_KEY_CODE_F9] = 0x01,
|
||||
[Q_KEY_CODE_F10] = 0x09,
|
||||
[Q_KEY_CODE_F11] = 0x78,
|
||||
[Q_KEY_CODE_F12] = 0x07,
|
||||
/* special handling for Q_KEY_CODE_PRINT */
|
||||
[Q_KEY_CODE_SCROLL_LOCK] = 0x7e,
|
||||
/* special handling for Q_KEY_CODE_PAUSE */
|
||||
[Q_KEY_CODE_BRACKET_LEFT] = 0x54,
|
||||
[Q_KEY_CODE_INSERT] = 0xe070,
|
||||
[Q_KEY_CODE_HOME] = 0xe06c,
|
||||
[Q_KEY_CODE_PGUP] = 0xe07d,
|
||||
[Q_KEY_CODE_DELETE] = 0xe071,
|
||||
[Q_KEY_CODE_END] = 0xe069,
|
||||
[Q_KEY_CODE_PGDN] = 0xe07a,
|
||||
[Q_KEY_CODE_UP] = 0xe075,
|
||||
[Q_KEY_CODE_LEFT] = 0xe06b,
|
||||
[Q_KEY_CODE_DOWN] = 0xe072,
|
||||
[Q_KEY_CODE_RIGHT] = 0xe074,
|
||||
[Q_KEY_CODE_NUM_LOCK] = 0x77,
|
||||
[Q_KEY_CODE_KP_DIVIDE] = 0xe04a,
|
||||
[Q_KEY_CODE_KP_MULTIPLY] = 0x7c,
|
||||
[Q_KEY_CODE_KP_SUBTRACT] = 0x7b,
|
||||
[Q_KEY_CODE_KP_ADD] = 0x79,
|
||||
[Q_KEY_CODE_KP_ENTER] = 0xe05a,
|
||||
[Q_KEY_CODE_KP_DECIMAL] = 0x71,
|
||||
[Q_KEY_CODE_KP_0] = 0x70,
|
||||
[Q_KEY_CODE_KP_1] = 0x69,
|
||||
[Q_KEY_CODE_KP_2] = 0x72,
|
||||
[Q_KEY_CODE_KP_3] = 0x7a,
|
||||
[Q_KEY_CODE_KP_4] = 0x6b,
|
||||
[Q_KEY_CODE_KP_5] = 0x73,
|
||||
[Q_KEY_CODE_KP_6] = 0x74,
|
||||
[Q_KEY_CODE_KP_7] = 0x6c,
|
||||
[Q_KEY_CODE_KP_8] = 0x75,
|
||||
[Q_KEY_CODE_KP_9] = 0x7d,
|
||||
[Q_KEY_CODE_BRACKET_RIGHT] = 0x5b,
|
||||
[Q_KEY_CODE_SEMICOLON] = 0x4c,
|
||||
[Q_KEY_CODE_APOSTROPHE] = 0x52,
|
||||
[Q_KEY_CODE_COMMA] = 0x41,
|
||||
[Q_KEY_CODE_DOT] = 0x49,
|
||||
[Q_KEY_CODE_SLASH] = 0x4a,
|
||||
|
||||
#if 0
|
||||
[Q_KEY_CODE_POWER] = 0x0e37,
|
||||
[Q_KEY_CODE_SLEEP] = 0x0e3f,
|
||||
[Q_KEY_CODE_WAKE] = 0x0e5e,
|
||||
|
||||
[Q_KEY_CODE_AUDIONEXT] = 0xe04d,
|
||||
[Q_KEY_CODE_AUDIOPREV] = 0xe015,
|
||||
[Q_KEY_CODE_AUDIOSTOP] = 0xe03b,
|
||||
[Q_KEY_CODE_AUDIOPLAY] = 0xe034,
|
||||
[Q_KEY_CODE_AUDIOMUTE] = 0xe023,
|
||||
[Q_KEY_CODE_VOLUMEUP] = 0xe032,
|
||||
[Q_KEY_CODE_VOLUMEDOWN] = 0xe021,
|
||||
[Q_KEY_CODE_MEDIASELECT] = 0xe050,
|
||||
[Q_KEY_CODE_MAIL] = 0xe048,
|
||||
[Q_KEY_CODE_CALCULATOR] = 0xe02b,
|
||||
[Q_KEY_CODE_COMPUTER] = 0xe040,
|
||||
[Q_KEY_CODE_AC_SEARCH] = 0xe010,
|
||||
[Q_KEY_CODE_AC_HOME] = 0xe03a,
|
||||
[Q_KEY_CODE_AC_BACK] = 0xe038,
|
||||
[Q_KEY_CODE_AC_FORWARD] = 0xe030,
|
||||
[Q_KEY_CODE_AC_STOP] = 0xe028,
|
||||
[Q_KEY_CODE_AC_REFRESH] = 0xe020,
|
||||
[Q_KEY_CODE_AC_BOOKMARKS] = 0xe018,
|
||||
#endif
|
||||
|
||||
[Q_KEY_CODE_ALTGR] = 0x08,
|
||||
[Q_KEY_CODE_ALTGR_R] = 0xe008,
|
||||
[Q_KEY_CODE_ASTERISK] = 0x7c,
|
||||
[Q_KEY_CODE_LESS] = 0x61,
|
||||
[Q_KEY_CODE_SYSRQ] = 0x7f,
|
||||
[Q_KEY_CODE_RO] = 0x51,
|
||||
[Q_KEY_CODE_KP_COMMA] = 0x6d,
|
||||
};
|
||||
|
||||
static const uint16_t qcode_to_keycode_set3[Q_KEY_CODE__MAX] = {
|
||||
[0 ... Q_KEY_CODE__MAX - 1] = 0,
|
||||
|
||||
[Q_KEY_CODE_A] = 0x1c,
|
||||
[Q_KEY_CODE_B] = 0x32,
|
||||
[Q_KEY_CODE_C] = 0x21,
|
||||
[Q_KEY_CODE_D] = 0x23,
|
||||
[Q_KEY_CODE_E] = 0x24,
|
||||
[Q_KEY_CODE_F] = 0x2b,
|
||||
[Q_KEY_CODE_G] = 0x34,
|
||||
[Q_KEY_CODE_H] = 0x33,
|
||||
[Q_KEY_CODE_I] = 0x43,
|
||||
[Q_KEY_CODE_J] = 0x3b,
|
||||
[Q_KEY_CODE_K] = 0x42,
|
||||
[Q_KEY_CODE_L] = 0x4b,
|
||||
[Q_KEY_CODE_M] = 0x3a,
|
||||
[Q_KEY_CODE_N] = 0x31,
|
||||
[Q_KEY_CODE_O] = 0x44,
|
||||
[Q_KEY_CODE_P] = 0x4d,
|
||||
[Q_KEY_CODE_Q] = 0x15,
|
||||
[Q_KEY_CODE_R] = 0x2d,
|
||||
[Q_KEY_CODE_S] = 0x1b,
|
||||
[Q_KEY_CODE_T] = 0x2c,
|
||||
[Q_KEY_CODE_U] = 0x3c,
|
||||
[Q_KEY_CODE_V] = 0x2a,
|
||||
[Q_KEY_CODE_W] = 0x1d,
|
||||
[Q_KEY_CODE_X] = 0x22,
|
||||
[Q_KEY_CODE_Y] = 0x35,
|
||||
[Q_KEY_CODE_Z] = 0x1a,
|
||||
[Q_KEY_CODE_0] = 0x45,
|
||||
[Q_KEY_CODE_1] = 0x16,
|
||||
[Q_KEY_CODE_2] = 0x1e,
|
||||
[Q_KEY_CODE_3] = 0x26,
|
||||
[Q_KEY_CODE_4] = 0x25,
|
||||
[Q_KEY_CODE_5] = 0x2e,
|
||||
[Q_KEY_CODE_6] = 0x36,
|
||||
[Q_KEY_CODE_7] = 0x3d,
|
||||
[Q_KEY_CODE_8] = 0x3e,
|
||||
[Q_KEY_CODE_9] = 0x46,
|
||||
[Q_KEY_CODE_GRAVE_ACCENT] = 0x0e,
|
||||
[Q_KEY_CODE_MINUS] = 0x4e,
|
||||
[Q_KEY_CODE_EQUAL] = 0x55,
|
||||
[Q_KEY_CODE_BACKSLASH] = 0x5c,
|
||||
[Q_KEY_CODE_BACKSPACE] = 0x66,
|
||||
[Q_KEY_CODE_SPC] = 0x29,
|
||||
[Q_KEY_CODE_TAB] = 0x0d,
|
||||
[Q_KEY_CODE_CAPS_LOCK] = 0x14,
|
||||
[Q_KEY_CODE_SHIFT] = 0x12,
|
||||
[Q_KEY_CODE_CTRL] = 0x11,
|
||||
[Q_KEY_CODE_META_L] = 0x8b,
|
||||
[Q_KEY_CODE_ALT] = 0x19,
|
||||
[Q_KEY_CODE_SHIFT_R] = 0x59,
|
||||
[Q_KEY_CODE_CTRL_R] = 0x58,
|
||||
[Q_KEY_CODE_META_R] = 0x8c,
|
||||
[Q_KEY_CODE_ALT_R] = 0x39,
|
||||
[Q_KEY_CODE_MENU] = 0x8d,
|
||||
[Q_KEY_CODE_RET] = 0x5a,
|
||||
[Q_KEY_CODE_ESC] = 0x08,
|
||||
[Q_KEY_CODE_F1] = 0x07,
|
||||
[Q_KEY_CODE_F2] = 0x0f,
|
||||
[Q_KEY_CODE_F3] = 0x17,
|
||||
[Q_KEY_CODE_F4] = 0x1f,
|
||||
[Q_KEY_CODE_F5] = 0x27,
|
||||
[Q_KEY_CODE_F6] = 0x2f,
|
||||
[Q_KEY_CODE_F7] = 0x37,
|
||||
[Q_KEY_CODE_F8] = 0x3f,
|
||||
[Q_KEY_CODE_F9] = 0x47,
|
||||
[Q_KEY_CODE_F10] = 0x4f,
|
||||
[Q_KEY_CODE_F11] = 0x56,
|
||||
[Q_KEY_CODE_F12] = 0x5e,
|
||||
[Q_KEY_CODE_PRINT] = 0x57,
|
||||
[Q_KEY_CODE_SCROLL_LOCK] = 0x5f,
|
||||
[Q_KEY_CODE_PAUSE] = 0x62,
|
||||
[Q_KEY_CODE_BRACKET_LEFT] = 0x54,
|
||||
[Q_KEY_CODE_INSERT] = 0x67,
|
||||
[Q_KEY_CODE_HOME] = 0x6e,
|
||||
[Q_KEY_CODE_PGUP] = 0x6f,
|
||||
[Q_KEY_CODE_DELETE] = 0x64,
|
||||
[Q_KEY_CODE_END] = 0x65,
|
||||
[Q_KEY_CODE_PGDN] = 0x6d,
|
||||
[Q_KEY_CODE_UP] = 0x63,
|
||||
[Q_KEY_CODE_LEFT] = 0x61,
|
||||
[Q_KEY_CODE_DOWN] = 0x60,
|
||||
[Q_KEY_CODE_RIGHT] = 0x6a,
|
||||
[Q_KEY_CODE_NUM_LOCK] = 0x76,
|
||||
[Q_KEY_CODE_KP_DIVIDE] = 0x4a,
|
||||
[Q_KEY_CODE_KP_MULTIPLY] = 0x7e,
|
||||
[Q_KEY_CODE_KP_SUBTRACT] = 0x4e,
|
||||
[Q_KEY_CODE_KP_ADD] = 0x7c,
|
||||
[Q_KEY_CODE_KP_ENTER] = 0x79,
|
||||
[Q_KEY_CODE_KP_DECIMAL] = 0x71,
|
||||
[Q_KEY_CODE_KP_0] = 0x70,
|
||||
[Q_KEY_CODE_KP_1] = 0x69,
|
||||
[Q_KEY_CODE_KP_2] = 0x72,
|
||||
[Q_KEY_CODE_KP_3] = 0x7a,
|
||||
[Q_KEY_CODE_KP_4] = 0x6b,
|
||||
[Q_KEY_CODE_KP_5] = 0x73,
|
||||
[Q_KEY_CODE_KP_6] = 0x74,
|
||||
[Q_KEY_CODE_KP_7] = 0x6c,
|
||||
[Q_KEY_CODE_KP_8] = 0x75,
|
||||
[Q_KEY_CODE_KP_9] = 0x7d,
|
||||
[Q_KEY_CODE_BRACKET_RIGHT] = 0x5b,
|
||||
[Q_KEY_CODE_SEMICOLON] = 0x4c,
|
||||
[Q_KEY_CODE_APOSTROPHE] = 0x52,
|
||||
[Q_KEY_CODE_COMMA] = 0x41,
|
||||
[Q_KEY_CODE_DOT] = 0x49,
|
||||
[Q_KEY_CODE_SLASH] = 0x4a,
|
||||
};
|
||||
|
||||
static uint8_t translate_table[256] = {
|
||||
0xff, 0x43, 0x41, 0x3f, 0x3d, 0x3b, 0x3c, 0x58,
|
||||
0x64, 0x44, 0x42, 0x40, 0x3e, 0x0f, 0x29, 0x59,
|
||||
0x65, 0x38, 0x2a, 0x70, 0x1d, 0x10, 0x02, 0x5a,
|
||||
0x66, 0x71, 0x2c, 0x1f, 0x1e, 0x11, 0x03, 0x5b,
|
||||
0x67, 0x2e, 0x2d, 0x20, 0x12, 0x05, 0x04, 0x5c,
|
||||
0x68, 0x39, 0x2f, 0x21, 0x14, 0x13, 0x06, 0x5d,
|
||||
0x69, 0x31, 0x30, 0x23, 0x22, 0x15, 0x07, 0x5e,
|
||||
0x6a, 0x72, 0x32, 0x24, 0x16, 0x08, 0x09, 0x5f,
|
||||
0x6b, 0x33, 0x25, 0x17, 0x18, 0x0b, 0x0a, 0x60,
|
||||
0x6c, 0x34, 0x35, 0x26, 0x27, 0x19, 0x0c, 0x61,
|
||||
0x6d, 0x73, 0x28, 0x74, 0x1a, 0x0d, 0x62, 0x6e,
|
||||
0x3a, 0x36, 0x1c, 0x1b, 0x75, 0x2b, 0x63, 0x76,
|
||||
0x55, 0x56, 0x77, 0x78, 0x79, 0x7a, 0x0e, 0x7b,
|
||||
0x7c, 0x4f, 0x7d, 0x4b, 0x47, 0x7e, 0x7f, 0x6f,
|
||||
0x52, 0x53, 0x50, 0x4c, 0x4d, 0x48, 0x01, 0x45,
|
||||
0x57, 0x4e, 0x51, 0x4a, 0x37, 0x49, 0x46, 0x54,
|
||||
0x80, 0x81, 0x82, 0x41, 0x54, 0x85, 0x86, 0x87,
|
||||
0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
|
||||
0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
|
||||
0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
|
||||
0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
|
||||
0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
|
||||
0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
|
||||
0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
|
||||
0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
|
||||
0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
|
||||
0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
|
||||
0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
|
||||
0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
|
||||
0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
|
||||
0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
|
||||
0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
|
||||
};
|
||||
|
||||
void ps2_queue(void *opaque, int b)
|
||||
@@ -152,44 +555,130 @@ void ps2_queue(void *opaque, int b)
|
||||
s->update_irq(s->update_arg, 1);
|
||||
}
|
||||
|
||||
/*
|
||||
keycode is expressed as follow:
|
||||
bit 7 - 0 key pressed, 1 = key released
|
||||
bits 6-0 - translated scancode set 2
|
||||
*/
|
||||
/* keycode is the untranslated scancode in the current scancode set. */
|
||||
static void ps2_put_keycode(void *opaque, int keycode)
|
||||
{
|
||||
PS2KbdState *s = opaque;
|
||||
|
||||
trace_ps2_put_keycode(opaque, keycode);
|
||||
qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER);
|
||||
/* XXX: add support for scancode set 1 */
|
||||
if (!s->translate && keycode < 0xe0 && s->scancode_set > 1) {
|
||||
if (keycode & 0x80) {
|
||||
ps2_queue(&s->common, 0xf0);
|
||||
|
||||
if (s->translate) {
|
||||
if (keycode == 0xf0) {
|
||||
s->need_high_bit = true;
|
||||
} else if (s->need_high_bit) {
|
||||
ps2_queue(&s->common, translate_table[keycode] | 0x80);
|
||||
s->need_high_bit = false;
|
||||
} else {
|
||||
ps2_queue(&s->common, translate_table[keycode]);
|
||||
}
|
||||
if (s->scancode_set == 2) {
|
||||
keycode = ps2_raw_keycode[keycode & 0x7f];
|
||||
} else if (s->scancode_set == 3) {
|
||||
keycode = ps2_raw_keycode_set3[keycode & 0x7f];
|
||||
}
|
||||
}
|
||||
ps2_queue(&s->common, keycode);
|
||||
} else {
|
||||
ps2_queue(&s->common, keycode);
|
||||
}
|
||||
}
|
||||
|
||||
static void ps2_keyboard_event(DeviceState *dev, QemuConsole *src,
|
||||
InputEvent *evt)
|
||||
{
|
||||
PS2KbdState *s = (PS2KbdState *)dev;
|
||||
int scancodes[3], i, count;
|
||||
InputKeyEvent *key = evt->u.key.data;
|
||||
int qcode;
|
||||
uint16_t keycode;
|
||||
|
||||
qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER);
|
||||
count = qemu_input_key_value_to_scancode(key->key,
|
||||
key->down,
|
||||
scancodes);
|
||||
for (i = 0; i < count; i++) {
|
||||
ps2_put_keycode(s, scancodes[i]);
|
||||
assert(evt->type == INPUT_EVENT_KIND_KEY);
|
||||
qcode = qemu_input_key_value_to_qcode(key->key);
|
||||
|
||||
if (s->scancode_set == 1) {
|
||||
if (qcode == Q_KEY_CODE_PAUSE) {
|
||||
if (key->down) {
|
||||
ps2_put_keycode(s, 0xe1);
|
||||
ps2_put_keycode(s, 0x1d);
|
||||
ps2_put_keycode(s, 0x45);
|
||||
ps2_put_keycode(s, 0x91);
|
||||
ps2_put_keycode(s, 0x9d);
|
||||
ps2_put_keycode(s, 0xc5);
|
||||
}
|
||||
} else if (qcode == Q_KEY_CODE_PRINT) {
|
||||
if (key->down) {
|
||||
ps2_put_keycode(s, 0xe0);
|
||||
ps2_put_keycode(s, 0x2a);
|
||||
ps2_put_keycode(s, 0xe0);
|
||||
ps2_put_keycode(s, 0x37);
|
||||
} else {
|
||||
ps2_put_keycode(s, 0xe0);
|
||||
ps2_put_keycode(s, 0xb7);
|
||||
ps2_put_keycode(s, 0xe0);
|
||||
ps2_put_keycode(s, 0xaa);
|
||||
}
|
||||
} else {
|
||||
keycode = qcode_to_keycode_set1[qcode];
|
||||
if (keycode) {
|
||||
if (keycode & 0xff00) {
|
||||
ps2_put_keycode(s, keycode >> 8);
|
||||
}
|
||||
if (!key->down) {
|
||||
keycode |= 0x80;
|
||||
}
|
||||
ps2_put_keycode(s, keycode & 0xff);
|
||||
} else {
|
||||
qemu_log_mask(LOG_UNIMP,
|
||||
"ps2: ignoring key with qcode %d\n", qcode);
|
||||
}
|
||||
}
|
||||
} else if (s->scancode_set == 2) {
|
||||
if (qcode == Q_KEY_CODE_PAUSE) {
|
||||
if (key->down) {
|
||||
ps2_put_keycode(s, 0xe1);
|
||||
ps2_put_keycode(s, 0x14);
|
||||
ps2_put_keycode(s, 0x77);
|
||||
ps2_put_keycode(s, 0xe1);
|
||||
ps2_put_keycode(s, 0xf0);
|
||||
ps2_put_keycode(s, 0x14);
|
||||
ps2_put_keycode(s, 0xf0);
|
||||
ps2_put_keycode(s, 0x77);
|
||||
}
|
||||
} else if (qcode == Q_KEY_CODE_PRINT) {
|
||||
if (key->down) {
|
||||
ps2_put_keycode(s, 0xe0);
|
||||
ps2_put_keycode(s, 0x12);
|
||||
ps2_put_keycode(s, 0xe0);
|
||||
ps2_put_keycode(s, 0x7c);
|
||||
} else {
|
||||
ps2_put_keycode(s, 0xe0);
|
||||
ps2_put_keycode(s, 0xf0);
|
||||
ps2_put_keycode(s, 0x7c);
|
||||
ps2_put_keycode(s, 0xe0);
|
||||
ps2_put_keycode(s, 0xf0);
|
||||
ps2_put_keycode(s, 0x12);
|
||||
}
|
||||
} else {
|
||||
keycode = qcode_to_keycode_set2[qcode];
|
||||
if (keycode) {
|
||||
if (keycode & 0xff00) {
|
||||
ps2_put_keycode(s, keycode >> 8);
|
||||
}
|
||||
if (!key->down) {
|
||||
ps2_put_keycode(s, 0xf0);
|
||||
}
|
||||
ps2_put_keycode(s, keycode & 0xff);
|
||||
} else {
|
||||
qemu_log_mask(LOG_UNIMP,
|
||||
"ps2: ignoring key with qcode %d\n", qcode);
|
||||
}
|
||||
}
|
||||
} else if (s->scancode_set == 3) {
|
||||
keycode = qcode_to_keycode_set3[qcode];
|
||||
if (keycode) {
|
||||
/* FIXME: break code should be configured on a key by key basis */
|
||||
if (!key->down) {
|
||||
ps2_put_keycode(s, 0xf0);
|
||||
}
|
||||
ps2_put_keycode(s, keycode);
|
||||
} else {
|
||||
qemu_log_mask(LOG_UNIMP,
|
||||
"ps2: ignoring key with qcode %d\n", qcode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -290,22 +779,19 @@ void ps2_write_keyboard(void *opaque, int val)
|
||||
ps2_queue(&s->common, KBD_REPLY_POR);
|
||||
break;
|
||||
default:
|
||||
ps2_queue(&s->common, KBD_REPLY_ACK);
|
||||
ps2_queue(&s->common, KBD_REPLY_RESEND);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case KBD_CMD_SCANCODE:
|
||||
if (val == 0) {
|
||||
if (s->scancode_set == 1)
|
||||
ps2_put_keycode(s, 0x43);
|
||||
else if (s->scancode_set == 2)
|
||||
ps2_put_keycode(s, 0x41);
|
||||
else if (s->scancode_set == 3)
|
||||
ps2_put_keycode(s, 0x3f);
|
||||
} else {
|
||||
if (val >= 1 && val <= 3)
|
||||
s->scancode_set = val;
|
||||
ps2_queue(&s->common, KBD_REPLY_ACK);
|
||||
ps2_put_keycode(s, s->scancode_set);
|
||||
} else if (val >= 1 && val <= 3) {
|
||||
s->scancode_set = val;
|
||||
ps2_queue(&s->common, KBD_REPLY_ACK);
|
||||
} else {
|
||||
ps2_queue(&s->common, KBD_REPLY_RESEND);
|
||||
}
|
||||
s->common.write_cmd = -1;
|
||||
break;
|
||||
@@ -690,6 +1176,23 @@ static const VMStateDescription vmstate_ps2_keyboard_ledstate = {
|
||||
}
|
||||
};
|
||||
|
||||
static bool ps2_keyboard_need_high_bit_needed(void *opaque)
|
||||
{
|
||||
PS2KbdState *s = opaque;
|
||||
return s->need_high_bit != 0; /* 0 is the usual state */
|
||||
}
|
||||
|
||||
static const VMStateDescription vmstate_ps2_keyboard_need_high_bit = {
|
||||
.name = "ps2kbd/need_high_bit",
|
||||
.version_id = 1,
|
||||
.minimum_version_id = 1,
|
||||
.needed = ps2_keyboard_need_high_bit_needed,
|
||||
.fields = (VMStateField[]) {
|
||||
VMSTATE_BOOL(need_high_bit, PS2KbdState),
|
||||
VMSTATE_END_OF_LIST()
|
||||
}
|
||||
};
|
||||
|
||||
static int ps2_kbd_post_load(void* opaque, int version_id)
|
||||
{
|
||||
PS2KbdState *s = (PS2KbdState*)opaque;
|
||||
@@ -726,6 +1229,7 @@ static const VMStateDescription vmstate_ps2_keyboard = {
|
||||
},
|
||||
.subsections = (const VMStateDescription*[]) {
|
||||
&vmstate_ps2_keyboard_ledstate,
|
||||
&vmstate_ps2_keyboard_need_high_bit,
|
||||
NULL
|
||||
}
|
||||
};
|
||||
|
@@ -39,6 +39,10 @@
|
||||
|
||||
static APICCommonState *local_apics[MAX_APICS + 1];
|
||||
|
||||
#define TYPE_APIC "apic"
|
||||
#define APIC(obj) \
|
||||
OBJECT_CHECK(APICCommonState, (obj), TYPE_APIC)
|
||||
|
||||
static void apic_set_irq(APICCommonState *s, int vector_num, int trigger_mode);
|
||||
static void apic_update_irq(APICCommonState *s);
|
||||
static void apic_get_delivery_bitmask(uint32_t *deliver_bitmask,
|
||||
@@ -163,7 +167,7 @@ static void apic_local_deliver(APICCommonState *s, int vector)
|
||||
|
||||
void apic_deliver_pic_intr(DeviceState *dev, int level)
|
||||
{
|
||||
APICCommonState *s = APIC_COMMON(dev);
|
||||
APICCommonState *s = APIC(dev);
|
||||
|
||||
if (level) {
|
||||
apic_local_deliver(s, APIC_LVT_LINT0);
|
||||
@@ -373,7 +377,7 @@ static void apic_update_irq(APICCommonState *s)
|
||||
|
||||
void apic_poll_irq(DeviceState *dev)
|
||||
{
|
||||
APICCommonState *s = APIC_COMMON(dev);
|
||||
APICCommonState *s = APIC(dev);
|
||||
|
||||
apic_sync_vapic(s, SYNC_FROM_VAPIC);
|
||||
apic_update_irq(s);
|
||||
@@ -479,7 +483,7 @@ static void apic_startup(APICCommonState *s, int vector_num)
|
||||
|
||||
void apic_sipi(DeviceState *dev)
|
||||
{
|
||||
APICCommonState *s = APIC_COMMON(dev);
|
||||
APICCommonState *s = APIC(dev);
|
||||
|
||||
cpu_reset_interrupt(CPU(s->cpu), CPU_INTERRUPT_SIPI);
|
||||
|
||||
@@ -493,7 +497,7 @@ static void apic_deliver(DeviceState *dev, uint8_t dest, uint8_t dest_mode,
|
||||
uint8_t delivery_mode, uint8_t vector_num,
|
||||
uint8_t trigger_mode)
|
||||
{
|
||||
APICCommonState *s = APIC_COMMON(dev);
|
||||
APICCommonState *s = APIC(dev);
|
||||
uint32_t deliver_bitmask[MAX_APIC_WORDS];
|
||||
int dest_shorthand = (s->icr[0] >> 18) & 3;
|
||||
APICCommonState *apic_iter;
|
||||
@@ -550,7 +554,7 @@ static bool apic_check_pic(APICCommonState *s)
|
||||
|
||||
int apic_get_interrupt(DeviceState *dev)
|
||||
{
|
||||
APICCommonState *s = APIC_COMMON(dev);
|
||||
APICCommonState *s = APIC(dev);
|
||||
int intno;
|
||||
|
||||
/* if the APIC is installed or enabled, we let the 8259 handle the
|
||||
@@ -584,7 +588,7 @@ int apic_get_interrupt(DeviceState *dev)
|
||||
|
||||
int apic_accept_pic_intr(DeviceState *dev)
|
||||
{
|
||||
APICCommonState *s = APIC_COMMON(dev);
|
||||
APICCommonState *s = APIC(dev);
|
||||
uint32_t lvt0;
|
||||
|
||||
if (!s)
|
||||
@@ -663,7 +667,7 @@ static uint32_t apic_mem_readl(void *opaque, hwaddr addr)
|
||||
if (!dev) {
|
||||
return 0;
|
||||
}
|
||||
s = APIC_COMMON(dev);
|
||||
s = APIC(dev);
|
||||
|
||||
index = (addr >> 4) & 0xff;
|
||||
switch(index) {
|
||||
@@ -766,7 +770,7 @@ static void apic_mem_writel(void *opaque, hwaddr addr, uint32_t val)
|
||||
if (!dev) {
|
||||
return;
|
||||
}
|
||||
s = APIC_COMMON(dev);
|
||||
s = APIC(dev);
|
||||
|
||||
trace_apic_mem_writel(addr, val);
|
||||
|
||||
@@ -870,7 +874,7 @@ static const MemoryRegionOps apic_io_ops = {
|
||||
|
||||
static void apic_realize(DeviceState *dev, Error **errp)
|
||||
{
|
||||
APICCommonState *s = APIC_COMMON(dev);
|
||||
APICCommonState *s = APIC(dev);
|
||||
|
||||
if (s->id >= MAX_APICS) {
|
||||
error_setg(errp, "%s initialization failed. APIC ID %d is invalid",
|
||||
@@ -889,7 +893,7 @@ static void apic_realize(DeviceState *dev, Error **errp)
|
||||
|
||||
static void apic_unrealize(DeviceState *dev, Error **errp)
|
||||
{
|
||||
APICCommonState *s = APIC_COMMON(dev);
|
||||
APICCommonState *s = APIC(dev);
|
||||
|
||||
timer_del(s->timer);
|
||||
timer_free(s->timer);
|
||||
@@ -912,7 +916,7 @@ static void apic_class_init(ObjectClass *klass, void *data)
|
||||
}
|
||||
|
||||
static const TypeInfo apic_info = {
|
||||
.name = "apic",
|
||||
.name = TYPE_APIC,
|
||||
.instance_size = sizeof(APICCommonState),
|
||||
.parent = TYPE_APIC_COMMON,
|
||||
.class_init = apic_class_init,
|
||||
|
@@ -505,8 +505,11 @@ static void ics_reject(ICSState *ics, int nr)
|
||||
ICSIRQState *irq = ics->irqs + nr - ics->offset;
|
||||
|
||||
trace_xics_ics_reject(nr, nr - ics->offset);
|
||||
irq->status |= XICS_STATUS_REJECTED; /* Irrelevant but harmless for LSI */
|
||||
irq->status &= ~XICS_STATUS_SENT; /* Irrelevant but harmless for MSI */
|
||||
if (irq->flags & XICS_FLAGS_IRQ_MSI) {
|
||||
irq->status |= XICS_STATUS_REJECTED;
|
||||
} else if (irq->flags & XICS_FLAGS_IRQ_LSI) {
|
||||
irq->status &= ~XICS_STATUS_SENT;
|
||||
}
|
||||
}
|
||||
|
||||
static void ics_resend(ICSState *ics)
|
||||
|
@@ -1773,7 +1773,7 @@ static void ipmi_sim_realize(DeviceState *dev, Error **errp)
|
||||
ibs->acpi_power_state[1] = 0;
|
||||
|
||||
if (qemu_uuid_set) {
|
||||
memcpy(&ibs->uuid, qemu_uuid, 16);
|
||||
memcpy(&ibs->uuid, &qemu_uuid, 16);
|
||||
} else {
|
||||
memset(&ibs->uuid, 0, 16);
|
||||
}
|
||||
|
@@ -139,7 +139,7 @@ static m5206_timer_state *m5206_timer_init(qemu_irq irq)
|
||||
|
||||
s = (m5206_timer_state *)g_malloc0(sizeof(m5206_timer_state));
|
||||
bh = qemu_bh_new(m5206_timer_trigger, s);
|
||||
s->timer = ptimer_init(bh);
|
||||
s->timer = ptimer_init(bh, PTIMER_POLICY_DEFAULT);
|
||||
s->irq = irq;
|
||||
m5206_timer_reset(s);
|
||||
return s;
|
||||
|
@@ -183,7 +183,7 @@ static void mcf5208_sys_init(MemoryRegion *address_space, qemu_irq *pic)
|
||||
for (i = 0; i < 2; i++) {
|
||||
s = (m5208_timer_state *)g_malloc0(sizeof(m5208_timer_state));
|
||||
bh = qemu_bh_new(m5208_timer_trigger, s);
|
||||
s->timer = ptimer_init(bh);
|
||||
s->timer = ptimer_init(bh, PTIMER_POLICY_DEFAULT);
|
||||
memory_region_init_io(&s->iomem, NULL, &m5208_timer_ops, s,
|
||||
"m5208-timer", 0x00004000);
|
||||
memory_region_add_subregion(address_space, 0xfc080000 + 0x4000 * i,
|
||||
|
@@ -120,6 +120,41 @@ static const uint32_t ast2400_a0_resets[ASPEED_SCU_NR_REGS] = {
|
||||
[BMC_DEV_ID] = 0x00002402U
|
||||
};
|
||||
|
||||
/* SCU70 bit 23: 0 24Mhz. bit 11:9: 0b001 AXI:ABH ratio 2:1 */
|
||||
/* AST2500 revision A1 */
|
||||
|
||||
static const uint32_t ast2500_a1_resets[ASPEED_SCU_NR_REGS] = {
|
||||
[SYS_RST_CTRL] = 0xFFCFFEDCU,
|
||||
[CLK_SEL] = 0xF3F40000U,
|
||||
[CLK_STOP_CTRL] = 0x19FC3E8BU,
|
||||
[D2PLL_PARAM] = 0x00026108U,
|
||||
[MPLL_PARAM] = 0x00030291U,
|
||||
[HPLL_PARAM] = 0x93000400U,
|
||||
[MISC_CTRL1] = 0x00000010U,
|
||||
[PCI_CTRL1] = 0x20001A03U,
|
||||
[PCI_CTRL2] = 0x20001A03U,
|
||||
[PCI_CTRL3] = 0x04000030U,
|
||||
[SYS_RST_STATUS] = 0x00000001U,
|
||||
[SOC_SCRATCH1] = 0x000000C0U, /* SoC completed DRAM init */
|
||||
[MISC_CTRL2] = 0x00000023U,
|
||||
[RNG_CTRL] = 0x0000000EU,
|
||||
[PINMUX_CTRL2] = 0x0000F000U,
|
||||
[PINMUX_CTRL3] = 0x03000000U,
|
||||
[PINMUX_CTRL4] = 0x00000000U,
|
||||
[PINMUX_CTRL5] = 0x0000A000U,
|
||||
[WDT_RST_CTRL] = 0x023FFFF3U,
|
||||
[PINMUX_CTRL8] = 0xFFFF0000U,
|
||||
[PINMUX_CTRL9] = 0x000FFFFFU,
|
||||
[FREE_CNTR4] = 0x000000FFU,
|
||||
[FREE_CNTR4_EXT] = 0x000000FFU,
|
||||
[CPU2_BASE_SEG1] = 0x80000000U,
|
||||
[CPU2_BASE_SEG4] = 0x1E600000U,
|
||||
[CPU2_BASE_SEG5] = 0xC0000000U,
|
||||
[UART_HPLL_CLK] = 0x00001903U,
|
||||
[PCIE_CTRL] = 0x0000007BU,
|
||||
[BMC_DEV_ID] = 0x00002402U
|
||||
};
|
||||
|
||||
static uint64_t aspeed_scu_read(void *opaque, hwaddr offset, unsigned size)
|
||||
{
|
||||
AspeedSCUState *s = ASPEED_SCU(opaque);
|
||||
@@ -198,6 +233,10 @@ static void aspeed_scu_reset(DeviceState *dev)
|
||||
case AST2400_A0_SILICON_REV:
|
||||
reset = ast2400_a0_resets;
|
||||
break;
|
||||
case AST2500_A0_SILICON_REV:
|
||||
case AST2500_A1_SILICON_REV:
|
||||
reset = ast2500_a1_resets;
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached();
|
||||
}
|
||||
@@ -208,7 +247,11 @@ static void aspeed_scu_reset(DeviceState *dev)
|
||||
s->regs[HW_STRAP2] = s->hw_strap2;
|
||||
}
|
||||
|
||||
static uint32_t aspeed_silicon_revs[] = { AST2400_A0_SILICON_REV, };
|
||||
static uint32_t aspeed_silicon_revs[] = {
|
||||
AST2400_A0_SILICON_REV,
|
||||
AST2500_A0_SILICON_REV,
|
||||
AST2500_A1_SILICON_REV,
|
||||
};
|
||||
|
||||
bool is_supported_silicon_rev(uint32_t silicon_rev)
|
||||
{
|
||||
|
@@ -9,6 +9,7 @@
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include "qemu/log.h"
|
||||
#include "qemu/error-report.h"
|
||||
#include "hw/misc/aspeed_sdmc.h"
|
||||
#include "hw/misc/aspeed_scu.h"
|
||||
#include "hw/qdev-properties.h"
|
||||
@@ -139,9 +140,9 @@ static const MemoryRegionOps aspeed_sdmc_ops = {
|
||||
.valid.max_access_size = 4,
|
||||
};
|
||||
|
||||
static int ast2400_rambits(void)
|
||||
static int ast2400_rambits(AspeedSDMCState *s)
|
||||
{
|
||||
switch (ram_size >> 20) {
|
||||
switch (s->ram_size >> 20) {
|
||||
case 64:
|
||||
return ASPEED_SDMC_DRAM_64MB;
|
||||
case 128:
|
||||
@@ -151,18 +152,19 @@ static int ast2400_rambits(void)
|
||||
case 512:
|
||||
return ASPEED_SDMC_DRAM_512MB;
|
||||
default:
|
||||
qemu_log_mask(LOG_GUEST_ERROR, "%s: Invalid RAM size: 0x"
|
||||
RAM_ADDR_FMT "\n", __func__, ram_size);
|
||||
break;
|
||||
}
|
||||
|
||||
/* set a minimum default */
|
||||
return ASPEED_SDMC_DRAM_64MB;
|
||||
/* use a common default */
|
||||
error_report("warning: Invalid RAM size 0x%" PRIx64
|
||||
". Using default 256M", s->ram_size);
|
||||
s->ram_size = 256 << 20;
|
||||
return ASPEED_SDMC_DRAM_256MB;
|
||||
}
|
||||
|
||||
static int ast2500_rambits(void)
|
||||
static int ast2500_rambits(AspeedSDMCState *s)
|
||||
{
|
||||
switch (ram_size >> 20) {
|
||||
switch (s->ram_size >> 20) {
|
||||
case 128:
|
||||
return ASPEED_SDMC_AST2500_128MB;
|
||||
case 256:
|
||||
@@ -172,13 +174,14 @@ static int ast2500_rambits(void)
|
||||
case 1024:
|
||||
return ASPEED_SDMC_AST2500_1024MB;
|
||||
default:
|
||||
qemu_log_mask(LOG_GUEST_ERROR, "%s: Invalid RAM size: 0x"
|
||||
RAM_ADDR_FMT "\n", __func__, ram_size);
|
||||
break;
|
||||
}
|
||||
|
||||
/* set a minimum default */
|
||||
return ASPEED_SDMC_AST2500_128MB;
|
||||
/* use a common default */
|
||||
error_report("warning: Invalid RAM size 0x%" PRIx64
|
||||
". Using default 512M", s->ram_size);
|
||||
s->ram_size = 512 << 20;
|
||||
return ASPEED_SDMC_AST2500_512MB;
|
||||
}
|
||||
|
||||
static void aspeed_sdmc_reset(DeviceState *dev)
|
||||
@@ -192,14 +195,15 @@ static void aspeed_sdmc_reset(DeviceState *dev)
|
||||
case AST2400_A0_SILICON_REV:
|
||||
s->regs[R_CONF] |=
|
||||
ASPEED_SDMC_VGA_COMPAT |
|
||||
ASPEED_SDMC_DRAM_SIZE(ast2400_rambits());
|
||||
ASPEED_SDMC_DRAM_SIZE(s->ram_bits);
|
||||
break;
|
||||
|
||||
case AST2500_A0_SILICON_REV:
|
||||
case AST2500_A1_SILICON_REV:
|
||||
s->regs[R_CONF] |=
|
||||
ASPEED_SDMC_HW_VERSION(1) |
|
||||
ASPEED_SDMC_VGA_APERTURE(ASPEED_SDMC_VGA_64MB) |
|
||||
ASPEED_SDMC_DRAM_SIZE(ast2500_rambits());
|
||||
ASPEED_SDMC_DRAM_SIZE(s->ram_bits);
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -218,6 +222,18 @@ static void aspeed_sdmc_realize(DeviceState *dev, Error **errp)
|
||||
return;
|
||||
}
|
||||
|
||||
switch (s->silicon_rev) {
|
||||
case AST2400_A0_SILICON_REV:
|
||||
s->ram_bits = ast2400_rambits(s);
|
||||
break;
|
||||
case AST2500_A0_SILICON_REV:
|
||||
case AST2500_A1_SILICON_REV:
|
||||
s->ram_bits = ast2500_rambits(s);
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached();
|
||||
}
|
||||
|
||||
memory_region_init_io(&s->iomem, OBJECT(s), &aspeed_sdmc_ops, s,
|
||||
TYPE_ASPEED_SDMC, 0x1000);
|
||||
sysbus_init_mmio(sbd, &s->iomem);
|
||||
@@ -235,6 +251,7 @@ static const VMStateDescription vmstate_aspeed_sdmc = {
|
||||
|
||||
static Property aspeed_sdmc_properties[] = {
|
||||
DEFINE_PROP_UINT32("silicon-rev", AspeedSDMCState, silicon_rev, 0),
|
||||
DEFINE_PROP_UINT64("ram-size", AspeedSDMCState, ram_size, 0),
|
||||
DEFINE_PROP_END_OF_LIST(),
|
||||
};
|
||||
|
||||
|
@@ -27,7 +27,7 @@
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
static char const *imx25_ccm_reg_name(uint32_t reg)
|
||||
static const char *imx25_ccm_reg_name(uint32_t reg)
|
||||
{
|
||||
static char unknown[20];
|
||||
|
||||
|
@@ -29,7 +29,7 @@
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
static char const *imx31_ccm_reg_name(uint32_t reg)
|
||||
static const char *imx31_ccm_reg_name(uint32_t reg)
|
||||
{
|
||||
static char unknown[20];
|
||||
|
||||
|
@@ -26,7 +26,7 @@
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
static char const *imx6_ccm_reg_name(uint32_t reg)
|
||||
static const char *imx6_ccm_reg_name(uint32_t reg)
|
||||
{
|
||||
static char unknown[20];
|
||||
|
||||
@@ -99,7 +99,7 @@ static char const *imx6_ccm_reg_name(uint32_t reg)
|
||||
}
|
||||
}
|
||||
|
||||
static char const *imx6_analog_reg_name(uint32_t reg)
|
||||
static const char *imx6_analog_reg_name(uint32_t reg)
|
||||
{
|
||||
static char unknown[20];
|
||||
|
||||
|
@@ -27,7 +27,7 @@
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
static char const *imx6_src_reg_name(uint32_t reg)
|
||||
static const char *imx6_src_reg_name(uint32_t reg)
|
||||
{
|
||||
static char unknown[20];
|
||||
|
||||
|
@@ -628,7 +628,6 @@ static void ivshmem_read(void *opaque, const uint8_t *buf, int size)
|
||||
s->msg_buffered_bytes = 0;
|
||||
|
||||
fd = qemu_chr_fe_get_msgfd(s->server_chr);
|
||||
IVSHMEM_DPRINTF("posn is %" PRId64 ", fd is %d\n", msg, fd);
|
||||
|
||||
process_msg(s, msg, fd, &err);
|
||||
if (err) {
|
||||
|
@@ -26,6 +26,8 @@
|
||||
#include <zlib.h> /* For crc32 */
|
||||
|
||||
#include "hw/net/cadence_gem.h"
|
||||
#include "qapi/error.h"
|
||||
#include "qemu/log.h"
|
||||
#include "net/checksum.h"
|
||||
|
||||
#ifdef CADENCE_GEM_ERR_DEBUG
|
||||
@@ -141,6 +143,61 @@
|
||||
#define GEM_DESCONF6 (0x00000294/4)
|
||||
#define GEM_DESCONF7 (0x00000298/4)
|
||||
|
||||
#define GEM_INT_Q1_STATUS (0x00000400 / 4)
|
||||
#define GEM_INT_Q1_MASK (0x00000640 / 4)
|
||||
|
||||
#define GEM_TRANSMIT_Q1_PTR (0x00000440 / 4)
|
||||
#define GEM_TRANSMIT_Q15_PTR (GEM_TRANSMIT_Q1_PTR + 14)
|
||||
|
||||
#define GEM_RECEIVE_Q1_PTR (0x00000480 / 4)
|
||||
#define GEM_RECEIVE_Q15_PTR (GEM_RECEIVE_Q1_PTR + 14)
|
||||
|
||||
#define GEM_INT_Q1_ENABLE (0x00000600 / 4)
|
||||
#define GEM_INT_Q7_ENABLE (GEM_INT_Q1_ENABLE + 6)
|
||||
#define GEM_INT_Q8_ENABLE (0x00000660 / 4)
|
||||
#define GEM_INT_Q15_ENABLE (GEM_INT_Q8_ENABLE + 7)
|
||||
|
||||
#define GEM_INT_Q1_DISABLE (0x00000620 / 4)
|
||||
#define GEM_INT_Q7_DISABLE (GEM_INT_Q1_DISABLE + 6)
|
||||
#define GEM_INT_Q8_DISABLE (0x00000680 / 4)
|
||||
#define GEM_INT_Q15_DISABLE (GEM_INT_Q8_DISABLE + 7)
|
||||
|
||||
#define GEM_INT_Q1_MASK (0x00000640 / 4)
|
||||
#define GEM_INT_Q7_MASK (GEM_INT_Q1_MASK + 6)
|
||||
#define GEM_INT_Q8_MASK (0x000006A0 / 4)
|
||||
#define GEM_INT_Q15_MASK (GEM_INT_Q8_MASK + 7)
|
||||
|
||||
#define GEM_SCREENING_TYPE1_REGISTER_0 (0x00000500 / 4)
|
||||
|
||||
#define GEM_ST1R_UDP_PORT_MATCH_ENABLE (1 << 29)
|
||||
#define GEM_ST1R_DSTC_ENABLE (1 << 28)
|
||||
#define GEM_ST1R_UDP_PORT_MATCH_SHIFT (12)
|
||||
#define GEM_ST1R_UDP_PORT_MATCH_WIDTH (27 - GEM_ST1R_UDP_PORT_MATCH_SHIFT + 1)
|
||||
#define GEM_ST1R_DSTC_MATCH_SHIFT (4)
|
||||
#define GEM_ST1R_DSTC_MATCH_WIDTH (11 - GEM_ST1R_DSTC_MATCH_SHIFT + 1)
|
||||
#define GEM_ST1R_QUEUE_SHIFT (0)
|
||||
#define GEM_ST1R_QUEUE_WIDTH (3 - GEM_ST1R_QUEUE_SHIFT + 1)
|
||||
|
||||
#define GEM_SCREENING_TYPE2_REGISTER_0 (0x00000540 / 4)
|
||||
|
||||
#define GEM_ST2R_COMPARE_A_ENABLE (1 << 18)
|
||||
#define GEM_ST2R_COMPARE_A_SHIFT (13)
|
||||
#define GEM_ST2R_COMPARE_WIDTH (17 - GEM_ST2R_COMPARE_A_SHIFT + 1)
|
||||
#define GEM_ST2R_ETHERTYPE_ENABLE (1 << 12)
|
||||
#define GEM_ST2R_ETHERTYPE_INDEX_SHIFT (9)
|
||||
#define GEM_ST2R_ETHERTYPE_INDEX_WIDTH (11 - GEM_ST2R_ETHERTYPE_INDEX_SHIFT \
|
||||
+ 1)
|
||||
#define GEM_ST2R_QUEUE_SHIFT (0)
|
||||
#define GEM_ST2R_QUEUE_WIDTH (3 - GEM_ST2R_QUEUE_SHIFT + 1)
|
||||
|
||||
#define GEM_SCREENING_TYPE2_ETHERTYPE_REG_0 (0x000006e0 / 4)
|
||||
#define GEM_TYPE2_COMPARE_0_WORD_0 (0x00000700 / 4)
|
||||
|
||||
#define GEM_T2CW1_COMPARE_OFFSET_SHIFT (7)
|
||||
#define GEM_T2CW1_COMPARE_OFFSET_WIDTH (8 - GEM_T2CW1_COMPARE_OFFSET_SHIFT + 1)
|
||||
#define GEM_T2CW1_OFFSET_VALUE_SHIFT (0)
|
||||
#define GEM_T2CW1_OFFSET_VALUE_WIDTH (6 - GEM_T2CW1_OFFSET_VALUE_SHIFT + 1)
|
||||
|
||||
/*****************************************/
|
||||
#define GEM_NWCTRL_TXSTART 0x00000200 /* Transmit Enable */
|
||||
#define GEM_NWCTRL_TXENA 0x00000008 /* Transmit Enable */
|
||||
@@ -284,9 +341,9 @@ static inline unsigned tx_desc_get_length(unsigned *desc)
|
||||
return desc[1] & DESC_1_LENGTH;
|
||||
}
|
||||
|
||||
static inline void print_gem_tx_desc(unsigned *desc)
|
||||
static inline void print_gem_tx_desc(unsigned *desc, uint8_t queue)
|
||||
{
|
||||
DB_PRINT("TXDESC:\n");
|
||||
DB_PRINT("TXDESC (queue %" PRId8 "):\n", queue);
|
||||
DB_PRINT("bufaddr: 0x%08x\n", *desc);
|
||||
DB_PRINT("used_hw: %d\n", tx_desc_get_used(desc));
|
||||
DB_PRINT("wrap: %d\n", tx_desc_get_wrap(desc));
|
||||
@@ -416,6 +473,7 @@ static void phy_update_link(CadenceGEMState *s)
|
||||
static int gem_can_receive(NetClientState *nc)
|
||||
{
|
||||
CadenceGEMState *s;
|
||||
int i;
|
||||
|
||||
s = qemu_get_nic_opaque(nc);
|
||||
|
||||
@@ -428,18 +486,20 @@ static int gem_can_receive(NetClientState *nc)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (rx_desc_get_ownership(s->rx_desc) == 1) {
|
||||
if (s->can_rx_state != 2) {
|
||||
s->can_rx_state = 2;
|
||||
DB_PRINT("can't receive - busy buffer descriptor 0x%x\n",
|
||||
s->rx_desc_addr);
|
||||
for (i = 0; i < s->num_priority_queues; i++) {
|
||||
if (rx_desc_get_ownership(s->rx_desc[i]) == 1) {
|
||||
if (s->can_rx_state != 2) {
|
||||
s->can_rx_state = 2;
|
||||
DB_PRINT("can't receive - busy buffer descriptor (q%d) 0x%x\n",
|
||||
i, s->rx_desc_addr[i]);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (s->can_rx_state != 0) {
|
||||
s->can_rx_state = 0;
|
||||
DB_PRINT("can receive 0x%x\n", s->rx_desc_addr);
|
||||
DB_PRINT("can receive\n");
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
@@ -450,9 +510,20 @@ static int gem_can_receive(NetClientState *nc)
|
||||
*/
|
||||
static void gem_update_int_status(CadenceGEMState *s)
|
||||
{
|
||||
if (s->regs[GEM_ISR]) {
|
||||
DB_PRINT("asserting int. (0x%08x)\n", s->regs[GEM_ISR]);
|
||||
qemu_set_irq(s->irq, 1);
|
||||
int i;
|
||||
|
||||
if ((s->num_priority_queues == 1) && s->regs[GEM_ISR]) {
|
||||
/* No priority queues, just trigger the interrupt */
|
||||
DB_PRINT("asserting int.\n", i);
|
||||
qemu_set_irq(s->irq[0], 1);
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < s->num_priority_queues; ++i) {
|
||||
if (s->regs[GEM_INT_Q1_STATUS + i]) {
|
||||
DB_PRINT("asserting int. (q=%d)\n", i);
|
||||
qemu_set_irq(s->irq[i], 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -601,17 +672,137 @@ static int gem_mac_address_filter(CadenceGEMState *s, const uint8_t *packet)
|
||||
return GEM_RX_REJECT;
|
||||
}
|
||||
|
||||
static void gem_get_rx_desc(CadenceGEMState *s)
|
||||
/* Figure out which queue the received data should be sent to */
|
||||
static int get_queue_from_screen(CadenceGEMState *s, uint8_t *rxbuf_ptr,
|
||||
unsigned rxbufsize)
|
||||
{
|
||||
DB_PRINT("read descriptor 0x%x\n", (unsigned)s->rx_desc_addr);
|
||||
uint32_t reg;
|
||||
bool matched, mismatched;
|
||||
int i, j;
|
||||
|
||||
for (i = 0; i < s->num_type1_screeners; i++) {
|
||||
reg = s->regs[GEM_SCREENING_TYPE1_REGISTER_0 + i];
|
||||
matched = false;
|
||||
mismatched = false;
|
||||
|
||||
/* Screening is based on UDP Port */
|
||||
if (reg & GEM_ST1R_UDP_PORT_MATCH_ENABLE) {
|
||||
uint16_t udp_port = rxbuf_ptr[14 + 22] << 8 | rxbuf_ptr[14 + 23];
|
||||
if (udp_port == extract32(reg, GEM_ST1R_UDP_PORT_MATCH_SHIFT,
|
||||
GEM_ST1R_UDP_PORT_MATCH_WIDTH)) {
|
||||
matched = true;
|
||||
} else {
|
||||
mismatched = true;
|
||||
}
|
||||
}
|
||||
|
||||
/* Screening is based on DS/TC */
|
||||
if (reg & GEM_ST1R_DSTC_ENABLE) {
|
||||
uint8_t dscp = rxbuf_ptr[14 + 1];
|
||||
if (dscp == extract32(reg, GEM_ST1R_DSTC_MATCH_SHIFT,
|
||||
GEM_ST1R_DSTC_MATCH_WIDTH)) {
|
||||
matched = true;
|
||||
} else {
|
||||
mismatched = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (matched && !mismatched) {
|
||||
return extract32(reg, GEM_ST1R_QUEUE_SHIFT, GEM_ST1R_QUEUE_WIDTH);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < s->num_type2_screeners; i++) {
|
||||
reg = s->regs[GEM_SCREENING_TYPE2_REGISTER_0 + i];
|
||||
matched = false;
|
||||
mismatched = false;
|
||||
|
||||
if (reg & GEM_ST2R_ETHERTYPE_ENABLE) {
|
||||
uint16_t type = rxbuf_ptr[12] << 8 | rxbuf_ptr[13];
|
||||
int et_idx = extract32(reg, GEM_ST2R_ETHERTYPE_INDEX_SHIFT,
|
||||
GEM_ST2R_ETHERTYPE_INDEX_WIDTH);
|
||||
|
||||
if (et_idx > s->num_type2_screeners) {
|
||||
qemu_log_mask(LOG_GUEST_ERROR, "Out of range ethertype "
|
||||
"register index: %d\n", et_idx);
|
||||
}
|
||||
if (type == s->regs[GEM_SCREENING_TYPE2_ETHERTYPE_REG_0 +
|
||||
et_idx]) {
|
||||
matched = true;
|
||||
} else {
|
||||
mismatched = true;
|
||||
}
|
||||
}
|
||||
|
||||
/* Compare A, B, C */
|
||||
for (j = 0; j < 3; j++) {
|
||||
uint32_t cr0, cr1, mask;
|
||||
uint16_t rx_cmp;
|
||||
int offset;
|
||||
int cr_idx = extract32(reg, GEM_ST2R_COMPARE_A_SHIFT + j * 6,
|
||||
GEM_ST2R_COMPARE_WIDTH);
|
||||
|
||||
if (!(reg & (GEM_ST2R_COMPARE_A_ENABLE << (j * 6)))) {
|
||||
continue;
|
||||
}
|
||||
if (cr_idx > s->num_type2_screeners) {
|
||||
qemu_log_mask(LOG_GUEST_ERROR, "Out of range compare "
|
||||
"register index: %d\n", cr_idx);
|
||||
}
|
||||
|
||||
cr0 = s->regs[GEM_TYPE2_COMPARE_0_WORD_0 + cr_idx * 2];
|
||||
cr1 = s->regs[GEM_TYPE2_COMPARE_0_WORD_0 + cr_idx * 2 + 1];
|
||||
offset = extract32(cr1, GEM_T2CW1_OFFSET_VALUE_SHIFT,
|
||||
GEM_T2CW1_OFFSET_VALUE_WIDTH);
|
||||
|
||||
switch (extract32(cr1, GEM_T2CW1_COMPARE_OFFSET_SHIFT,
|
||||
GEM_T2CW1_COMPARE_OFFSET_WIDTH)) {
|
||||
case 3: /* Skip UDP header */
|
||||
qemu_log_mask(LOG_UNIMP, "TCP compare offsets"
|
||||
"unimplemented - assuming UDP\n");
|
||||
offset += 8;
|
||||
/* Fallthrough */
|
||||
case 2: /* skip the IP header */
|
||||
offset += 20;
|
||||
/* Fallthrough */
|
||||
case 1: /* Count from after the ethertype */
|
||||
offset += 14;
|
||||
break;
|
||||
case 0:
|
||||
/* Offset from start of frame */
|
||||
break;
|
||||
}
|
||||
|
||||
rx_cmp = rxbuf_ptr[offset] << 8 | rxbuf_ptr[offset];
|
||||
mask = extract32(cr0, 0, 16);
|
||||
|
||||
if ((rx_cmp & mask) == (extract32(cr0, 16, 16) & mask)) {
|
||||
matched = true;
|
||||
} else {
|
||||
mismatched = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (matched && !mismatched) {
|
||||
return extract32(reg, GEM_ST2R_QUEUE_SHIFT, GEM_ST2R_QUEUE_WIDTH);
|
||||
}
|
||||
}
|
||||
|
||||
/* We made it here, assume it's queue 0 */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void gem_get_rx_desc(CadenceGEMState *s, int q)
|
||||
{
|
||||
DB_PRINT("read descriptor 0x%x\n", (unsigned)s->rx_desc_addr[q]);
|
||||
/* read current descriptor */
|
||||
cpu_physical_memory_read(s->rx_desc_addr,
|
||||
(uint8_t *)s->rx_desc, sizeof(s->rx_desc));
|
||||
cpu_physical_memory_read(s->rx_desc_addr[0],
|
||||
(uint8_t *)s->rx_desc[0], sizeof(s->rx_desc[0]));
|
||||
|
||||
/* Descriptor owned by software ? */
|
||||
if (rx_desc_get_ownership(s->rx_desc) == 1) {
|
||||
if (rx_desc_get_ownership(s->rx_desc[q]) == 1) {
|
||||
DB_PRINT("descriptor 0x%x owned by sw.\n",
|
||||
(unsigned)s->rx_desc_addr);
|
||||
(unsigned)s->rx_desc_addr[q]);
|
||||
s->regs[GEM_RXSTATUS] |= GEM_RXSTATUS_NOBUF;
|
||||
s->regs[GEM_ISR] |= GEM_INT_RXUSED & ~(s->regs[GEM_IMR]);
|
||||
/* Handle interrupt consequences */
|
||||
@@ -632,6 +823,7 @@ static ssize_t gem_receive(NetClientState *nc, const uint8_t *buf, size_t size)
|
||||
uint8_t *rxbuf_ptr;
|
||||
bool first_desc = true;
|
||||
int maf;
|
||||
int q = 0;
|
||||
|
||||
s = qemu_get_nic_opaque(nc);
|
||||
|
||||
@@ -710,6 +902,9 @@ static ssize_t gem_receive(NetClientState *nc, const uint8_t *buf, size_t size)
|
||||
|
||||
DB_PRINT("config bufsize: %d packet size: %ld\n", rxbufsize, size);
|
||||
|
||||
/* Find which queue we are targetting */
|
||||
q = get_queue_from_screen(s, rxbuf_ptr, rxbufsize);
|
||||
|
||||
while (bytes_to_copy) {
|
||||
/* Do nothing if receive is not enabled. */
|
||||
if (!gem_can_receive(nc)) {
|
||||
@@ -718,56 +913,59 @@ static ssize_t gem_receive(NetClientState *nc, const uint8_t *buf, size_t size)
|
||||
}
|
||||
|
||||
DB_PRINT("copy %d bytes to 0x%x\n", MIN(bytes_to_copy, rxbufsize),
|
||||
rx_desc_get_buffer(s->rx_desc));
|
||||
rx_desc_get_buffer(s->rx_desc[q]));
|
||||
|
||||
/* Copy packet data to emulated DMA buffer */
|
||||
cpu_physical_memory_write(rx_desc_get_buffer(s->rx_desc) + rxbuf_offset,
|
||||
cpu_physical_memory_write(rx_desc_get_buffer(s->rx_desc[q]) +
|
||||
rxbuf_offset,
|
||||
rxbuf_ptr, MIN(bytes_to_copy, rxbufsize));
|
||||
rxbuf_ptr += MIN(bytes_to_copy, rxbufsize);
|
||||
bytes_to_copy -= MIN(bytes_to_copy, rxbufsize);
|
||||
|
||||
/* Update the descriptor. */
|
||||
if (first_desc) {
|
||||
rx_desc_set_sof(s->rx_desc);
|
||||
rx_desc_set_sof(s->rx_desc[q]);
|
||||
first_desc = false;
|
||||
}
|
||||
if (bytes_to_copy == 0) {
|
||||
rx_desc_set_eof(s->rx_desc);
|
||||
rx_desc_set_length(s->rx_desc, size);
|
||||
rx_desc_set_eof(s->rx_desc[q]);
|
||||
rx_desc_set_length(s->rx_desc[q], size);
|
||||
}
|
||||
rx_desc_set_ownership(s->rx_desc);
|
||||
rx_desc_set_ownership(s->rx_desc[q]);
|
||||
|
||||
switch (maf) {
|
||||
case GEM_RX_PROMISCUOUS_ACCEPT:
|
||||
break;
|
||||
case GEM_RX_BROADCAST_ACCEPT:
|
||||
rx_desc_set_broadcast(s->rx_desc);
|
||||
rx_desc_set_broadcast(s->rx_desc[q]);
|
||||
break;
|
||||
case GEM_RX_UNICAST_HASH_ACCEPT:
|
||||
rx_desc_set_unicast_hash(s->rx_desc);
|
||||
rx_desc_set_unicast_hash(s->rx_desc[q]);
|
||||
break;
|
||||
case GEM_RX_MULTICAST_HASH_ACCEPT:
|
||||
rx_desc_set_multicast_hash(s->rx_desc);
|
||||
rx_desc_set_multicast_hash(s->rx_desc[q]);
|
||||
break;
|
||||
case GEM_RX_REJECT:
|
||||
abort();
|
||||
default: /* SAR */
|
||||
rx_desc_set_sar(s->rx_desc, maf);
|
||||
rx_desc_set_sar(s->rx_desc[q], maf);
|
||||
}
|
||||
|
||||
/* Descriptor write-back. */
|
||||
cpu_physical_memory_write(s->rx_desc_addr,
|
||||
(uint8_t *)s->rx_desc, sizeof(s->rx_desc));
|
||||
cpu_physical_memory_write(s->rx_desc_addr[q],
|
||||
(uint8_t *)s->rx_desc[q],
|
||||
sizeof(s->rx_desc[q]));
|
||||
|
||||
/* Next descriptor */
|
||||
if (rx_desc_get_wrap(s->rx_desc)) {
|
||||
if (rx_desc_get_wrap(s->rx_desc[q])) {
|
||||
DB_PRINT("wrapping RX descriptor list\n");
|
||||
s->rx_desc_addr = s->regs[GEM_RXQBASE];
|
||||
s->rx_desc_addr[q] = s->regs[GEM_RXQBASE];
|
||||
} else {
|
||||
DB_PRINT("incrementing RX descriptor list\n");
|
||||
s->rx_desc_addr += 8;
|
||||
s->rx_desc_addr[q] += 8;
|
||||
}
|
||||
gem_get_rx_desc(s);
|
||||
|
||||
gem_get_rx_desc(s, q);
|
||||
}
|
||||
|
||||
/* Count it */
|
||||
@@ -839,6 +1037,7 @@ static void gem_transmit(CadenceGEMState *s)
|
||||
uint8_t tx_packet[2048];
|
||||
uint8_t *p;
|
||||
unsigned total_bytes;
|
||||
int q = 0;
|
||||
|
||||
/* Do nothing if transmit is not enabled. */
|
||||
if (!(s->regs[GEM_NWCTRL] & GEM_NWCTRL_TXENA)) {
|
||||
@@ -854,110 +1053,123 @@ static void gem_transmit(CadenceGEMState *s)
|
||||
p = tx_packet;
|
||||
total_bytes = 0;
|
||||
|
||||
/* read current descriptor */
|
||||
packet_desc_addr = s->tx_desc_addr;
|
||||
for (q = s->num_priority_queues - 1; q >= 0; q--) {
|
||||
/* read current descriptor */
|
||||
packet_desc_addr = s->tx_desc_addr[q];
|
||||
|
||||
DB_PRINT("read descriptor 0x%" HWADDR_PRIx "\n", packet_desc_addr);
|
||||
cpu_physical_memory_read(packet_desc_addr,
|
||||
(uint8_t *)desc, sizeof(desc));
|
||||
/* Handle all descriptors owned by hardware */
|
||||
while (tx_desc_get_used(desc) == 0) {
|
||||
|
||||
/* Do nothing if transmit is not enabled. */
|
||||
if (!(s->regs[GEM_NWCTRL] & GEM_NWCTRL_TXENA)) {
|
||||
return;
|
||||
}
|
||||
print_gem_tx_desc(desc);
|
||||
|
||||
/* The real hardware would eat this (and possibly crash).
|
||||
* For QEMU let's lend a helping hand.
|
||||
*/
|
||||
if ((tx_desc_get_buffer(desc) == 0) ||
|
||||
(tx_desc_get_length(desc) == 0)) {
|
||||
DB_PRINT("Invalid TX descriptor @ 0x%x\n",
|
||||
(unsigned)packet_desc_addr);
|
||||
break;
|
||||
}
|
||||
|
||||
if (tx_desc_get_length(desc) > sizeof(tx_packet) - (p - tx_packet)) {
|
||||
DB_PRINT("TX descriptor @ 0x%x too large: size 0x%x space 0x%x\n",
|
||||
(unsigned)packet_desc_addr,
|
||||
(unsigned)tx_desc_get_length(desc),
|
||||
sizeof(tx_packet) - (p - tx_packet));
|
||||
break;
|
||||
}
|
||||
|
||||
/* Gather this fragment of the packet from "dma memory" to our contig.
|
||||
* buffer.
|
||||
*/
|
||||
cpu_physical_memory_read(tx_desc_get_buffer(desc), p,
|
||||
tx_desc_get_length(desc));
|
||||
p += tx_desc_get_length(desc);
|
||||
total_bytes += tx_desc_get_length(desc);
|
||||
|
||||
/* Last descriptor for this packet; hand the whole thing off */
|
||||
if (tx_desc_get_last(desc)) {
|
||||
unsigned desc_first[2];
|
||||
|
||||
/* Modify the 1st descriptor of this packet to be owned by
|
||||
* the processor.
|
||||
*/
|
||||
cpu_physical_memory_read(s->tx_desc_addr, (uint8_t *)desc_first,
|
||||
sizeof(desc_first));
|
||||
tx_desc_set_used(desc_first);
|
||||
cpu_physical_memory_write(s->tx_desc_addr, (uint8_t *)desc_first,
|
||||
sizeof(desc_first));
|
||||
/* Advance the hardware current descriptor past this packet */
|
||||
if (tx_desc_get_wrap(desc)) {
|
||||
s->tx_desc_addr = s->regs[GEM_TXQBASE];
|
||||
} else {
|
||||
s->tx_desc_addr = packet_desc_addr + 8;
|
||||
}
|
||||
DB_PRINT("TX descriptor next: 0x%08x\n", s->tx_desc_addr);
|
||||
|
||||
s->regs[GEM_TXSTATUS] |= GEM_TXSTATUS_TXCMPL;
|
||||
s->regs[GEM_ISR] |= GEM_INT_TXCMPL & ~(s->regs[GEM_IMR]);
|
||||
|
||||
/* Handle interrupt consequences */
|
||||
gem_update_int_status(s);
|
||||
|
||||
/* Is checksum offload enabled? */
|
||||
if (s->regs[GEM_DMACFG] & GEM_DMACFG_TXCSUM_OFFL) {
|
||||
net_checksum_calculate(tx_packet, total_bytes);
|
||||
}
|
||||
|
||||
/* Update MAC statistics */
|
||||
gem_transmit_updatestats(s, tx_packet, total_bytes);
|
||||
|
||||
/* Send the packet somewhere */
|
||||
if (s->phy_loop || (s->regs[GEM_NWCTRL] & GEM_NWCTRL_LOCALLOOP)) {
|
||||
gem_receive(qemu_get_queue(s->nic), tx_packet, total_bytes);
|
||||
} else {
|
||||
qemu_send_packet(qemu_get_queue(s->nic), tx_packet,
|
||||
total_bytes);
|
||||
}
|
||||
|
||||
/* Prepare for next packet */
|
||||
p = tx_packet;
|
||||
total_bytes = 0;
|
||||
}
|
||||
|
||||
/* read next descriptor */
|
||||
if (tx_desc_get_wrap(desc)) {
|
||||
tx_desc_set_last(desc);
|
||||
packet_desc_addr = s->regs[GEM_TXQBASE];
|
||||
} else {
|
||||
packet_desc_addr += 8;
|
||||
}
|
||||
DB_PRINT("read descriptor 0x%" HWADDR_PRIx "\n", packet_desc_addr);
|
||||
cpu_physical_memory_read(packet_desc_addr,
|
||||
(uint8_t *)desc, sizeof(desc));
|
||||
}
|
||||
/* Handle all descriptors owned by hardware */
|
||||
while (tx_desc_get_used(desc) == 0) {
|
||||
|
||||
if (tx_desc_get_used(desc)) {
|
||||
s->regs[GEM_TXSTATUS] |= GEM_TXSTATUS_USED;
|
||||
s->regs[GEM_ISR] |= GEM_INT_TXUSED & ~(s->regs[GEM_IMR]);
|
||||
gem_update_int_status(s);
|
||||
/* Do nothing if transmit is not enabled. */
|
||||
if (!(s->regs[GEM_NWCTRL] & GEM_NWCTRL_TXENA)) {
|
||||
return;
|
||||
}
|
||||
print_gem_tx_desc(desc, q);
|
||||
|
||||
/* The real hardware would eat this (and possibly crash).
|
||||
* For QEMU let's lend a helping hand.
|
||||
*/
|
||||
if ((tx_desc_get_buffer(desc) == 0) ||
|
||||
(tx_desc_get_length(desc) == 0)) {
|
||||
DB_PRINT("Invalid TX descriptor @ 0x%x\n",
|
||||
(unsigned)packet_desc_addr);
|
||||
break;
|
||||
}
|
||||
|
||||
if (tx_desc_get_length(desc) > sizeof(tx_packet) -
|
||||
(p - tx_packet)) {
|
||||
DB_PRINT("TX descriptor @ 0x%x too large: size 0x%x space " \
|
||||
"0x%x\n", (unsigned)packet_desc_addr,
|
||||
(unsigned)tx_desc_get_length(desc),
|
||||
sizeof(tx_packet) - (p - tx_packet));
|
||||
break;
|
||||
}
|
||||
|
||||
/* Gather this fragment of the packet from "dma memory" to our
|
||||
* contig buffer.
|
||||
*/
|
||||
cpu_physical_memory_read(tx_desc_get_buffer(desc), p,
|
||||
tx_desc_get_length(desc));
|
||||
p += tx_desc_get_length(desc);
|
||||
total_bytes += tx_desc_get_length(desc);
|
||||
|
||||
/* Last descriptor for this packet; hand the whole thing off */
|
||||
if (tx_desc_get_last(desc)) {
|
||||
unsigned desc_first[2];
|
||||
|
||||
/* Modify the 1st descriptor of this packet to be owned by
|
||||
* the processor.
|
||||
*/
|
||||
cpu_physical_memory_read(s->tx_desc_addr[q],
|
||||
(uint8_t *)desc_first,
|
||||
sizeof(desc_first));
|
||||
tx_desc_set_used(desc_first);
|
||||
cpu_physical_memory_write(s->tx_desc_addr[q],
|
||||
(uint8_t *)desc_first,
|
||||
sizeof(desc_first));
|
||||
/* Advance the hardware current descriptor past this packet */
|
||||
if (tx_desc_get_wrap(desc)) {
|
||||
s->tx_desc_addr[q] = s->regs[GEM_TXQBASE];
|
||||
} else {
|
||||
s->tx_desc_addr[q] = packet_desc_addr + 8;
|
||||
}
|
||||
DB_PRINT("TX descriptor next: 0x%08x\n", s->tx_desc_addr[q]);
|
||||
|
||||
s->regs[GEM_TXSTATUS] |= GEM_TXSTATUS_TXCMPL;
|
||||
s->regs[GEM_ISR] |= GEM_INT_TXCMPL & ~(s->regs[GEM_IMR]);
|
||||
|
||||
/* Update queue interrupt status */
|
||||
if (s->num_priority_queues > 1) {
|
||||
s->regs[GEM_INT_Q1_STATUS + q] |=
|
||||
GEM_INT_TXCMPL & ~(s->regs[GEM_INT_Q1_MASK + q]);
|
||||
}
|
||||
|
||||
/* Handle interrupt consequences */
|
||||
gem_update_int_status(s);
|
||||
|
||||
/* Is checksum offload enabled? */
|
||||
if (s->regs[GEM_DMACFG] & GEM_DMACFG_TXCSUM_OFFL) {
|
||||
net_checksum_calculate(tx_packet, total_bytes);
|
||||
}
|
||||
|
||||
/* Update MAC statistics */
|
||||
gem_transmit_updatestats(s, tx_packet, total_bytes);
|
||||
|
||||
/* Send the packet somewhere */
|
||||
if (s->phy_loop || (s->regs[GEM_NWCTRL] &
|
||||
GEM_NWCTRL_LOCALLOOP)) {
|
||||
gem_receive(qemu_get_queue(s->nic), tx_packet,
|
||||
total_bytes);
|
||||
} else {
|
||||
qemu_send_packet(qemu_get_queue(s->nic), tx_packet,
|
||||
total_bytes);
|
||||
}
|
||||
|
||||
/* Prepare for next packet */
|
||||
p = tx_packet;
|
||||
total_bytes = 0;
|
||||
}
|
||||
|
||||
/* read next descriptor */
|
||||
if (tx_desc_get_wrap(desc)) {
|
||||
tx_desc_set_last(desc);
|
||||
packet_desc_addr = s->regs[GEM_TXQBASE];
|
||||
} else {
|
||||
packet_desc_addr += 8;
|
||||
}
|
||||
DB_PRINT("read descriptor 0x%" HWADDR_PRIx "\n", packet_desc_addr);
|
||||
cpu_physical_memory_read(packet_desc_addr,
|
||||
(uint8_t *)desc, sizeof(desc));
|
||||
}
|
||||
|
||||
if (tx_desc_get_used(desc)) {
|
||||
s->regs[GEM_TXSTATUS] |= GEM_TXSTATUS_USED;
|
||||
s->regs[GEM_ISR] |= GEM_INT_TXUSED & ~(s->regs[GEM_IMR]);
|
||||
gem_update_int_status(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1065,7 +1277,7 @@ static uint64_t gem_read(void *opaque, hwaddr offset, unsigned size)
|
||||
{
|
||||
CadenceGEMState *s;
|
||||
uint32_t retval;
|
||||
|
||||
int i;
|
||||
s = (CadenceGEMState *)opaque;
|
||||
|
||||
offset >>= 2;
|
||||
@@ -1075,8 +1287,10 @@ static uint64_t gem_read(void *opaque, hwaddr offset, unsigned size)
|
||||
|
||||
switch (offset) {
|
||||
case GEM_ISR:
|
||||
DB_PRINT("lowering irq on ISR read\n");
|
||||
qemu_set_irq(s->irq, 0);
|
||||
DB_PRINT("lowering irqs on ISR read\n");
|
||||
for (i = 0; i < s->num_priority_queues; ++i) {
|
||||
qemu_set_irq(s->irq[i], 0);
|
||||
}
|
||||
break;
|
||||
case GEM_PHYMNTNC:
|
||||
if (retval & GEM_PHYMNTNC_OP_R) {
|
||||
@@ -1101,6 +1315,7 @@ static uint64_t gem_read(void *opaque, hwaddr offset, unsigned size)
|
||||
retval &= ~(s->regs_wo[offset]);
|
||||
|
||||
DB_PRINT("0x%08x\n", retval);
|
||||
gem_update_int_status(s);
|
||||
return retval;
|
||||
}
|
||||
|
||||
@@ -1113,6 +1328,7 @@ static void gem_write(void *opaque, hwaddr offset, uint64_t val,
|
||||
{
|
||||
CadenceGEMState *s = (CadenceGEMState *)opaque;
|
||||
uint32_t readonly;
|
||||
int i;
|
||||
|
||||
DB_PRINT("offset: 0x%04x write: 0x%08x ", (unsigned)offset, (unsigned)val);
|
||||
offset >>= 2;
|
||||
@@ -1132,14 +1348,18 @@ static void gem_write(void *opaque, hwaddr offset, uint64_t val,
|
||||
switch (offset) {
|
||||
case GEM_NWCTRL:
|
||||
if (val & GEM_NWCTRL_RXENA) {
|
||||
gem_get_rx_desc(s);
|
||||
for (i = 0; i < s->num_priority_queues; ++i) {
|
||||
gem_get_rx_desc(s, i);
|
||||
}
|
||||
}
|
||||
if (val & GEM_NWCTRL_TXSTART) {
|
||||
gem_transmit(s);
|
||||
}
|
||||
if (!(val & GEM_NWCTRL_TXENA)) {
|
||||
/* Reset to start of Q when transmit disabled. */
|
||||
s->tx_desc_addr = s->regs[GEM_TXQBASE];
|
||||
for (i = 0; i < s->num_priority_queues; i++) {
|
||||
s->tx_desc_addr[i] = s->regs[GEM_TXQBASE];
|
||||
}
|
||||
}
|
||||
if (gem_can_receive(qemu_get_queue(s->nic))) {
|
||||
qemu_flush_queued_packets(qemu_get_queue(s->nic));
|
||||
@@ -1150,10 +1370,16 @@ static void gem_write(void *opaque, hwaddr offset, uint64_t val,
|
||||
gem_update_int_status(s);
|
||||
break;
|
||||
case GEM_RXQBASE:
|
||||
s->rx_desc_addr = val;
|
||||
s->rx_desc_addr[0] = val;
|
||||
break;
|
||||
case GEM_RECEIVE_Q1_PTR ... GEM_RECEIVE_Q15_PTR:
|
||||
s->rx_desc_addr[offset - GEM_RECEIVE_Q1_PTR + 1] = val;
|
||||
break;
|
||||
case GEM_TXQBASE:
|
||||
s->tx_desc_addr = val;
|
||||
s->tx_desc_addr[0] = val;
|
||||
break;
|
||||
case GEM_TRANSMIT_Q1_PTR ... GEM_TRANSMIT_Q15_PTR:
|
||||
s->tx_desc_addr[offset - GEM_TRANSMIT_Q1_PTR + 1] = val;
|
||||
break;
|
||||
case GEM_RXSTATUS:
|
||||
gem_update_int_status(s);
|
||||
@@ -1162,10 +1388,26 @@ static void gem_write(void *opaque, hwaddr offset, uint64_t val,
|
||||
s->regs[GEM_IMR] &= ~val;
|
||||
gem_update_int_status(s);
|
||||
break;
|
||||
case GEM_INT_Q1_ENABLE ... GEM_INT_Q7_ENABLE:
|
||||
s->regs[GEM_INT_Q1_MASK + offset - GEM_INT_Q1_ENABLE] &= ~val;
|
||||
gem_update_int_status(s);
|
||||
break;
|
||||
case GEM_INT_Q8_ENABLE ... GEM_INT_Q15_ENABLE:
|
||||
s->regs[GEM_INT_Q8_MASK + offset - GEM_INT_Q8_ENABLE] &= ~val;
|
||||
gem_update_int_status(s);
|
||||
break;
|
||||
case GEM_IDR:
|
||||
s->regs[GEM_IMR] |= val;
|
||||
gem_update_int_status(s);
|
||||
break;
|
||||
case GEM_INT_Q1_DISABLE ... GEM_INT_Q7_DISABLE:
|
||||
s->regs[GEM_INT_Q1_MASK + offset - GEM_INT_Q1_DISABLE] |= val;
|
||||
gem_update_int_status(s);
|
||||
break;
|
||||
case GEM_INT_Q8_DISABLE ... GEM_INT_Q15_DISABLE:
|
||||
s->regs[GEM_INT_Q8_MASK + offset - GEM_INT_Q8_DISABLE] |= val;
|
||||
gem_update_int_status(s);
|
||||
break;
|
||||
case GEM_SPADDR1LO:
|
||||
case GEM_SPADDR2LO:
|
||||
case GEM_SPADDR3LO:
|
||||
@@ -1202,8 +1444,11 @@ static const MemoryRegionOps gem_ops = {
|
||||
|
||||
static void gem_set_link(NetClientState *nc)
|
||||
{
|
||||
CadenceGEMState *s = qemu_get_nic_opaque(nc);
|
||||
|
||||
DB_PRINT("\n");
|
||||
phy_update_link(qemu_get_nic_opaque(nc));
|
||||
phy_update_link(s);
|
||||
gem_update_int_status(s);
|
||||
}
|
||||
|
||||
static NetClientInfo net_gem_info = {
|
||||
@@ -1214,36 +1459,62 @@ static NetClientInfo net_gem_info = {
|
||||
.link_status_changed = gem_set_link,
|
||||
};
|
||||
|
||||
static int gem_init(SysBusDevice *sbd)
|
||||
static void gem_realize(DeviceState *dev, Error **errp)
|
||||
{
|
||||
DeviceState *dev = DEVICE(sbd);
|
||||
CadenceGEMState *s = CADENCE_GEM(dev);
|
||||
int i;
|
||||
|
||||
if (s->num_priority_queues == 0 ||
|
||||
s->num_priority_queues > MAX_PRIORITY_QUEUES) {
|
||||
error_setg(errp, "Invalid num-priority-queues value: %" PRIx8,
|
||||
s->num_priority_queues);
|
||||
return;
|
||||
} else if (s->num_type1_screeners > MAX_TYPE1_SCREENERS) {
|
||||
error_setg(errp, "Invalid num-type1-screeners value: %" PRIx8,
|
||||
s->num_type1_screeners);
|
||||
return;
|
||||
} else if (s->num_type2_screeners > MAX_TYPE2_SCREENERS) {
|
||||
error_setg(errp, "Invalid num-type2-screeners value: %" PRIx8,
|
||||
s->num_type2_screeners);
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < s->num_priority_queues; ++i) {
|
||||
sysbus_init_irq(SYS_BUS_DEVICE(dev), &s->irq[i]);
|
||||
}
|
||||
|
||||
qemu_macaddr_default_if_unset(&s->conf.macaddr);
|
||||
|
||||
s->nic = qemu_new_nic(&net_gem_info, &s->conf,
|
||||
object_get_typename(OBJECT(dev)), dev->id, s);
|
||||
}
|
||||
|
||||
static void gem_init(Object *obj)
|
||||
{
|
||||
CadenceGEMState *s = CADENCE_GEM(obj);
|
||||
DeviceState *dev = DEVICE(obj);
|
||||
|
||||
DB_PRINT("\n");
|
||||
|
||||
gem_init_register_masks(s);
|
||||
memory_region_init_io(&s->iomem, OBJECT(s), &gem_ops, s,
|
||||
"enet", sizeof(s->regs));
|
||||
sysbus_init_mmio(sbd, &s->iomem);
|
||||
sysbus_init_irq(sbd, &s->irq);
|
||||
qemu_macaddr_default_if_unset(&s->conf.macaddr);
|
||||
|
||||
s->nic = qemu_new_nic(&net_gem_info, &s->conf,
|
||||
object_get_typename(OBJECT(dev)), dev->id, s);
|
||||
|
||||
return 0;
|
||||
sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->iomem);
|
||||
}
|
||||
|
||||
static const VMStateDescription vmstate_cadence_gem = {
|
||||
.name = "cadence_gem",
|
||||
.version_id = 2,
|
||||
.minimum_version_id = 2,
|
||||
.version_id = 4,
|
||||
.minimum_version_id = 4,
|
||||
.fields = (VMStateField[]) {
|
||||
VMSTATE_UINT32_ARRAY(regs, CadenceGEMState, CADENCE_GEM_MAXREG),
|
||||
VMSTATE_UINT16_ARRAY(phy_regs, CadenceGEMState, 32),
|
||||
VMSTATE_UINT8(phy_loop, CadenceGEMState),
|
||||
VMSTATE_UINT32(rx_desc_addr, CadenceGEMState),
|
||||
VMSTATE_UINT32(tx_desc_addr, CadenceGEMState),
|
||||
VMSTATE_UINT32_ARRAY(rx_desc_addr, CadenceGEMState,
|
||||
MAX_PRIORITY_QUEUES),
|
||||
VMSTATE_UINT32_ARRAY(tx_desc_addr, CadenceGEMState,
|
||||
MAX_PRIORITY_QUEUES),
|
||||
VMSTATE_BOOL_ARRAY(sar_active, CadenceGEMState, 4),
|
||||
VMSTATE_END_OF_LIST(),
|
||||
}
|
||||
@@ -1251,15 +1522,20 @@ static const VMStateDescription vmstate_cadence_gem = {
|
||||
|
||||
static Property gem_properties[] = {
|
||||
DEFINE_NIC_PROPERTIES(CadenceGEMState, conf),
|
||||
DEFINE_PROP_UINT8("num-priority-queues", CadenceGEMState,
|
||||
num_priority_queues, 1),
|
||||
DEFINE_PROP_UINT8("num-type1-screeners", CadenceGEMState,
|
||||
num_type1_screeners, 4),
|
||||
DEFINE_PROP_UINT8("num-type2-screeners", CadenceGEMState,
|
||||
num_type2_screeners, 4),
|
||||
DEFINE_PROP_END_OF_LIST(),
|
||||
};
|
||||
|
||||
static void gem_class_init(ObjectClass *klass, void *data)
|
||||
{
|
||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||
SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass);
|
||||
|
||||
sdc->init = gem_init;
|
||||
dc->realize = gem_realize;
|
||||
dc->props = gem_properties;
|
||||
dc->vmsd = &vmstate_cadence_gem;
|
||||
dc->reset = gem_reset;
|
||||
@@ -1269,6 +1545,7 @@ static const TypeInfo gem_info = {
|
||||
.name = TYPE_CADENCE_GEM,
|
||||
.parent = TYPE_SYS_BUS_DEVICE,
|
||||
.instance_size = sizeof(CadenceGEMState),
|
||||
.instance_init = gem_init,
|
||||
.class_init = gem_class_init,
|
||||
};
|
||||
|
||||
|
@@ -387,7 +387,7 @@ static void etsec_realize(DeviceState *dev, Error **errp)
|
||||
|
||||
|
||||
etsec->bh = qemu_bh_new(etsec_timer_hit, etsec);
|
||||
etsec->ptimer = ptimer_init(etsec->bh);
|
||||
etsec->ptimer = ptimer_init(etsec->bh, PTIMER_POLICY_DEFAULT);
|
||||
ptimer_set_freq(etsec->ptimer, 100);
|
||||
}
|
||||
|
||||
|
@@ -1345,7 +1345,7 @@ static int lan9118_init1(SysBusDevice *sbd)
|
||||
s->txp = &s->tx_packet;
|
||||
|
||||
bh = qemu_bh_new(lan9118_tick, s);
|
||||
s->timer = ptimer_init(bh);
|
||||
s->timer = ptimer_init(bh, PTIMER_POLICY_DEFAULT);
|
||||
ptimer_set_freq(s->timer, 10000);
|
||||
ptimer_set_limit(s->timer, 0xffff, 1);
|
||||
|
||||
|
@@ -34,20 +34,13 @@
|
||||
#include "hw/ppc/spapr.h"
|
||||
#include "hw/ppc/spapr_vio.h"
|
||||
#include "sysemu/sysemu.h"
|
||||
#include "trace.h"
|
||||
|
||||
#include <libfdt.h>
|
||||
|
||||
#define ETH_ALEN 6
|
||||
#define MAX_PACKET_SIZE 65536
|
||||
|
||||
/*#define DEBUG*/
|
||||
|
||||
#ifdef DEBUG
|
||||
#define DPRINTF(fmt...) do { fprintf(stderr, fmt); } while (0)
|
||||
#else
|
||||
#define DPRINTF(fmt...)
|
||||
#endif
|
||||
|
||||
/* Compatibility flags for migration */
|
||||
#define SPAPRVLAN_FLAG_RX_BUF_POOLS_BIT 0
|
||||
#define SPAPRVLAN_FLAG_RX_BUF_POOLS (1 << SPAPRVLAN_FLAG_RX_BUF_POOLS_BIT)
|
||||
@@ -158,8 +151,10 @@ static vlan_bd_t spapr_vlan_get_rx_bd_from_pool(VIOsPAPRVLANDevice *dev,
|
||||
return 0;
|
||||
}
|
||||
|
||||
DPRINTF("Found buffer: pool=%d count=%d rxbufs=%d\n", pool,
|
||||
dev->rx_pool[pool]->count, dev->rx_bufs);
|
||||
|
||||
trace_spapr_vlan_get_rx_bd_from_pool_found(pool,
|
||||
dev->rx_pool[pool]->count,
|
||||
dev->rx_bufs);
|
||||
|
||||
/* Remove the buffer from the pool */
|
||||
dev->rx_pool[pool]->count--;
|
||||
@@ -186,8 +181,8 @@ static vlan_bd_t spapr_vlan_get_rx_bd_from_page(VIOsPAPRVLANDevice *dev,
|
||||
}
|
||||
|
||||
bd = vio_ldq(&dev->sdev, dev->buf_list + buf_ptr);
|
||||
DPRINTF("use_buf_ptr=%d bd=0x%016llx\n",
|
||||
buf_ptr, (unsigned long long)bd);
|
||||
|
||||
trace_spapr_vlan_get_rx_bd_from_page(buf_ptr, (uint64_t)bd);
|
||||
} while ((!(bd & VLAN_BD_VALID) || VLAN_BD_LEN(bd) < size + 8)
|
||||
&& buf_ptr != dev->use_buf_ptr);
|
||||
|
||||
@@ -200,7 +195,7 @@ static vlan_bd_t spapr_vlan_get_rx_bd_from_page(VIOsPAPRVLANDevice *dev,
|
||||
dev->use_buf_ptr = buf_ptr;
|
||||
vio_stq(&dev->sdev, dev->buf_list + dev->use_buf_ptr, 0);
|
||||
|
||||
DPRINTF("Found buffer: ptr=%d rxbufs=%d\n", dev->use_buf_ptr, dev->rx_bufs);
|
||||
trace_spapr_vlan_get_rx_bd_from_page_found(dev->use_buf_ptr, dev->rx_bufs);
|
||||
|
||||
return bd;
|
||||
}
|
||||
@@ -215,8 +210,7 @@ static ssize_t spapr_vlan_receive(NetClientState *nc, const uint8_t *buf,
|
||||
uint64_t handle;
|
||||
uint8_t control;
|
||||
|
||||
DPRINTF("spapr_vlan_receive() [%s] rx_bufs=%d\n", sdev->qdev.id,
|
||||
dev->rx_bufs);
|
||||
trace_spapr_vlan_receive(sdev->qdev.id, dev->rx_bufs);
|
||||
|
||||
if (!dev->isopen) {
|
||||
return -1;
|
||||
@@ -244,7 +238,7 @@ static ssize_t spapr_vlan_receive(NetClientState *nc, const uint8_t *buf,
|
||||
return -1;
|
||||
}
|
||||
|
||||
DPRINTF("spapr_vlan_receive: DMA write completed\n");
|
||||
trace_spapr_vlan_receive_dma_completed();
|
||||
|
||||
/* Update the receive queue */
|
||||
control = VLAN_RXQC_TOGGLE | VLAN_RXQC_VALID;
|
||||
@@ -258,12 +252,11 @@ static ssize_t spapr_vlan_receive(NetClientState *nc, const uint8_t *buf,
|
||||
vio_sth(sdev, VLAN_BD_ADDR(rxq_bd) + dev->rxq_ptr + 2, 8);
|
||||
vio_stb(sdev, VLAN_BD_ADDR(rxq_bd) + dev->rxq_ptr, control);
|
||||
|
||||
DPRINTF("wrote rxq entry (ptr=0x%llx): 0x%016llx 0x%016llx\n",
|
||||
(unsigned long long)dev->rxq_ptr,
|
||||
(unsigned long long)vio_ldq(sdev, VLAN_BD_ADDR(rxq_bd) +
|
||||
dev->rxq_ptr),
|
||||
(unsigned long long)vio_ldq(sdev, VLAN_BD_ADDR(rxq_bd) +
|
||||
dev->rxq_ptr + 8));
|
||||
trace_spapr_vlan_receive_wrote(dev->rxq_ptr,
|
||||
vio_ldq(sdev, VLAN_BD_ADDR(rxq_bd) +
|
||||
dev->rxq_ptr),
|
||||
vio_ldq(sdev, VLAN_BD_ADDR(rxq_bd) +
|
||||
dev->rxq_ptr + 8));
|
||||
|
||||
dev->rxq_ptr += 16;
|
||||
if (dev->rxq_ptr >= VLAN_BD_LEN(rxq_bd)) {
|
||||
@@ -580,8 +573,8 @@ static target_long spapr_vlan_add_rxbuf_to_pool(VIOsPAPRVLANDevice *dev,
|
||||
qsort(dev->rx_pool, RX_MAX_POOLS, sizeof(dev->rx_pool[0]),
|
||||
rx_pool_size_compare);
|
||||
pool = spapr_vlan_get_rx_pool_id(dev, size);
|
||||
DPRINTF("created RX pool %d for size %lld\n", pool,
|
||||
VLAN_BD_LEN(buf));
|
||||
trace_spapr_vlan_add_rxbuf_to_pool_create(pool,
|
||||
VLAN_BD_LEN(buf));
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -591,8 +584,8 @@ static target_long spapr_vlan_add_rxbuf_to_pool(VIOsPAPRVLANDevice *dev,
|
||||
return H_RESOURCE;
|
||||
}
|
||||
|
||||
DPRINTF("h_add_llan_buf(): Add buf using pool %i (size %lli, count=%i)\n",
|
||||
pool, VLAN_BD_LEN(buf), dev->rx_pool[pool]->count);
|
||||
trace_spapr_vlan_add_rxbuf_to_pool(pool, VLAN_BD_LEN(buf),
|
||||
dev->rx_pool[pool]->count);
|
||||
|
||||
dev->rx_pool[pool]->bds[dev->rx_pool[pool]->count++] = buf;
|
||||
|
||||
@@ -623,8 +616,7 @@ static target_long spapr_vlan_add_rxbuf_to_page(VIOsPAPRVLANDevice *dev,
|
||||
|
||||
vio_stq(&dev->sdev, dev->buf_list + dev->add_buf_ptr, buf);
|
||||
|
||||
DPRINTF("h_add_llan_buf(): Added buf ptr=%d rx_bufs=%d bd=0x%016llx\n",
|
||||
dev->add_buf_ptr, dev->rx_bufs, (unsigned long long)buf);
|
||||
trace_spapr_vlan_add_rxbuf_to_page(dev->add_buf_ptr, dev->rx_bufs, buf);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -640,8 +632,7 @@ static target_ulong h_add_logical_lan_buffer(PowerPCCPU *cpu,
|
||||
VIOsPAPRVLANDevice *dev = VIO_SPAPR_VLAN_DEVICE(sdev);
|
||||
target_long ret;
|
||||
|
||||
DPRINTF("H_ADD_LOGICAL_LAN_BUFFER(0x" TARGET_FMT_lx
|
||||
", 0x" TARGET_FMT_lx ")\n", reg, buf);
|
||||
trace_spapr_vlan_h_add_logical_lan_buffer(reg, buf);
|
||||
|
||||
if (!sdev) {
|
||||
hcall_dprintf("Bad device\n");
|
||||
@@ -694,14 +685,13 @@ static target_ulong h_send_logical_lan(PowerPCCPU *cpu,
|
||||
int i, nbufs;
|
||||
int ret;
|
||||
|
||||
DPRINTF("H_SEND_LOGICAL_LAN(0x" TARGET_FMT_lx ", <bufs>, 0x"
|
||||
TARGET_FMT_lx ")\n", reg, continue_token);
|
||||
trace_spapr_vlan_h_send_logical_lan(reg, continue_token);
|
||||
|
||||
if (!sdev) {
|
||||
return H_PARAMETER;
|
||||
}
|
||||
|
||||
DPRINTF("rxbufs = %d\n", dev->rx_bufs);
|
||||
trace_spapr_vlan_h_send_logical_lan_rxbufs(dev->rx_bufs);
|
||||
|
||||
if (!dev->isopen) {
|
||||
return H_DROPPED;
|
||||
@@ -713,7 +703,7 @@ static target_ulong h_send_logical_lan(PowerPCCPU *cpu,
|
||||
|
||||
total_len = 0;
|
||||
for (i = 0; i < 6; i++) {
|
||||
DPRINTF(" buf desc: 0x" TARGET_FMT_lx "\n", bufs[i]);
|
||||
trace_spapr_vlan_h_send_logical_lan_buf_desc(bufs[i]);
|
||||
if (!(bufs[i] & VLAN_BD_VALID)) {
|
||||
break;
|
||||
}
|
||||
@@ -721,8 +711,7 @@ static target_ulong h_send_logical_lan(PowerPCCPU *cpu,
|
||||
}
|
||||
|
||||
nbufs = i;
|
||||
DPRINTF("h_send_logical_lan() %d buffers, total length 0x%x\n",
|
||||
nbufs, total_len);
|
||||
trace_spapr_vlan_h_send_logical_lan_total(nbufs, total_len);
|
||||
|
||||
if (total_len == 0) {
|
||||
return H_SUCCESS;
|
||||
|
@@ -270,3 +270,19 @@ e1000e_cfg_support_virtio(bool support) "Virtio header supported: %d"
|
||||
|
||||
e1000e_vm_state_running(void) "VM state is running"
|
||||
e1000e_vm_state_stopped(void) "VM state is stopped"
|
||||
|
||||
# hw/net/spapr_llan.c
|
||||
spapr_vlan_get_rx_bd_from_pool_found(int pool, int32_t count, uint32_t rx_bufs) "pool=%d count=%"PRId32" rxbufs=%"PRIu32
|
||||
spapr_vlan_get_rx_bd_from_page(int buf_ptr, uint64_t bd) "use_buf_ptr=%d bd=0x%016"PRIx64
|
||||
spapr_vlan_get_rx_bd_from_page_found(uint32_t use_buf_ptr, uint32_t rx_bufs) "ptr=%"PRIu32" rxbufs=%"PRIu32
|
||||
spapr_vlan_receive(const char *id, uint32_t rx_bufs) "[%s] rx_bufs=%"PRIu32
|
||||
spapr_vlan_receive_dma_completed(void) "DMA write completed"
|
||||
spapr_vlan_receive_wrote(uint64_t ptr, uint64_t hi, uint64_t lo) "rxq entry (ptr=0x%"PRIx64"): 0x%016"PRIx64" 0x%016"PRIx64
|
||||
spapr_vlan_add_rxbuf_to_pool_create(int pool, uint64_t len) "created RX pool %d for size %"PRIu64
|
||||
spapr_vlan_add_rxbuf_to_pool(int pool, uint64_t len, int32_t count) "add buf using pool %d (size %"PRIu64", count=%"PRId32")"
|
||||
spapr_vlan_add_rxbuf_to_page(uint32_t ptr, uint32_t rx_bufs, uint64_t bd) "added buf ptr=%"PRIu32" rx_bufs=%"PRIu32" bd=0x%016"PRIx64
|
||||
spapr_vlan_h_add_logical_lan_buffer(uint64_t reg, uint64_t buf) "H_ADD_LOGICAL_LAN_BUFFER(0x%"PRIx64", 0x%"PRIx64")"
|
||||
spapr_vlan_h_send_logical_lan(uint64_t reg, uint64_t continue_token) "H_SEND_LOGICAL_LAN(0x%"PRIx64", <bufs>, 0x%"PRIx64")"
|
||||
spapr_vlan_h_send_logical_lan_rxbufs(uint32_t rx_bufs) "rxbufs = %"PRIu32
|
||||
spapr_vlan_h_send_logical_lan_buf_desc(uint64_t buf) " buf desc: 0x%"PRIx64
|
||||
spapr_vlan_h_send_logical_lan_total(int nbufs, unsigned total_len) "%d buffers, total length 0x%x"
|
||||
|
@@ -180,7 +180,7 @@ static void fw_cfg_bootsplash(FWCfgState *s)
|
||||
temp = qemu_opt_get(opts, "splash-time");
|
||||
if (temp != NULL) {
|
||||
p = (char *)temp;
|
||||
boot_splash_time = strtol(p, (char **)&p, 10);
|
||||
boot_splash_time = strtol(p, &p, 10);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -240,7 +240,7 @@ static void fw_cfg_reboot(FWCfgState *s)
|
||||
temp = qemu_opt_get(opts, "reboot-timeout");
|
||||
if (temp != NULL) {
|
||||
p = (char *)temp;
|
||||
reboot_timeout = strtol(p, (char **)&p, 10);
|
||||
reboot_timeout = strtol(p, &p, 10);
|
||||
}
|
||||
}
|
||||
/* validate the input */
|
||||
@@ -883,7 +883,7 @@ static void fw_cfg_init1(DeviceState *dev)
|
||||
qdev_init_nofail(dev);
|
||||
|
||||
fw_cfg_add_bytes(s, FW_CFG_SIGNATURE, (char *)"QEMU", 4);
|
||||
fw_cfg_add_bytes(s, FW_CFG_UUID, qemu_uuid, 16);
|
||||
fw_cfg_add_bytes(s, FW_CFG_UUID, &qemu_uuid, 16);
|
||||
fw_cfg_add_i16(s, FW_CFG_NOGRAPHIC, (uint16_t)!machine->enable_graphics);
|
||||
fw_cfg_add_i16(s, FW_CFG_NB_CPUS, (uint16_t)smp_cpus);
|
||||
fw_cfg_add_i16(s, FW_CFG_BOOT_MENU, (uint16_t)boot_menu);
|
||||
|
@@ -71,11 +71,5 @@ CPUPPCState *ppc405ep_init(MemoryRegion *address_space_mem,
|
||||
hwaddr ram_sizes[2],
|
||||
uint32_t sysclk, qemu_irq **picp,
|
||||
int do_init);
|
||||
/* IBM STBxxx microcontrollers */
|
||||
CPUPPCState *ppc_stb025_init (MemoryRegion ram_memories[2],
|
||||
hwaddr ram_bases[2],
|
||||
hwaddr ram_sizes[2],
|
||||
uint32_t sysclk, qemu_irq **picp,
|
||||
ram_addr_t *offsetp);
|
||||
|
||||
#endif /* PPC405_H */
|
||||
|
@@ -332,12 +332,7 @@ static void *spapr_create_fdt_skel(hwaddr initrd_base,
|
||||
g_free(buf);
|
||||
}
|
||||
|
||||
buf = g_strdup_printf(UUID_FMT, qemu_uuid[0], qemu_uuid[1],
|
||||
qemu_uuid[2], qemu_uuid[3], qemu_uuid[4],
|
||||
qemu_uuid[5], qemu_uuid[6], qemu_uuid[7],
|
||||
qemu_uuid[8], qemu_uuid[9], qemu_uuid[10],
|
||||
qemu_uuid[11], qemu_uuid[12], qemu_uuid[13],
|
||||
qemu_uuid[14], qemu_uuid[15]);
|
||||
buf = qemu_uuid_unparse_strdup(&qemu_uuid);
|
||||
|
||||
_FDT((fdt_property_string(fdt, "vm,uuid", buf)));
|
||||
if (qemu_uuid_set) {
|
||||
@@ -1814,6 +1809,9 @@ static void ppc_spapr_init(MachineState *machine)
|
||||
/* Enable H_LOGICAL_CI_* so SLOF can talk to in-kernel devices */
|
||||
kvmppc_enable_logical_ci_hcalls();
|
||||
kvmppc_enable_set_mode_hcall();
|
||||
|
||||
/* H_CLEAR_MOD/_REF are mandatory in PAPR, but off by default */
|
||||
kvmppc_enable_clear_ref_mod_hcalls();
|
||||
}
|
||||
|
||||
/* allocate RAM */
|
||||
@@ -2312,8 +2310,8 @@ static void spapr_machine_device_pre_plug(HotplugHandler *hotplug_dev,
|
||||
}
|
||||
}
|
||||
|
||||
static HotplugHandler *spapr_get_hotpug_handler(MachineState *machine,
|
||||
DeviceState *dev)
|
||||
static HotplugHandler *spapr_get_hotplug_handler(MachineState *machine,
|
||||
DeviceState *dev)
|
||||
{
|
||||
if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM) ||
|
||||
object_dynamic_cast(OBJECT(dev), TYPE_SPAPR_CPU_CORE)) {
|
||||
@@ -2385,7 +2383,7 @@ static void spapr_machine_class_init(ObjectClass *oc, void *data)
|
||||
mc->kvm_type = spapr_kvm_type;
|
||||
mc->has_dynamic_sysbus = true;
|
||||
mc->pci_allow_0_address = true;
|
||||
mc->get_hotplug_handler = spapr_get_hotpug_handler;
|
||||
mc->get_hotplug_handler = spapr_get_hotplug_handler;
|
||||
hc->pre_plug = spapr_machine_device_pre_plug;
|
||||
hc->plug = spapr_machine_device_plug;
|
||||
hc->unplug = spapr_machine_device_unplug;
|
||||
|
@@ -112,7 +112,8 @@ char *spapr_get_cpu_core_type(const char *model)
|
||||
static void spapr_core_release(DeviceState *dev, void *opaque)
|
||||
{
|
||||
sPAPRCPUCore *sc = SPAPR_CPU_CORE(OBJECT(dev));
|
||||
const char *typename = object_class_get_name(sc->cpu_class);
|
||||
sPAPRCPUCoreClass *scc = SPAPR_CPU_CORE_GET_CLASS(OBJECT(dev));
|
||||
const char *typename = object_class_get_name(scc->cpu_class);
|
||||
size_t size = object_type_get_instance_size(typename);
|
||||
sPAPRMachineState *spapr = SPAPR_MACHINE(qdev_get_machine());
|
||||
CPUCore *cc = CPU_CORE(dev);
|
||||
@@ -287,8 +288,9 @@ static void spapr_cpu_core_realize_child(Object *child, Error **errp)
|
||||
static void spapr_cpu_core_realize(DeviceState *dev, Error **errp)
|
||||
{
|
||||
sPAPRCPUCore *sc = SPAPR_CPU_CORE(OBJECT(dev));
|
||||
sPAPRCPUCoreClass *scc = SPAPR_CPU_CORE_GET_CLASS(OBJECT(dev));
|
||||
CPUCore *cc = CPU_CORE(OBJECT(dev));
|
||||
const char *typename = object_class_get_name(sc->cpu_class);
|
||||
const char *typename = object_class_get_name(scc->cpu_class);
|
||||
size_t size = object_type_get_instance_size(typename);
|
||||
Error *local_err = NULL;
|
||||
void *obj;
|
||||
@@ -331,83 +333,43 @@ err:
|
||||
error_propagate(errp, local_err);
|
||||
}
|
||||
|
||||
static void spapr_cpu_core_class_init(ObjectClass *oc, void *data)
|
||||
{
|
||||
DeviceClass *dc = DEVICE_CLASS(oc);
|
||||
dc->realize = spapr_cpu_core_realize;
|
||||
}
|
||||
|
||||
/*
|
||||
* instance_init routines from different flavours of sPAPR CPU cores.
|
||||
*/
|
||||
#define SPAPR_CPU_CORE_INITFN(_type, _fname) \
|
||||
static void glue(glue(spapr_cpu_core_, _fname), _initfn(Object *obj)) \
|
||||
{ \
|
||||
sPAPRCPUCore *core = SPAPR_CPU_CORE(obj); \
|
||||
char *name = g_strdup_printf("%s-" TYPE_POWERPC_CPU, stringify(_type)); \
|
||||
ObjectClass *oc = object_class_by_name(name); \
|
||||
g_assert(oc); \
|
||||
g_free((void *)name); \
|
||||
core->cpu_class = oc; \
|
||||
}
|
||||
|
||||
SPAPR_CPU_CORE_INITFN(970mp_v1.0, 970MP_v10);
|
||||
SPAPR_CPU_CORE_INITFN(970mp_v1.1, 970MP_v11);
|
||||
SPAPR_CPU_CORE_INITFN(970_v2.2, 970);
|
||||
SPAPR_CPU_CORE_INITFN(POWER5+_v2.1, POWER5plus);
|
||||
SPAPR_CPU_CORE_INITFN(POWER7_v2.3, POWER7);
|
||||
SPAPR_CPU_CORE_INITFN(POWER7+_v2.1, POWER7plus);
|
||||
SPAPR_CPU_CORE_INITFN(POWER8_v2.0, POWER8);
|
||||
SPAPR_CPU_CORE_INITFN(POWER8E_v2.1, POWER8E);
|
||||
SPAPR_CPU_CORE_INITFN(POWER8NVL_v1.0, POWER8NVL);
|
||||
|
||||
typedef struct SPAPRCoreInfo {
|
||||
const char *name;
|
||||
void (*initfn)(Object *obj);
|
||||
} SPAPRCoreInfo;
|
||||
|
||||
static const SPAPRCoreInfo spapr_cores[] = {
|
||||
static const char *spapr_core_models[] = {
|
||||
/* 970 */
|
||||
{ .name = "970_v2.2", .initfn = spapr_cpu_core_970_initfn },
|
||||
"970_v2.2",
|
||||
|
||||
/* 970MP variants */
|
||||
{ .name = "970MP_v1.0", .initfn = spapr_cpu_core_970MP_v10_initfn },
|
||||
{ .name = "970mp_v1.0", .initfn = spapr_cpu_core_970MP_v10_initfn },
|
||||
{ .name = "970MP_v1.1", .initfn = spapr_cpu_core_970MP_v11_initfn },
|
||||
{ .name = "970mp_v1.1", .initfn = spapr_cpu_core_970MP_v11_initfn },
|
||||
"970MP_v1.0",
|
||||
"970mp_v1.0",
|
||||
"970MP_v1.1",
|
||||
"970mp_v1.1",
|
||||
|
||||
/* POWER5+ */
|
||||
{ .name = "POWER5+_v2.1", .initfn = spapr_cpu_core_POWER5plus_initfn },
|
||||
"POWER5+_v2.1",
|
||||
|
||||
/* POWER7 */
|
||||
{ .name = "POWER7_v2.3", .initfn = spapr_cpu_core_POWER7_initfn },
|
||||
"POWER7_v2.3",
|
||||
|
||||
/* POWER7+ */
|
||||
{ .name = "POWER7+_v2.1", .initfn = spapr_cpu_core_POWER7plus_initfn },
|
||||
"POWER7+_v2.1",
|
||||
|
||||
/* POWER8 */
|
||||
{ .name = "POWER8_v2.0", .initfn = spapr_cpu_core_POWER8_initfn },
|
||||
"POWER8_v2.0",
|
||||
|
||||
/* POWER8E */
|
||||
{ .name = "POWER8E_v2.1", .initfn = spapr_cpu_core_POWER8E_initfn },
|
||||
"POWER8E_v2.1",
|
||||
|
||||
/* POWER8NVL */
|
||||
{ .name = "POWER8NVL_v1.0", .initfn = spapr_cpu_core_POWER8NVL_initfn },
|
||||
|
||||
{ .name = NULL }
|
||||
"POWER8NVL_v1.0",
|
||||
};
|
||||
|
||||
static void spapr_cpu_core_register(const SPAPRCoreInfo *info)
|
||||
void spapr_cpu_core_class_init(ObjectClass *oc, void *data)
|
||||
{
|
||||
TypeInfo type_info = {
|
||||
.parent = TYPE_SPAPR_CPU_CORE,
|
||||
.instance_size = sizeof(sPAPRCPUCore),
|
||||
.instance_init = info->initfn,
|
||||
};
|
||||
DeviceClass *dc = DEVICE_CLASS(oc);
|
||||
sPAPRCPUCoreClass *scc = SPAPR_CPU_CORE_CLASS(oc);
|
||||
|
||||
type_info.name = g_strdup_printf("%s-" TYPE_SPAPR_CPU_CORE, info->name);
|
||||
type_register(&type_info);
|
||||
g_free((void *)type_info.name);
|
||||
dc->realize = spapr_cpu_core_realize;
|
||||
scc->cpu_class = cpu_class_by_name(TYPE_POWERPC_CPU, data);
|
||||
g_assert(scc->cpu_class);
|
||||
}
|
||||
|
||||
static const TypeInfo spapr_cpu_core_type_info = {
|
||||
@@ -415,17 +377,27 @@ static const TypeInfo spapr_cpu_core_type_info = {
|
||||
.parent = TYPE_CPU_CORE,
|
||||
.abstract = true,
|
||||
.instance_size = sizeof(sPAPRCPUCore),
|
||||
.class_init = spapr_cpu_core_class_init,
|
||||
.class_size = sizeof(sPAPRCPUCoreClass),
|
||||
};
|
||||
|
||||
static void spapr_cpu_core_register_types(void)
|
||||
{
|
||||
const SPAPRCoreInfo *info = spapr_cores;
|
||||
int i;
|
||||
|
||||
type_register_static(&spapr_cpu_core_type_info);
|
||||
while (info->name) {
|
||||
spapr_cpu_core_register(info);
|
||||
info++;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(spapr_core_models); i++) {
|
||||
TypeInfo type_info = {
|
||||
.parent = TYPE_SPAPR_CPU_CORE,
|
||||
.instance_size = sizeof(sPAPRCPUCore),
|
||||
.class_init = spapr_cpu_core_class_init,
|
||||
.class_data = (void *) spapr_core_models[i],
|
||||
};
|
||||
|
||||
type_info.name = g_strdup_printf("%s-" TYPE_SPAPR_CPU_CORE,
|
||||
spapr_core_models[i]);
|
||||
type_register(&type_info);
|
||||
g_free((void *)type_info.name);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -20,20 +20,7 @@
|
||||
#include "qapi/visitor.h"
|
||||
#include "qemu/error-report.h"
|
||||
#include "hw/ppc/spapr.h" /* for RTAS return codes */
|
||||
|
||||
/* #define DEBUG_SPAPR_DRC */
|
||||
|
||||
#ifdef DEBUG_SPAPR_DRC
|
||||
#define DPRINTF(fmt, ...) \
|
||||
do { fprintf(stderr, fmt, ## __VA_ARGS__); } while (0)
|
||||
#define DPRINTFN(fmt, ...) \
|
||||
do { DPRINTF(fmt, ## __VA_ARGS__); fprintf(stderr, "\n"); } while (0)
|
||||
#else
|
||||
#define DPRINTF(fmt, ...) \
|
||||
do { } while (0)
|
||||
#define DPRINTFN(fmt, ...) \
|
||||
do { } while (0)
|
||||
#endif
|
||||
#include "trace.h"
|
||||
|
||||
#define DRC_CONTAINER_PATH "/dr-connector"
|
||||
#define DRC_INDEX_TYPE_SHIFT 28
|
||||
@@ -69,7 +56,7 @@ static uint32_t set_isolation_state(sPAPRDRConnector *drc,
|
||||
{
|
||||
sPAPRDRConnectorClass *drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
|
||||
|
||||
DPRINTFN("drc: %x, set_isolation_state: %x", get_index(drc), state);
|
||||
trace_spapr_drc_set_isolation_state(get_index(drc), state);
|
||||
|
||||
if (state == SPAPR_DR_ISOLATION_STATE_UNISOLATED) {
|
||||
/* cannot unisolate a non-existant resource, and, or resources
|
||||
@@ -94,11 +81,11 @@ static uint32_t set_isolation_state(sPAPRDRConnector *drc,
|
||||
*/
|
||||
if (drc->awaiting_release) {
|
||||
if (drc->configured) {
|
||||
DPRINTFN("finalizing device removal");
|
||||
trace_spapr_drc_set_isolation_state_finalizing(get_index(drc));
|
||||
drck->detach(drc, DEVICE(drc->dev), drc->detach_cb,
|
||||
drc->detach_cb_opaque, NULL);
|
||||
} else {
|
||||
DPRINTFN("deferring device removal on unconfigured device\n");
|
||||
trace_spapr_drc_set_isolation_state_deferring(get_index(drc));
|
||||
}
|
||||
}
|
||||
drc->configured = false;
|
||||
@@ -110,7 +97,7 @@ static uint32_t set_isolation_state(sPAPRDRConnector *drc,
|
||||
static uint32_t set_indicator_state(sPAPRDRConnector *drc,
|
||||
sPAPRDRIndicatorState state)
|
||||
{
|
||||
DPRINTFN("drc: %x, set_indicator_state: %x", get_index(drc), state);
|
||||
trace_spapr_drc_set_indicator_state(get_index(drc), state);
|
||||
drc->indicator_state = state;
|
||||
return RTAS_OUT_SUCCESS;
|
||||
}
|
||||
@@ -120,7 +107,7 @@ static uint32_t set_allocation_state(sPAPRDRConnector *drc,
|
||||
{
|
||||
sPAPRDRConnectorClass *drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
|
||||
|
||||
DPRINTFN("drc: %x, set_allocation_state: %x", get_index(drc), state);
|
||||
trace_spapr_drc_set_allocation_state(get_index(drc), state);
|
||||
|
||||
if (state == SPAPR_DR_ALLOCATION_STATE_USABLE) {
|
||||
/* if there's no resource/device associated with the DRC, there's
|
||||
@@ -137,7 +124,7 @@ static uint32_t set_allocation_state(sPAPRDRConnector *drc,
|
||||
drc->allocation_state = state;
|
||||
if (drc->awaiting_release &&
|
||||
drc->allocation_state == SPAPR_DR_ALLOCATION_STATE_UNUSABLE) {
|
||||
DPRINTFN("finalizing device removal");
|
||||
trace_spapr_drc_set_allocation_state_finalizing(get_index(drc));
|
||||
drck->detach(drc, DEVICE(drc->dev), drc->detach_cb,
|
||||
drc->detach_cb_opaque, NULL);
|
||||
} else if (drc->allocation_state == SPAPR_DR_ALLOCATION_STATE_USABLE) {
|
||||
@@ -167,12 +154,11 @@ static const void *get_fdt(sPAPRDRConnector *drc, int *fdt_start_offset)
|
||||
|
||||
static void set_configured(sPAPRDRConnector *drc)
|
||||
{
|
||||
DPRINTFN("drc: %x, set_configured", get_index(drc));
|
||||
trace_spapr_drc_set_configured(get_index(drc));
|
||||
|
||||
if (drc->isolation_state != SPAPR_DR_ISOLATION_STATE_UNISOLATED) {
|
||||
/* guest should be not configuring an isolated device */
|
||||
DPRINTFN("drc: %x, set_configured: skipping isolated device",
|
||||
get_index(drc));
|
||||
trace_spapr_drc_set_configured_skipping(get_index(drc));
|
||||
return;
|
||||
}
|
||||
drc->configured = true;
|
||||
@@ -222,7 +208,7 @@ static uint32_t entity_sense(sPAPRDRConnector *drc, sPAPRDREntitySense *state)
|
||||
}
|
||||
}
|
||||
|
||||
DPRINTFN("drc: %x, entity_sense: %x", get_index(drc), state);
|
||||
trace_spapr_drc_entity_sense(get_index(drc), *state);
|
||||
return RTAS_OUT_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -336,7 +322,7 @@ static void prop_get_fdt(Object *obj, Visitor *v, const char *name,
|
||||
static void attach(sPAPRDRConnector *drc, DeviceState *d, void *fdt,
|
||||
int fdt_start_offset, bool coldplug, Error **errp)
|
||||
{
|
||||
DPRINTFN("drc: %x, attach", get_index(drc));
|
||||
trace_spapr_drc_attach(get_index(drc));
|
||||
|
||||
if (drc->isolation_state != SPAPR_DR_ISOLATION_STATE_ISOLATED) {
|
||||
error_setg(errp, "an attached device is still awaiting release");
|
||||
@@ -389,7 +375,7 @@ static void detach(sPAPRDRConnector *drc, DeviceState *d,
|
||||
spapr_drc_detach_cb *detach_cb,
|
||||
void *detach_cb_opaque, Error **errp)
|
||||
{
|
||||
DPRINTFN("drc: %x, detach", get_index(drc));
|
||||
trace_spapr_drc_detach(get_index(drc));
|
||||
|
||||
drc->detach_cb = detach_cb;
|
||||
drc->detach_cb_opaque = detach_cb_opaque;
|
||||
@@ -415,21 +401,21 @@ static void detach(sPAPRDRConnector *drc, DeviceState *d,
|
||||
}
|
||||
|
||||
if (drc->isolation_state != SPAPR_DR_ISOLATION_STATE_ISOLATED) {
|
||||
DPRINTFN("awaiting transition to isolated state before removal");
|
||||
trace_spapr_drc_awaiting_isolated(get_index(drc));
|
||||
drc->awaiting_release = true;
|
||||
return;
|
||||
}
|
||||
|
||||
if (drc->type != SPAPR_DR_CONNECTOR_TYPE_PCI &&
|
||||
drc->allocation_state != SPAPR_DR_ALLOCATION_STATE_UNUSABLE) {
|
||||
DPRINTFN("awaiting transition to unusable state before removal");
|
||||
trace_spapr_drc_awaiting_unusable(get_index(drc));
|
||||
drc->awaiting_release = true;
|
||||
return;
|
||||
}
|
||||
|
||||
if (drc->awaiting_allocation) {
|
||||
drc->awaiting_release = true;
|
||||
DPRINTFN("awaiting allocation to complete before removal");
|
||||
trace_spapr_drc_awaiting_allocation(get_index(drc));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -460,7 +446,7 @@ static void reset(DeviceState *d)
|
||||
sPAPRDRConnectorClass *drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
|
||||
sPAPRDREntitySense state;
|
||||
|
||||
DPRINTFN("drc reset: %x", drck->get_index(drc));
|
||||
trace_spapr_drc_reset(drck->get_index(drc));
|
||||
/* immediately upon reset we can safely assume DRCs whose devices
|
||||
* are pending removal can be safely removed, and that they will
|
||||
* subsequently be left in an ISOLATED state. move the DRC to this
|
||||
@@ -502,7 +488,7 @@ static void realize(DeviceState *d, Error **errp)
|
||||
gchar *child_name;
|
||||
Error *err = NULL;
|
||||
|
||||
DPRINTFN("drc realize: %x", drck->get_index(drc));
|
||||
trace_spapr_drc_realize(drck->get_index(drc));
|
||||
/* NOTE: we do this as part of realize/unrealize due to the fact
|
||||
* that the guest will communicate with the DRC via RTAS calls
|
||||
* referencing the global DRC index. By unlinking the DRC
|
||||
@@ -513,7 +499,7 @@ static void realize(DeviceState *d, Error **errp)
|
||||
root_container = container_get(object_get_root(), DRC_CONTAINER_PATH);
|
||||
snprintf(link_name, sizeof(link_name), "%x", drck->get_index(drc));
|
||||
child_name = object_get_canonical_path_component(OBJECT(drc));
|
||||
DPRINTFN("drc child name: %s", child_name);
|
||||
trace_spapr_drc_realize_child(drck->get_index(drc), child_name);
|
||||
object_property_add_alias(root_container, link_name,
|
||||
drc->owner, child_name, &err);
|
||||
if (err) {
|
||||
@@ -521,7 +507,7 @@ static void realize(DeviceState *d, Error **errp)
|
||||
object_unref(OBJECT(drc));
|
||||
}
|
||||
g_free(child_name);
|
||||
DPRINTFN("drc realize complete");
|
||||
trace_spapr_drc_realize_complete(drck->get_index(drc));
|
||||
}
|
||||
|
||||
static void unrealize(DeviceState *d, Error **errp)
|
||||
@@ -532,7 +518,7 @@ static void unrealize(DeviceState *d, Error **errp)
|
||||
char name[256];
|
||||
Error *err = NULL;
|
||||
|
||||
DPRINTFN("drc unrealize: %x", drck->get_index(drc));
|
||||
trace_spapr_drc_unrealize(drck->get_index(drc));
|
||||
root_container = container_get(object_get_root(), DRC_CONTAINER_PATH);
|
||||
snprintf(name, sizeof(name), "%x", drck->get_index(drc));
|
||||
object_property_del(root_container, name, &err);
|
||||
|
@@ -201,7 +201,7 @@ static target_ulong h_remove(PowerPCCPU *cpu, sPAPRMachineState *spapr,
|
||||
|
||||
switch (ret) {
|
||||
case REMOVE_SUCCESS:
|
||||
check_tlb_flush(env);
|
||||
check_tlb_flush(env, true);
|
||||
return H_SUCCESS;
|
||||
|
||||
case REMOVE_NOT_FOUND:
|
||||
@@ -282,7 +282,7 @@ static target_ulong h_bulk_remove(PowerPCCPU *cpu, sPAPRMachineState *spapr,
|
||||
}
|
||||
}
|
||||
exit:
|
||||
check_tlb_flush(env);
|
||||
check_tlb_flush(env, true);
|
||||
|
||||
return rc;
|
||||
}
|
||||
@@ -319,6 +319,8 @@ static target_ulong h_protect(PowerPCCPU *cpu, sPAPRMachineState *spapr,
|
||||
ppc_hash64_store_hpte(cpu, pte_index,
|
||||
(v & ~HPTE64_V_VALID) | HPTE64_V_HPTE_DIRTY, 0);
|
||||
ppc_hash64_tlb_flush_hpte(cpu, pte_index, v, r);
|
||||
/* Flush the tlb */
|
||||
check_tlb_flush(env, true);
|
||||
/* Don't need a memory barrier, due to qemu's global lock */
|
||||
ppc_hash64_store_hpte(cpu, pte_index, v | HPTE64_V_HPTE_DIRTY, r);
|
||||
return H_SUCCESS;
|
||||
|
@@ -47,6 +47,7 @@
|
||||
#include "sysemu/device_tree.h"
|
||||
#include "sysemu/kvm.h"
|
||||
#include "sysemu/hostmem.h"
|
||||
#include "sysemu/numa.h"
|
||||
|
||||
#include "hw/vfio/vfio.h"
|
||||
|
||||
@@ -1544,6 +1545,7 @@ static Property spapr_phb_properties[] = {
|
||||
DEFINE_PROP_BOOL("ddw", sPAPRPHBState, ddw_enabled, true),
|
||||
DEFINE_PROP_UINT64("pgsz", sPAPRPHBState, page_size_mask,
|
||||
(1ULL << 12) | (1ULL << 16)),
|
||||
DEFINE_PROP_UINT32("numa_node", sPAPRPHBState, numa_node, -1),
|
||||
DEFINE_PROP_END_OF_LIST(),
|
||||
};
|
||||
|
||||
@@ -1805,6 +1807,11 @@ int spapr_populate_pci_dt(sPAPRPHBState *phb,
|
||||
cpu_to_be32(1),
|
||||
cpu_to_be32(RTAS_IBM_RESET_PE_DMA_WINDOW)
|
||||
};
|
||||
uint32_t associativity[] = {cpu_to_be32(0x4),
|
||||
cpu_to_be32(0x0),
|
||||
cpu_to_be32(0x0),
|
||||
cpu_to_be32(0x0),
|
||||
cpu_to_be32(phb->numa_node)};
|
||||
sPAPRTCETable *tcet;
|
||||
PCIBus *bus = PCI_HOST_BRIDGE(phb)->bus;
|
||||
sPAPRFDT s_fdt;
|
||||
@@ -1837,6 +1844,12 @@ int spapr_populate_pci_dt(sPAPRPHBState *phb,
|
||||
&ddw_extensions, sizeof(ddw_extensions)));
|
||||
}
|
||||
|
||||
/* Advertise NUMA via ibm,associativity */
|
||||
if (nb_numa_nodes > 1) {
|
||||
_FDT(fdt_setprop(fdt, bus_off, "ibm,associativity", associativity,
|
||||
sizeof(associativity)));
|
||||
}
|
||||
|
||||
/* Build the interrupt-map, this must matches what is done
|
||||
* in pci_spapr_map_irq
|
||||
*/
|
||||
|
@@ -37,6 +37,7 @@
|
||||
|
||||
#include "hw/ppc/spapr.h"
|
||||
#include "hw/ppc/spapr_vio.h"
|
||||
#include "hw/ppc/spapr_rtas.h"
|
||||
#include "hw/ppc/ppc.h"
|
||||
#include "qapi-event.h"
|
||||
#include "hw/boards.h"
|
||||
@@ -44,16 +45,7 @@
|
||||
#include <libfdt.h>
|
||||
#include "hw/ppc/spapr_drc.h"
|
||||
#include "qemu/cutils.h"
|
||||
|
||||
/* #define DEBUG_SPAPR */
|
||||
|
||||
#ifdef DEBUG_SPAPR
|
||||
#define DPRINTF(fmt, ...) \
|
||||
do { fprintf(stderr, fmt, ## __VA_ARGS__); } while (0)
|
||||
#else
|
||||
#define DPRINTF(fmt, ...) \
|
||||
do { } while (0)
|
||||
#endif
|
||||
#include "trace.h"
|
||||
|
||||
static sPAPRConfigureConnectorState *spapr_ccs_find(sPAPRMachineState *spapr,
|
||||
uint32_t drc_index)
|
||||
@@ -303,7 +295,8 @@ static void rtas_ibm_get_system_parameter(PowerPCCPU *cpu,
|
||||
break;
|
||||
}
|
||||
case RTAS_SYSPARM_UUID:
|
||||
ret = sysparm_st(buffer, length, qemu_uuid, (qemu_uuid_set ? 16 : 0));
|
||||
ret = sysparm_st(buffer, length, (unsigned char *)&qemu_uuid,
|
||||
(qemu_uuid_set ? 16 : 0));
|
||||
break;
|
||||
default:
|
||||
ret = RTAS_OUT_NOT_SUPPORTED;
|
||||
@@ -435,8 +428,7 @@ static void rtas_set_indicator(PowerPCCPU *cpu, sPAPRMachineState *spapr,
|
||||
/* if this is a DR sensor we can assume sensor_index == drc_index */
|
||||
drc = spapr_dr_connector_by_index(sensor_index);
|
||||
if (!drc) {
|
||||
DPRINTF("rtas_set_indicator: invalid sensor/DRC index: %xh\n",
|
||||
sensor_index);
|
||||
trace_spapr_rtas_set_indicator_invalid(sensor_index);
|
||||
ret = RTAS_OUT_PARAM_ERROR;
|
||||
goto out;
|
||||
}
|
||||
@@ -475,8 +467,7 @@ out:
|
||||
|
||||
out_unimplemented:
|
||||
/* currently only DR-related sensors are implemented */
|
||||
DPRINTF("rtas_set_indicator: sensor/indicator not implemented: %d\n",
|
||||
sensor_type);
|
||||
trace_spapr_rtas_set_indicator_not_supported(sensor_index, sensor_type);
|
||||
rtas_st(rets, 0, RTAS_OUT_NOT_SUPPORTED);
|
||||
}
|
||||
|
||||
@@ -502,16 +493,15 @@ static void rtas_get_sensor_state(PowerPCCPU *cpu, sPAPRMachineState *spapr,
|
||||
|
||||
if (sensor_type != RTAS_SENSOR_TYPE_ENTITY_SENSE) {
|
||||
/* currently only DR-related sensors are implemented */
|
||||
DPRINTF("rtas_get_sensor_state: sensor/indicator not implemented: %d\n",
|
||||
sensor_type);
|
||||
trace_spapr_rtas_get_sensor_state_not_supported(sensor_index,
|
||||
sensor_type);
|
||||
ret = RTAS_OUT_NOT_SUPPORTED;
|
||||
goto out;
|
||||
}
|
||||
|
||||
drc = spapr_dr_connector_by_index(sensor_index);
|
||||
if (!drc) {
|
||||
DPRINTF("rtas_get_sensor_state: invalid sensor/DRC index: %xh\n",
|
||||
sensor_index);
|
||||
trace_spapr_rtas_get_sensor_state_invalid(sensor_index);
|
||||
ret = RTAS_OUT_PARAM_ERROR;
|
||||
goto out;
|
||||
}
|
||||
@@ -568,8 +558,7 @@ static void rtas_ibm_configure_connector(PowerPCCPU *cpu,
|
||||
drc_index = rtas_ld(wa_addr, 0);
|
||||
drc = spapr_dr_connector_by_index(drc_index);
|
||||
if (!drc) {
|
||||
DPRINTF("rtas_ibm_configure_connector: invalid DRC index: %xh\n",
|
||||
drc_index);
|
||||
trace_spapr_rtas_ibm_configure_connector_invalid(drc_index);
|
||||
rc = RTAS_OUT_PARAM_ERROR;
|
||||
goto out;
|
||||
}
|
||||
@@ -577,8 +566,7 @@ static void rtas_ibm_configure_connector(PowerPCCPU *cpu,
|
||||
drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
|
||||
fdt = drck->get_fdt(drc, NULL);
|
||||
if (!fdt) {
|
||||
DPRINTF("rtas_ibm_configure_connector: Missing FDT for DRC index: %xh\n",
|
||||
drc_index);
|
||||
trace_spapr_rtas_ibm_configure_connector_missing_fdt(drc_index);
|
||||
rc = SPAPR_DR_CC_RESPONSE_NOT_CONFIGURABLE;
|
||||
goto out;
|
||||
}
|
||||
@@ -692,6 +680,24 @@ target_ulong spapr_rtas_call(PowerPCCPU *cpu, sPAPRMachineState *spapr,
|
||||
return H_PARAMETER;
|
||||
}
|
||||
|
||||
uint64_t qtest_rtas_call(char *cmd, uint32_t nargs, uint64_t args,
|
||||
uint32_t nret, uint64_t rets)
|
||||
{
|
||||
int token;
|
||||
|
||||
for (token = 0; token < RTAS_TOKEN_MAX - RTAS_TOKEN_BASE; token++) {
|
||||
if (strcmp(cmd, rtas_table[token].name) == 0) {
|
||||
sPAPRMachineState *spapr = SPAPR_MACHINE(qdev_get_machine());
|
||||
PowerPCCPU *cpu = POWERPC_CPU(first_cpu);
|
||||
|
||||
rtas_table[token].fn(cpu, spapr, token + RTAS_TOKEN_BASE,
|
||||
nargs, args, nret, rets);
|
||||
return H_SUCCESS;
|
||||
}
|
||||
}
|
||||
return H_PARAMETER;
|
||||
}
|
||||
|
||||
void spapr_rtas_register(int token, const char *name, spapr_rtas_fn fn)
|
||||
{
|
||||
assert((token >= RTAS_TOKEN_BASE) && (token < RTAS_TOKEN_MAX));
|
||||
|
@@ -36,19 +36,10 @@
|
||||
#include "hw/ppc/spapr.h"
|
||||
#include "hw/ppc/spapr_vio.h"
|
||||
#include "hw/ppc/xics.h"
|
||||
#include "trace.h"
|
||||
|
||||
#include <libfdt.h>
|
||||
|
||||
/* #define DEBUG_SPAPR */
|
||||
|
||||
#ifdef DEBUG_SPAPR
|
||||
#define DPRINTF(fmt, ...) \
|
||||
do { fprintf(stderr, fmt, ## __VA_ARGS__); } while (0)
|
||||
#else
|
||||
#define DPRINTF(fmt, ...) \
|
||||
do { } while (0)
|
||||
#endif
|
||||
|
||||
static Property spapr_vio_props[] = {
|
||||
DEFINE_PROP_UINT32("irq", VIOsPAPRDevice, irq, 0), \
|
||||
DEFINE_PROP_END_OF_LIST(),
|
||||
@@ -202,9 +193,7 @@ static target_ulong h_reg_crq(PowerPCCPU *cpu, sPAPRMachineState *spapr,
|
||||
dev->crq.qsize = queue_len;
|
||||
dev->crq.qnext = 0;
|
||||
|
||||
DPRINTF("CRQ for dev 0x" TARGET_FMT_lx " registered at 0x"
|
||||
TARGET_FMT_lx "/0x" TARGET_FMT_lx "\n",
|
||||
reg, queue_addr, queue_len);
|
||||
trace_spapr_vio_h_reg_crq(reg, queue_addr, queue_len);
|
||||
return H_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -214,7 +203,7 @@ static target_ulong free_crq(VIOsPAPRDevice *dev)
|
||||
dev->crq.qsize = 0;
|
||||
dev->crq.qnext = 0;
|
||||
|
||||
DPRINTF("CRQ for dev 0x%" PRIx32 " freed\n", dev->reg);
|
||||
trace_spapr_vio_free_crq(dev->reg);
|
||||
|
||||
return H_SUCCESS;
|
||||
}
|
||||
|
@@ -35,6 +35,39 @@ spapr_iommu_ddw_create(uint64_t buid, uint32_t cfgaddr, uint64_t pg_size, uint64
|
||||
spapr_iommu_ddw_remove(uint32_t liobn) "liobn=%"PRIx32
|
||||
spapr_iommu_ddw_reset(uint64_t buid, uint32_t cfgaddr) "buid=%"PRIx64" addr=%"PRIx32
|
||||
|
||||
# hw/ppc/spapr_drc.c
|
||||
spapr_drc_set_isolation_state(uint32_t index, int state) "drc: 0x%"PRIx32", state: %"PRIx32
|
||||
spapr_drc_set_isolation_state_finalizing(uint32_t index) "drc: 0x%"PRIx32
|
||||
spapr_drc_set_isolation_state_deferring(uint32_t index) "drc: 0x%"PRIx32
|
||||
spapr_drc_set_indicator_state(uint32_t index, int state) "drc: 0x%"PRIx32", state: 0x%x"
|
||||
spapr_drc_set_allocation_state(uint32_t index, int state) "drc: 0x%"PRIx32", state: 0x%x"
|
||||
spapr_drc_set_allocation_state_finalizing(uint32_t index) "drc: 0x%"PRIx32
|
||||
spapr_drc_set_configured(uint32_t index) "drc: 0x%"PRIx32
|
||||
spapr_drc_set_configured_skipping(uint32_t index) "drc: 0x%"PRIx32", isolated device"
|
||||
spapr_drc_entity_sense(uint32_t index, int state) "drc: 0x%"PRIx32", state: 0x%x"
|
||||
spapr_drc_attach(uint32_t index) "drc: 0x%"PRIx32
|
||||
spapr_drc_detach(uint32_t index) "drc: 0x%"PRIx32
|
||||
spapr_drc_awaiting_isolated(uint32_t index) "drc: 0x%"PRIx32
|
||||
spapr_drc_awaiting_unusable(uint32_t index) "drc: 0x%"PRIx32
|
||||
spapr_drc_awaiting_allocation(uint32_t index) "drc: 0x%"PRIx32
|
||||
spapr_drc_reset(uint32_t index) "drc: 0x%"PRIx32
|
||||
spapr_drc_realize(uint32_t index) "drc: 0x%"PRIx32
|
||||
spapr_drc_realize_child(uint32_t index, char *childname) "drc: 0x%"PRIx32", child name: %s"
|
||||
spapr_drc_realize_complete(uint32_t index) "drc: 0x%"PRIx32
|
||||
spapr_drc_unrealize(uint32_t index) "drc: 0x%"PRIx32
|
||||
|
||||
# hw/ppc/spapr_rtas.c
|
||||
spapr_rtas_set_indicator_invalid(uint32_t index) "sensor index: 0x%"PRIx32
|
||||
spapr_rtas_set_indicator_not_supported(uint32_t index, uint32_t type) "sensor index: 0x%"PRIx32", type: %"PRIu32
|
||||
spapr_rtas_get_sensor_state_not_supported(uint32_t index, uint32_t type) "sensor index: 0x%"PRIx32", type: %"PRIu32
|
||||
spapr_rtas_get_sensor_state_invalid(uint32_t index) "sensor index: 0x%"PRIx32
|
||||
spapr_rtas_ibm_configure_connector_invalid(uint32_t index) "DRC index: 0x%"PRIx32
|
||||
spapr_rtas_ibm_configure_connector_missing_fdt(uint32_t index) "DRC index: 0x%"PRIx32
|
||||
|
||||
# hw/ppc/spapr_vio.c
|
||||
spapr_vio_h_reg_crq(uint64_t reg, uint64_t queue_addr, uint64_t queue_len) "CRQ for dev 0x%" PRIx64 " registered at 0x%" PRIx64 "/0x%" PRIx64
|
||||
spapr_vio_free_crq(uint32_t reg) "CRQ for dev 0x%" PRIx32 " freed"
|
||||
|
||||
# hw/ppc/ppc.c
|
||||
ppc_tb_adjust(uint64_t offs1, uint64_t offs2, int64_t diff, int64_t seconds) "adjusted from 0x%"PRIx64" to 0x%"PRIx64", diff %"PRId64" (%"PRId64"s)"
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user