aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--accel.c1
-rw-r--r--aio-posix.c1
-rw-r--r--aio-win32.c1
-rw-r--r--arch_init.c2
-rw-r--r--async.c1
-rw-r--r--backends/baum.c1
-rw-r--r--backends/hostmem-file.c1
-rw-r--r--backends/hostmem-ram.c1
-rw-r--r--backends/hostmem.c1
-rw-r--r--backends/msmouse.c2
-rw-r--r--backends/rng-egd.c1
-rw-r--r--backends/rng-random.c1
-rw-r--r--backends/rng.c1
-rw-r--r--backends/testdev.c1
-rw-r--r--backends/tpm.c1
-rw-r--r--balloon.c1
-rw-r--r--block.c4
-rw-r--r--blockdev-nbd.c1
-rw-r--r--blockdev.c1
-rw-r--r--blockjob.c2
-rw-r--r--bootdevice.c1
-rw-r--r--bsd-user/bsdload.c8
-rw-r--r--bsd-user/elfload.c8
-rw-r--r--bsd-user/main.c8
-rw-r--r--bsd-user/mmap.c7
-rw-r--r--bsd-user/signal.c7
-rw-r--r--bsd-user/strace.c6
-rw-r--r--bsd-user/syscall.c12
-rw-r--r--bsd-user/uaccess.c3
-rw-r--r--bt-host.c2
-rw-r--r--bt-vhci.c1
-rw-r--r--contrib/ivshmem-client/ivshmem-client.c2
-rw-r--r--contrib/ivshmem-client/main.c1
-rw-r--r--contrib/ivshmem-server/ivshmem-server.c2
-rw-r--r--contrib/ivshmem-server/main.c1
-rw-r--r--default-configs/arm-softmmu.mak1
-rw-r--r--device-hotplug.c1
-rw-r--r--device_tree.c7
-rw-r--r--disas.c3
-rw-r--r--disas/hppa.c1
-rw-r--r--disas/i386.c2
-rw-r--r--disas/ia64.c3
-rw-r--r--disas/libvixl/vixl/a64/disasm-a64.cc6
-rw-r--r--disas/m68k.c3
-rw-r--r--disas/s390.c1
-rw-r--r--disas/sparc.c2
-rw-r--r--disas/tci.c1
-rw-r--r--dma-helpers.c1
-rw-r--r--dump.c2
-rw-r--r--fpu/softfloat.c3
-rw-r--r--gdbstub.c9
-rw-r--r--hmp.c1
-rw-r--r--hw/arm/Makefile.objs1
-rw-r--r--hw/arm/bcm2835_peripherals.c204
-rw-r--r--hw/arm/bcm2836.c165
-rw-r--r--hw/arm/boot.c53
-rw-r--r--hw/arm/highbank.c37
-rw-r--r--hw/arm/raspi.c152
-rw-r--r--hw/arm/virt-acpi-build.c28
-rw-r--r--hw/audio/cs4231a.c23
-rw-r--r--hw/audio/gus.c20
-rw-r--r--hw/audio/sb16.c23
-rw-r--r--hw/block/fdc.c81
-rw-r--r--hw/dma/i82374.c58
-rw-r--r--hw/dma/i8257.c395
-rw-r--r--hw/i386/pc.c2
-rw-r--r--hw/intc/Makefile.objs1
-rw-r--r--hw/intc/bcm2835_ic.c236
-rw-r--r--hw/intc/bcm2836_control.c303
-rw-r--r--hw/isa/isa-bus.c21
-rw-r--r--hw/mips/mips_fulong2e.c2
-rw-r--r--hw/mips/mips_jazz.c5
-rw-r--r--hw/mips/mips_malta.c2
-rw-r--r--hw/misc/Makefile.objs2
-rw-r--r--hw/misc/bcm2835_mbox.c333
-rw-r--r--hw/misc/bcm2835_property.c287
-rw-r--r--hw/net/cadence_gem.c12
-rw-r--r--hw/net/e1000.c6
-rw-r--r--hw/sparc/sun4m.c24
-rw-r--r--hw/sparc64/sun4u.c39
-rw-r--r--include/exec/ram_addr.h8
-rw-r--r--include/hw/arm/arm.h5
-rw-r--r--include/hw/arm/bcm2835_peripherals.h42
-rw-r--r--include/hw/arm/bcm2836.h35
-rw-r--r--include/hw/arm/raspi_platform.h128
-rw-r--r--include/hw/arm/virt-acpi-build.h1
-rw-r--r--include/hw/intc/bcm2835_ic.h33
-rw-r--r--include/hw/intc/bcm2836_control.h51
-rw-r--r--include/hw/isa/i8257.h42
-rw-r--r--include/hw/isa/isa.h51
-rw-r--r--include/hw/misc/bcm2835_mbox.h38
-rw-r--r--include/hw/misc/bcm2835_mbox_defs.h27
-rw-r--r--include/hw/misc/bcm2835_property.h31
-rw-r--r--include/migration/migration.h2
-rw-r--r--include/net/filter.h1
-rw-r--r--include/net/net.h2
-rw-r--r--include/qemu/typedefs.h1
-rw-r--r--io/channel-buffer.c1
-rw-r--r--io/channel-command.c1
-rw-r--r--io/channel-file.c1
-rw-r--r--io/channel-socket.c1
-rw-r--r--io/channel-tls.c1
-rw-r--r--io/channel-watch.c1
-rw-r--r--io/channel-websock.c1
-rw-r--r--io/channel.c1
-rw-r--r--io/task.c1
-rw-r--r--iohandler.c2
-rw-r--r--ioport.c1
-rw-r--r--iothread.c1
-rw-r--r--kvm-all.c3
-rw-r--r--kvm-stub.c1
-rw-r--r--main-loop.c1
-rw-r--r--memory.c2
-rw-r--r--memory_mapping.c1
-rw-r--r--migration/exec.c4
-rw-r--r--migration/fd.c4
-rw-r--r--migration/migration.c78
-rw-r--r--migration/postcopy-ram.c6
-rw-r--r--migration/ram.c73
-rw-r--r--migration/rdma.c2
-rw-r--r--migration/savevm.c162
-rw-r--r--migration/tcp.c4
-rw-r--r--migration/unix.c4
-rw-r--r--module-common.c2
-rw-r--r--monitor.c2
-rw-r--r--nbd/client.c1
-rw-r--r--nbd/common.c1
-rw-r--r--nbd/server.c1
-rw-r--r--net/checksum.c1
-rw-r--r--net/dump.c1
-rw-r--r--net/eth.c1
-rw-r--r--net/filter-buffer.c1
-rw-r--r--net/filter.c44
-rw-r--r--net/hub.c1
-rw-r--r--net/l2tpv3.c2
-rw-r--r--net/net.c54
-rw-r--r--net/netmap.c100
-rw-r--r--net/queue.c1
-rw-r--r--net/slirp.c5
-rw-r--r--net/socket.c2
-rw-r--r--net/tap-aix.c2
-rw-r--r--net/tap-bsd.c1
-rw-r--r--net/tap-haiku.c2
-rw-r--r--net/tap-linux.c1
-rw-r--r--net/tap-solaris.c2
-rw-r--r--net/tap-win32.c2
-rw-r--r--net/tap.c3
-rw-r--r--net/util.c3
-rw-r--r--net/vde.c2
-rw-r--r--net/vhost-user.c1
-rw-r--r--numa.c1
-rw-r--r--os-posix.c9
-rw-r--r--os-win32.c7
-rw-r--r--page_cache.c8
-rw-r--r--pc-bios/openbios-ppcbin746588 -> 750684 bytes
-rw-r--r--pc-bios/openbios-sparc32bin381584 -> 381584 bytes
-rw-r--r--pc-bios/openbios-sparc64bin1616864 -> 1592280 bytes
-rw-r--r--qapi/opts-visitor.c1
-rw-r--r--qapi/qapi-dealloc-visitor.c1
-rw-r--r--qapi/qapi-util.c2
-rw-r--r--qapi/qapi-visit-core.c1
-rw-r--r--qapi/qmp-dispatch.c2
-rw-r--r--qapi/qmp-event.c2
-rw-r--r--qapi/qmp-input-visitor.c1
-rw-r--r--qapi/qmp-output-visitor.c1
-rw-r--r--qapi/qmp-registry.c2
-rw-r--r--qapi/string-input-visitor.c1
-rw-r--r--qapi/string-output-visitor.c1
-rw-r--r--qdev-monitor.c1
-rw-r--r--qemu-bridge-helper.c13
-rw-r--r--qemu-char.c8
-rw-r--r--qemu-doc.texi9
-rw-r--r--qemu-nbd.c5
-rw-r--r--qemu-seccomp.c2
-rw-r--r--qemu-timer.c1
-rw-r--r--qga/channel-posix.c7
-rw-r--r--qga/channel-win32.c5
-rw-r--r--qga/commands-posix.c9
-rw-r--r--qga/commands-win32.c3
-rw-r--r--qga/commands.c1
-rw-r--r--qga/guest-agent-command-state.c1
-rw-r--r--qga/main.c5
-rw-r--r--qga/service-win32.c3
-rw-r--r--qga/vss-win32.c2
-rw-r--r--qjson.c2
-rw-r--r--qmp-commands.hx33
-rw-r--r--qmp.c1
-rw-r--r--qobject/json-lexer.c2
-rw-r--r--qobject/json-parser.c2
-rw-r--r--qobject/json-streamer.c1
-rw-r--r--qobject/qbool.c1
-rw-r--r--qobject/qdict.c1
-rw-r--r--qobject/qfloat.c1
-rw-r--r--qobject/qint.c1
-rw-r--r--qobject/qjson.c1
-rw-r--r--qobject/qlist.c1
-rw-r--r--qobject/qnull.c1
-rw-r--r--qobject/qobject.c1
-rw-r--r--qobject/qstring.c1
-rw-r--r--qom/container.c2
-rw-r--r--qom/object.c1
-rw-r--r--qom/object_interfaces.c1
-rw-r--r--qom/qom-qobject.c1
-rw-r--r--qtest.c1
-rw-r--r--replay/replay-events.c1
-rw-r--r--replay/replay-input.c1
-rw-r--r--replay/replay-internal.c1
-rw-r--r--replay/replay-time.c1
-rw-r--r--replay/replay.c1
m---------roms/openbios0
-rwxr-xr-xscripts/vmstate-static-checker.py1
-rw-r--r--slirp/arp_table.c1
-rw-r--r--slirp/bootp.c3
-rw-r--r--slirp/cksum.c1
-rw-r--r--slirp/dnssearch.c4
-rw-r--r--slirp/if.c1
-rw-r--r--slirp/ip_icmp.c24
-rw-r--r--slirp/ip_input.c1
-rw-r--r--slirp/ip_output.c1
-rw-r--r--slirp/mbuf.c3
-rw-r--r--slirp/mbuf.h2
-rw-r--r--slirp/misc.c1
-rw-r--r--slirp/sbuf.c1
-rw-r--r--slirp/slirp.c117
-rw-r--r--slirp/slirp.h2
-rw-r--r--slirp/socket.c159
-rw-r--r--slirp/socket.h51
-rw-r--r--slirp/tcp_input.c31
-rw-r--r--slirp/tcp_output.c1
-rw-r--r--slirp/tcp_subr.c41
-rw-r--r--slirp/tcp_timer.c1
-rw-r--r--slirp/tftp.c7
-rw-r--r--slirp/udp.c75
-rw-r--r--slirp/udp.h5
-rw-r--r--spice-qemu-char.c3
-rw-r--r--stubs/arch-query-cpu-def.c1
-rw-r--r--stubs/bdrv-commit-all.c1
-rw-r--r--stubs/clock-warp.c1
-rw-r--r--stubs/cpu-get-clock.c1
-rw-r--r--stubs/cpu-get-icount.c1
-rw-r--r--stubs/cpus.c1
-rw-r--r--stubs/dump.c1
-rw-r--r--stubs/fd-register.c1
-rw-r--r--stubs/fdset-add-fd.c1
-rw-r--r--stubs/fdset-find-fd.c1
-rw-r--r--stubs/fdset-get-fd.c1
-rw-r--r--stubs/fdset-remove-fd.c1
-rw-r--r--stubs/gdbstub.c1
-rw-r--r--stubs/get-fd.c1
-rw-r--r--stubs/get-next-serial.c1
-rw-r--r--stubs/get-vm-name.c1
-rw-r--r--stubs/iothread-lock.c1
-rw-r--r--stubs/is-daemonized.c1
-rw-r--r--stubs/kvm.c1
-rw-r--r--stubs/machine-init-done.c1
-rw-r--r--stubs/migr-blocker.c1
-rw-r--r--stubs/mon-is-qmp.c1
-rw-r--r--stubs/mon-printf.c1
-rw-r--r--stubs/monitor-init.c1
-rw-r--r--stubs/notify-event.c1
-rw-r--r--stubs/qmp_pc_dimm_device_list.c1
-rw-r--r--stubs/qtest.c1
-rw-r--r--stubs/replay-user.c1
-rw-r--r--stubs/replay.c2
-rw-r--r--stubs/reset.c1
-rw-r--r--stubs/runstate-check.c1
-rw-r--r--stubs/set-fd-handler.c1
-rw-r--r--stubs/slirp.c1
-rw-r--r--stubs/sysbus.c1
-rw-r--r--stubs/target-get-monitor-def.c1
-rw-r--r--stubs/target-monitor-defs.c1
-rw-r--r--stubs/uuid.c1
-rw-r--r--stubs/vhost.c1
-rw-r--r--stubs/vm-stop.c1
-rw-r--r--stubs/vmstate.c1
-rw-r--r--target-arm/cpu.c9
-rw-r--r--target-arm/helper.c94
-rw-r--r--tcg-runtime.c2
-rw-r--r--tci.c2
-rw-r--r--thread-pool.c2
-rw-r--r--thunk.c4
-rw-r--r--tpm.c2
-rw-r--r--trace/control.c1
-rw-r--r--trace/ftrace.c5
-rw-r--r--trace/qmp.c1
-rw-r--r--trace/simple.c6
-rw-r--r--ui/console-gl.c1
-rw-r--r--ui/console.c1
-rw-r--r--ui/curses.c1
-rw-r--r--ui/cursor.c1
-rw-r--r--ui/egl-context.c1
-rw-r--r--ui/egl-helpers.c9
-rw-r--r--ui/gtk-egl.c1
-rw-r--r--ui/gtk-gl-area.c1
-rw-r--r--ui/gtk.c1
-rw-r--r--ui/input-keymap.c1
-rw-r--r--ui/input-legacy.c2
-rw-r--r--ui/input.c1
-rw-r--r--ui/keymaps.c1
-rw-r--r--ui/qemu-pixman.c1
-rw-r--r--ui/sdl.c1
-rw-r--r--ui/sdl2-2d.c1
-rw-r--r--ui/sdl2-gl.c1
-rw-r--r--ui/sdl2-input.c1
-rw-r--r--ui/sdl2.c1
-rw-r--r--ui/sdl_zoom.c4
-rw-r--r--ui/shader.c1
-rw-r--r--ui/spice-core.c1
-rw-r--r--ui/spice-display.c1
-rw-r--r--ui/spice-input.c5
-rw-r--r--ui/vnc-auth-sasl.c1
-rw-r--r--ui/vnc-auth-vencrypt.c1
-rw-r--r--ui/vnc-enc-hextile.c1
-rw-r--r--ui/vnc-enc-tight.c3
-rw-r--r--ui/vnc-enc-zlib.c1
-rw-r--r--ui/vnc-enc-zrle-template.c2
-rw-r--r--ui/vnc-enc-zrle.c1
-rw-r--r--ui/vnc-enc-zywrle-template.c1
-rw-r--r--ui/vnc-jobs.c1
-rw-r--r--ui/vnc-palette.c2
-rw-r--r--ui/vnc-ws.c1
-rw-r--r--ui/vnc.c2
-rw-r--r--ui/x_keymap.c1
-rw-r--r--user-exec.c3
-rw-r--r--util/acl.c1
-rw-r--r--util/base64.c1
-rw-r--r--util/bitmap.c1
-rw-r--r--util/bitops.c1
-rw-r--r--util/buffer.c1
-rw-r--r--util/compatfd.c1
-rw-r--r--util/coroutine-gthread.c1
-rw-r--r--util/coroutine-sigaltstack.c4
-rw-r--r--util/coroutine-ucontext.c3
-rw-r--r--util/coroutine-win32.c1
-rw-r--r--util/crc32c.c1
-rw-r--r--util/cutils.c3
-rw-r--r--util/envlist.c1
-rw-r--r--util/error.c2
-rw-r--r--util/event_notifier-posix.c1
-rw-r--r--util/event_notifier-win32.c1
-rw-r--r--util/fifo8.c1
-rw-r--r--util/getauxval.c2
-rw-r--r--util/hbitmap.c4
-rw-r--r--util/hexdump.c1
-rw-r--r--util/host-utils.c3
-rw-r--r--util/id.c1
-rw-r--r--util/iov.c1
-rw-r--r--util/log.c1
-rw-r--r--util/mmap-alloc.c3
-rw-r--r--util/module.c2
-rw-r--r--util/notify.c1
-rw-r--r--util/osdep.c11
-rw-r--r--util/oslib-posix.c3
-rw-r--r--util/oslib-win32.c3
-rw-r--r--util/path.c7
-rw-r--r--util/qemu-config.c2
-rw-r--r--util/qemu-coroutine-io.c1
-rw-r--r--util/qemu-coroutine-lock.c1
-rw-r--r--util/qemu-coroutine-sleep.c1
-rw-r--r--util/qemu-coroutine.c1
-rw-r--r--util/qemu-error.c2
-rw-r--r--util/qemu-openpty.c2
-rw-r--r--util/qemu-option.c4
-rw-r--r--util/qemu-progress.c3
-rw-r--r--util/qemu-sockets.c7
-rw-r--r--util/qemu-thread-posix.c11
-rw-r--r--util/qemu-thread-win32.c3
-rw-r--r--util/qemu-timer-common.c1
-rw-r--r--util/rcu.c6
-rw-r--r--util/readline.c1
-rw-r--r--util/rfifolock.c2
-rw-r--r--util/throttle.c1
-rw-r--r--util/timed-average.c2
-rw-r--r--util/unicode.c1
-rw-r--r--util/uri.c3
-rw-r--r--vl.c15
376 files changed, 3651 insertions, 1182 deletions
diff --git a/accel.c b/accel.c
index 74e41daaa5..0510b90f67 100644
--- a/accel.c
+++ b/accel.c
@@ -23,6 +23,7 @@
* THE SOFTWARE.
*/
+#include "qemu/osdep.h"
#include "sysemu/accel.h"
#include "hw/boards.h"
#include "qemu-common.h"
diff --git a/aio-posix.c b/aio-posix.c
index 482b316502..fa7f8ab2a5 100644
--- a/aio-posix.c
+++ b/aio-posix.c
@@ -13,6 +13,7 @@
* GNU GPL, version 2 or (at your option) any later version.
*/
+#include "qemu/osdep.h"
#include "qemu-common.h"
#include "block/block.h"
#include "qemu/queue.h"
diff --git a/aio-win32.c b/aio-win32.c
index cdc445608b..6aaa32a147 100644
--- a/aio-win32.c
+++ b/aio-win32.c
@@ -15,6 +15,7 @@
* GNU GPL, version 2 or (at your option) any later version.
*/
+#include "qemu/osdep.h"
#include "qemu-common.h"
#include "block/block.h"
#include "qemu/queue.h"
diff --git a/arch_init.c b/arch_init.c
index d1383b3c43..f6aba02cb2 100644
--- a/arch_init.c
+++ b/arch_init.c
@@ -21,7 +21,7 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
-#include <stdint.h>
+#include "qemu/osdep.h"
#include "sysemu/sysemu.h"
#include "sysemu/arch_init.h"
#include "hw/pci/pci.h"
diff --git a/async.c b/async.c
index e106072a44..d4dd2cc799 100644
--- a/async.c
+++ b/async.c
@@ -22,6 +22,7 @@
* THE SOFTWARE.
*/
+#include "qemu/osdep.h"
#include "qemu-common.h"
#include "block/aio.h"
#include "block/thread-pool.h"
diff --git a/backends/baum.c b/backends/baum.c
index ba32b61002..374562a483 100644
--- a/backends/baum.c
+++ b/backends/baum.c
@@ -21,6 +21,7 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
+#include "qemu/osdep.h"
#include "qemu-common.h"
#include "sysemu/char.h"
#include "qemu/timer.h"
diff --git a/backends/hostmem-file.c b/backends/hostmem-file.c
index e9b6d21dac..fd59482693 100644
--- a/backends/hostmem-file.c
+++ b/backends/hostmem-file.c
@@ -9,6 +9,7 @@
* This work is licensed under the terms of the GNU GPL, version 2 or later.
* See the COPYING file in the top-level directory.
*/
+#include "qemu/osdep.h"
#include "qemu-common.h"
#include "sysemu/hostmem.h"
#include "sysemu/sysemu.h"
diff --git a/backends/hostmem-ram.c b/backends/hostmem-ram.c
index a67a134521..44fb3902b8 100644
--- a/backends/hostmem-ram.c
+++ b/backends/hostmem-ram.c
@@ -9,6 +9,7 @@
* This work is licensed under the terms of the GNU GPL, version 2 or later.
* See the COPYING file in the top-level directory.
*/
+#include "qemu/osdep.h"
#include "sysemu/hostmem.h"
#include "qom/object_interfaces.h"
diff --git a/backends/hostmem.c b/backends/hostmem.c
index 1b4eb45817..60e882c628 100644
--- a/backends/hostmem.c
+++ b/backends/hostmem.c
@@ -9,6 +9,7 @@
* This work is licensed under the terms of the GNU GPL, version 2 or later.
* See the COPYING file in the top-level directory.
*/
+#include "qemu/osdep.h"
#include "sysemu/hostmem.h"
#include "hw/boards.h"
#include "qapi/visitor.h"
diff --git a/backends/msmouse.c b/backends/msmouse.c
index 476dab5634..9a82efda9e 100644
--- a/backends/msmouse.c
+++ b/backends/msmouse.c
@@ -21,7 +21,7 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
-#include <stdlib.h>
+#include "qemu/osdep.h"
#include "qemu-common.h"
#include "sysemu/char.h"
#include "ui/console.h"
diff --git a/backends/rng-egd.c b/backends/rng-egd.c
index 6c13409632..2de5cd5fef 100644
--- a/backends/rng-egd.c
+++ b/backends/rng-egd.c
@@ -10,6 +10,7 @@
* See the COPYING file in the top-level directory.
*/
+#include "qemu/osdep.h"
#include "sysemu/rng.h"
#include "sysemu/char.h"
#include "qapi/qmp/qerror.h"
diff --git a/backends/rng-random.c b/backends/rng-random.c
index 4e51f4609b..8cdad6af7b 100644
--- a/backends/rng-random.c
+++ b/backends/rng-random.c
@@ -10,6 +10,7 @@
* See the COPYING file in the top-level directory.
*/
+#include "qemu/osdep.h"
#include "sysemu/rng-random.h"
#include "sysemu/rng.h"
#include "qapi/qmp/qerror.h"
diff --git a/backends/rng.c b/backends/rng.c
index 5065fdc155..b7820ef471 100644
--- a/backends/rng.c
+++ b/backends/rng.c
@@ -10,6 +10,7 @@
* See the COPYING file in the top-level directory.
*/
+#include "qemu/osdep.h"
#include "sysemu/rng.h"
#include "qapi/qmp/qerror.h"
#include "qom/object_interfaces.h"
diff --git a/backends/testdev.c b/backends/testdev.c
index 26d5c7307a..3ab1c90c1c 100644
--- a/backends/testdev.c
+++ b/backends/testdev.c
@@ -23,6 +23,7 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
+#include "qemu/osdep.h"
#include "qemu-common.h"
#include "sysemu/char.h"
diff --git a/backends/tpm.c b/backends/tpm.c
index a512693b15..d53da18627 100644
--- a/backends/tpm.c
+++ b/backends/tpm.c
@@ -12,6 +12,7 @@
* Based on backends/rng.c by Anthony Liguori
*/
+#include "qemu/osdep.h"
#include "sysemu/tpm_backend.h"
#include "qapi/qmp/qerror.h"
#include "sysemu/tpm.h"
diff --git a/balloon.c b/balloon.c
index 0f45d1b5c4..f2ef50cf77 100644
--- a/balloon.c
+++ b/balloon.c
@@ -24,6 +24,7 @@
* THE SOFTWARE.
*/
+#include "qemu/osdep.h"
#include "qemu-common.h"
#include "exec/cpu-common.h"
#include "sysemu/kvm.h"
diff --git a/block.c b/block.c
index dff3a3a3f9..efc3c43f89 100644
--- a/block.c
+++ b/block.c
@@ -21,7 +21,7 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
-#include "config-host.h"
+#include "qemu/osdep.h"
#include "qemu-common.h"
#include "trace.h"
#include "block/block_int.h"
@@ -42,8 +42,6 @@
#include "block/throttle-groups.h"
#ifdef CONFIG_BSD
-#include <sys/types.h>
-#include <sys/stat.h>
#include <sys/ioctl.h>
#include <sys/queue.h>
#ifndef __DragonFly__
diff --git a/blockdev-nbd.c b/blockdev-nbd.c
index 9d6a21c33d..efc31a462c 100644
--- a/blockdev-nbd.c
+++ b/blockdev-nbd.c
@@ -9,6 +9,7 @@
* later. See the COPYING file in the top-level directory.
*/
+#include "qemu/osdep.h"
#include "sysemu/blockdev.h"
#include "sysemu/block-backend.h"
#include "hw/block/block.h"
diff --git a/blockdev.c b/blockdev.c
index be4ca44ab2..e1b6b0f0e1 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -30,6 +30,7 @@
* THE SOFTWARE.
*/
+#include "qemu/osdep.h"
#include "sysemu/block-backend.h"
#include "sysemu/blockdev.h"
#include "hw/block/block.h"
diff --git a/blockjob.c b/blockjob.c
index a69214254c..a402181835 100644
--- a/blockjob.c
+++ b/blockjob.c
@@ -23,7 +23,7 @@
* THE SOFTWARE.
*/
-#include "config-host.h"
+#include "qemu/osdep.h"
#include "qemu-common.h"
#include "trace.h"
#include "block/block.h"
diff --git a/bootdevice.c b/bootdevice.c
index 3cdc0d7b22..1ee7b117de 100644
--- a/bootdevice.c
+++ b/bootdevice.c
@@ -22,6 +22,7 @@
* THE SOFTWARE.
*/
+#include "qemu/osdep.h"
#include "sysemu/sysemu.h"
#include "qapi/visitor.h"
#include "qemu/error-report.h"
diff --git a/bsd-user/bsdload.c b/bsd-user/bsdload.c
index 2abc7136e0..94eec363b2 100644
--- a/bsd-user/bsdload.c
+++ b/bsd-user/bsdload.c
@@ -1,12 +1,6 @@
/* Code for loading BSD executables. Mostly linux kernel code. */
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <unistd.h>
-#include <stdio.h>
-#include <stdlib.h>
+#include "qemu/osdep.h"
#include "qemu.h"
diff --git a/bsd-user/elfload.c b/bsd-user/elfload.c
index 59a7bdf0cc..0a6092bdf7 100644
--- a/bsd-user/elfload.c
+++ b/bsd-user/elfload.c
@@ -1,13 +1,7 @@
/* This is the Linux kernel elf-loading code, ported into user space */
-#include <stdio.h>
-#include <sys/types.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <unistd.h>
+#include "qemu/osdep.h"
#include <sys/mman.h>
-#include <stdlib.h>
-#include <string.h>
#include "qemu.h"
#include "disas/disas.h"
diff --git a/bsd-user/main.c b/bsd-user/main.c
index fefcfc1ccf..287ec1d369 100644
--- a/bsd-user/main.c
+++ b/bsd-user/main.c
@@ -16,14 +16,8 @@
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdarg.h>
-#include <string.h>
-#include <errno.h>
-#include <unistd.h>
+#include "qemu/osdep.h"
#include <machine/trap.h>
-#include <sys/types.h>
#include <sys/mman.h>
#include "qemu.h"
diff --git a/bsd-user/mmap.c b/bsd-user/mmap.c
index 092bf7f892..6ab5334702 100644
--- a/bsd-user/mmap.c
+++ b/bsd-user/mmap.c
@@ -16,12 +16,7 @@
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdarg.h>
-#include <string.h>
-#include <unistd.h>
-#include <errno.h>
+#include "qemu/osdep.h"
#include <sys/mman.h>
#include "qemu.h"
diff --git a/bsd-user/signal.c b/bsd-user/signal.c
index 4887ecc617..f6f7aa2427 100644
--- a/bsd-user/signal.c
+++ b/bsd-user/signal.c
@@ -16,12 +16,7 @@
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdarg.h>
-#include <unistd.h>
-#include <errno.h>
+#include "qemu/osdep.h"
#include "qemu.h"
#include "target_signal.h"
diff --git a/bsd-user/strace.c b/bsd-user/strace.c
index e33dd4d48f..fa66fe1ee2 100644
--- a/bsd-user/strace.c
+++ b/bsd-user/strace.c
@@ -16,14 +16,10 @@
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
-#include <stdio.h>
-#include <errno.h>
+#include "qemu/osdep.h"
#include <sys/select.h>
-#include <sys/types.h>
-#include <unistd.h>
#include <sys/syscall.h>
#include <sys/ioccom.h>
-#include <ctype.h>
#include "qemu.h"
diff --git a/bsd-user/syscall.c b/bsd-user/syscall.c
index a4d1583fed..35f784cb6c 100644
--- a/bsd-user/syscall.c
+++ b/bsd-user/syscall.c
@@ -16,17 +16,7 @@
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdint.h>
-#include <stdarg.h>
-#include <string.h>
-#include <errno.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <time.h>
-#include <limits.h>
-#include <sys/types.h>
+#include "qemu/osdep.h"
#include <sys/mman.h>
#include <sys/syscall.h>
#include <sys/param.h>
diff --git a/bsd-user/uaccess.c b/bsd-user/uaccess.c
index 677f19c26e..7cb6d17495 100644
--- a/bsd-user/uaccess.c
+++ b/bsd-user/uaccess.c
@@ -1,6 +1,5 @@
/* User memory access */
-#include <stdio.h>
-#include <string.h>
+#include "qemu/osdep.h"
#include "qemu.h"
diff --git a/bt-host.c b/bt-host.c
index 49205bf288..2f8f631c25 100644
--- a/bt-host.c
+++ b/bt-host.c
@@ -17,12 +17,12 @@
* with this program; if not, see <http://www.gnu.org/licenses/>.
*/
+#include "qemu/osdep.h"
#include "qemu-common.h"
#include "sysemu/bt.h"
#include "qemu/main-loop.h"
#ifndef _WIN32
-# include <errno.h>
# include <sys/ioctl.h>
# include <sys/uio.h>
# ifdef CONFIG_BLUEZ
diff --git a/bt-vhci.c b/bt-vhci.c
index e267c8ad15..9d277c32bf 100644
--- a/bt-vhci.c
+++ b/bt-vhci.c
@@ -17,6 +17,7 @@
* with this program; if not, see <http://www.gnu.org/licenses/>.
*/
+#include "qemu/osdep.h"
#include "qemu-common.h"
#include "sysemu/bt.h"
#include "hw/bt.h"
diff --git a/contrib/ivshmem-client/ivshmem-client.c b/contrib/ivshmem-client/ivshmem-client.c
index 31619d80e9..44ae3646e1 100644
--- a/contrib/ivshmem-client/ivshmem-client.c
+++ b/contrib/ivshmem-client/ivshmem-client.c
@@ -6,7 +6,7 @@
* top-level directory.
*/
-#include <sys/types.h>
+#include "qemu/osdep.h"
#include <sys/socket.h>
#include <sys/un.h>
diff --git a/contrib/ivshmem-client/main.c b/contrib/ivshmem-client/main.c
index c004870ae3..33ae1daa15 100644
--- a/contrib/ivshmem-client/main.c
+++ b/contrib/ivshmem-client/main.c
@@ -6,6 +6,7 @@
* top-level directory.
*/
+#include "qemu/osdep.h"
#include "qemu-common.h"
#include "ivshmem-client.h"
diff --git a/contrib/ivshmem-server/ivshmem-server.c b/contrib/ivshmem-server/ivshmem-server.c
index d9e26b0574..bfd0fad49a 100644
--- a/contrib/ivshmem-server/ivshmem-server.c
+++ b/contrib/ivshmem-server/ivshmem-server.c
@@ -5,11 +5,11 @@
* (at your option) any later version. See the COPYING file in the
* top-level directory.
*/
+#include "qemu/osdep.h"
#include "qemu-common.h"
#include "qemu/sockets.h"
#include <sys/mman.h>
-#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#ifdef CONFIG_LINUX
diff --git a/contrib/ivshmem-server/main.c b/contrib/ivshmem-server/main.c
index 9b0d6e2319..cca1061f0e 100644
--- a/contrib/ivshmem-server/main.c
+++ b/contrib/ivshmem-server/main.c
@@ -6,6 +6,7 @@
* top-level directory.
*/
+#include "qemu/osdep.h"
#include "qemu-common.h"
#include "ivshmem-server.h"
diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
index d9b90a50d6..a9f82a1032 100644
--- a/default-configs/arm-softmmu.mak
+++ b/default-configs/arm-softmmu.mak
@@ -79,6 +79,7 @@ CONFIG_TUSB6010=y
CONFIG_IMX=y
CONFIG_MAINSTONE=y
CONFIG_NSERIES=y
+CONFIG_RASPI=y
CONFIG_REALVIEW=y
CONFIG_ZAURUS=y
CONFIG_ZYNQ=y
diff --git a/device-hotplug.c b/device-hotplug.c
index 68b94967c5..9a7cd669d5 100644
--- a/device-hotplug.c
+++ b/device-hotplug.c
@@ -22,6 +22,7 @@
* THE SOFTWARE.
*/
+#include "qemu/osdep.h"
#include "hw/hw.h"
#include "hw/boards.h"
#include "sysemu/block-backend.h"
diff --git a/device_tree.c b/device_tree.c
index a9f5f8e598..b1ad836073 100644
--- a/device_tree.c
+++ b/device_tree.c
@@ -11,12 +11,7 @@
*
*/
-#include <stdio.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <stdlib.h>
+#include "qemu/osdep.h"
#include "qemu-common.h"
#include "qemu/error-report.h"
diff --git a/disas.c b/disas.c
index 4e119449e8..05a7a1260a 100644
--- a/disas.c
+++ b/disas.c
@@ -1,9 +1,8 @@
/* General "disassemble this chunk" code. Used for debugging. */
-#include "config.h"
+#include "qemu/osdep.h"
#include "qemu-common.h"
#include "disas/bfd.h"
#include "elf.h"
-#include <errno.h>
#include "cpu.h"
#include "disas/disas.h"
diff --git a/disas/hppa.c b/disas/hppa.c
index c7c8be66a2..43facdc47b 100644
--- a/disas/hppa.c
+++ b/disas/hppa.c
@@ -18,6 +18,7 @@
You should have received a copy of the GNU General Public License
along with this program; if not, see <http://www.gnu.org/licenses/>. */
+#include "qemu/osdep.h"
#include "disas/bfd.h"
/* HP PA-RISC SOM object file format: definitions internal to BFD.
diff --git a/disas/i386.c b/disas/i386.c
index c63d4a06e4..d40b72ab10 100644
--- a/disas/i386.c
+++ b/disas/i386.c
@@ -31,7 +31,7 @@
and the small letter tells about the operand size. Refer to
the Intel manual for details. */
-#include <stdlib.h>
+#include "qemu/osdep.h"
#include "disas/bfd.h"
/* include/opcode/i386.h r1.78 */
diff --git a/disas/ia64.c b/disas/ia64.c
index d7c7bdfc51..140754c944 100644
--- a/disas/ia64.c
+++ b/disas/ia64.c
@@ -18,7 +18,7 @@
along with this file; see the file COPYING. If not, see
<http://www.gnu.org/licenses/>. */
-#include <string.h>
+#include "qemu/osdep.h"
#include "disas/bfd.h"
@@ -27,7 +27,6 @@
Free Software Foundation, Inc.
Contributed by David Mosberger-Tang <davidm@hpl.hp.com> */
-#include <sys/types.h>
typedef uint64_t ia64_insn;
diff --git a/disas/libvixl/vixl/a64/disasm-a64.cc b/disas/libvixl/vixl/a64/disasm-a64.cc
index 20caba4317..7a58a5c087 100644
--- a/disas/libvixl/vixl/a64/disasm-a64.cc
+++ b/disas/libvixl/vixl/a64/disasm-a64.cc
@@ -2688,8 +2688,12 @@ void Disassembler::AppendRegisterNameToOutput(const Instruction* instr,
void Disassembler::AppendPCRelativeOffsetToOutput(const Instruction* instr,
int64_t offset) {
USE(instr);
+ uint64_t abs_offset = offset;
char sign = (offset < 0) ? '-' : '+';
- AppendToOutput("#%c0x%" PRIx64, sign, std::abs(offset));
+ if (offset < 0) {
+ abs_offset = -abs_offset;
+ }
+ AppendToOutput("#%c0x%" PRIx64, sign, abs_offset);
}
diff --git a/disas/m68k.c b/disas/m68k.c
index cc0db96cae..0412ecd4b6 100644
--- a/disas/m68k.c
+++ b/disas/m68k.c
@@ -1,9 +1,8 @@
/* This file is composed of several different files from the upstream
sourceware.org CVS. Original file boundaries marked with **** */
-#include <string.h>
+#include "qemu/osdep.h"
#include <math.h>
-#include <stdio.h>
#include "disas/bfd.h"
diff --git a/disas/s390.c b/disas/s390.c
index c29bc4e697..1f167d2eaa 100644
--- a/disas/s390.c
+++ b/disas/s390.c
@@ -20,6 +20,7 @@
Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
02110-1301, USA. */
+#include "qemu/osdep.h"
#include "qemu-common.h"
#include "disas/bfd.h"
diff --git a/disas/sparc.c b/disas/sparc.c
index 59a1e36cf7..64bba8df27 100644
--- a/disas/sparc.c
+++ b/disas/sparc.c
@@ -26,7 +26,7 @@
along with GAS or GDB; see the file COPYING. If not,
see <http://www.gnu.org/licenses/>. */
-#include <stdlib.h>
+#include "qemu/osdep.h"
#include "disas/bfd.h"
/* The SPARC opcode table (and other related data) is defined in
diff --git a/disas/tci.c b/disas/tci.c
index d7b954e62f..1cdf5eeafc 100644
--- a/disas/tci.c
+++ b/disas/tci.c
@@ -17,6 +17,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+#include "qemu/osdep.h"
#include "qemu-common.h"
#include "disas/bfd.h"
#include "tcg/tcg.h"
diff --git a/dma-helpers.c b/dma-helpers.c
index 4faec5d0ca..4ad0bca67e 100644
--- a/dma-helpers.c
+++ b/dma-helpers.c
@@ -7,6 +7,7 @@
* (GNU GPL), version 2 or later.
*/
+#include "qemu/osdep.h"
#include "sysemu/block-backend.h"
#include "sysemu/dma.h"
#include "trace.h"
diff --git a/dump.c b/dump.c
index 2d4892bec2..96e1fc15de 100644
--- a/dump.c
+++ b/dump.c
@@ -11,6 +11,7 @@
*
*/
+#include "qemu/osdep.h"
#include "qemu-common.h"
#include "elf.h"
#include "cpu.h"
@@ -22,7 +23,6 @@
#include "sysemu/sysemu.h"
#include "sysemu/memory_mapping.h"
#include "sysemu/cpus.h"
-#include "qapi/error.h"
#include "qapi/qmp/qerror.h"
#include "qmp-commands.h"
diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index 162c21122c..cfa9787d8d 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -82,12 +82,11 @@ this code that are retained.
/* softfloat (and in particular the code in softfloat-specialize.h) is
* target-dependent and needs the TARGET_* macros.
*/
-#include "config.h"
+#include "qemu/osdep.h"
#include "fpu/softfloat.h"
/* We only need stdlib for abort() */
-#include <stdlib.h>
/*----------------------------------------------------------------------------
| Primitive arithmetic functions, including multi-word arithmetic, and
diff --git a/gdbstub.c b/gdbstub.c
index 59d16506c5..61c12b168e 100644
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -16,16 +16,9 @@
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
-#include "config.h"
+#include "qemu/osdep.h"
#include "qemu-common.h"
#ifdef CONFIG_USER_ONLY
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdarg.h>
-#include <string.h>
-#include <errno.h>
-#include <unistd.h>
-#include <fcntl.h>
#include "qemu.h"
#else
diff --git a/hmp.c b/hmp.c
index 9c571f50a8..cb03a156d2 100644
--- a/hmp.c
+++ b/hmp.c
@@ -13,6 +13,7 @@
* GNU GPL, version 2 or (at your option) any later version.
*/
+#include "qemu/osdep.h"
#include "hmp.h"
#include "net/net.h"
#include "net/eth.h"
diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs
index 2195b60fac..a711e4df61 100644
--- a/hw/arm/Makefile.objs
+++ b/hw/arm/Makefile.objs
@@ -11,6 +11,7 @@ obj-y += armv7m.o exynos4210.o pxa2xx.o pxa2xx_gpio.o pxa2xx_pic.o
obj-$(CONFIG_DIGIC) += digic.o
obj-y += omap1.o omap2.o strongarm.o
obj-$(CONFIG_ALLWINNER_A10) += allwinner-a10.o cubieboard.o
+obj-$(CONFIG_RASPI) += bcm2835_peripherals.o bcm2836.o raspi.o
obj-$(CONFIG_STM32F205_SOC) += stm32f205_soc.o
obj-$(CONFIG_XLNX_ZYNQMP) += xlnx-zynqmp.o xlnx-ep108.o
obj-$(CONFIG_FSL_IMX25) += fsl-imx25.o imx25_pdk.o
diff --git a/hw/arm/bcm2835_peripherals.c b/hw/arm/bcm2835_peripherals.c
new file mode 100644
index 0000000000..18b72ecb69
--- /dev/null
+++ b/hw/arm/bcm2835_peripherals.c
@@ -0,0 +1,204 @@
+/*
+ * Raspberry Pi emulation (c) 2012 Gregory Estrade
+ * Upstreaming code cleanup [including bcm2835_*] (c) 2013 Jan Petrous
+ *
+ * Rasperry Pi 2 emulation and refactoring Copyright (c) 2015, Microsoft
+ * Written by Andrew Baumann
+ *
+ * This code is licensed under the GNU GPLv2 and later.
+ */
+
+#include "hw/arm/bcm2835_peripherals.h"
+#include "hw/misc/bcm2835_mbox_defs.h"
+#include "hw/arm/raspi_platform.h"
+
+/* Peripheral base address on the VC (GPU) system bus */
+#define BCM2835_VC_PERI_BASE 0x7e000000
+
+/* Capabilities for SD controller: no DMA, high-speed, default clocks etc. */
+#define BCM2835_SDHC_CAPAREG 0x52034b4
+
+static void bcm2835_peripherals_init(Object *obj)
+{
+ BCM2835PeripheralState *s = BCM2835_PERIPHERALS(obj);
+
+ /* Memory region for peripheral devices, which we export to our parent */
+ memory_region_init(&s->peri_mr, obj,"bcm2835-peripherals", 0x1000000);
+ object_property_add_child(obj, "peripheral-io", OBJECT(&s->peri_mr), NULL);
+ sysbus_init_mmio(SYS_BUS_DEVICE(s), &s->peri_mr);
+
+ /* Internal memory region for peripheral bus addresses (not exported) */
+ memory_region_init(&s->gpu_bus_mr, obj, "bcm2835-gpu", (uint64_t)1 << 32);
+ object_property_add_child(obj, "gpu-bus", OBJECT(&s->gpu_bus_mr), NULL);
+
+ /* Internal memory region for request/response communication with
+ * mailbox-addressable peripherals (not exported)
+ */
+ memory_region_init(&s->mbox_mr, obj, "bcm2835-mbox",
+ MBOX_CHAN_COUNT << MBOX_AS_CHAN_SHIFT);
+
+ /* Interrupt Controller */
+ object_initialize(&s->ic, sizeof(s->ic), TYPE_BCM2835_IC);
+ object_property_add_child(obj, "ic", OBJECT(&s->ic), NULL);
+ qdev_set_parent_bus(DEVICE(&s->ic), sysbus_get_default());
+
+ /* UART0 */
+ s->uart0 = SYS_BUS_DEVICE(object_new("pl011"));
+ object_property_add_child(obj, "uart0", OBJECT(s->uart0), NULL);
+ qdev_set_parent_bus(DEVICE(s->uart0), sysbus_get_default());
+
+ /* Mailboxes */
+ object_initialize(&s->mboxes, sizeof(s->mboxes), TYPE_BCM2835_MBOX);
+ object_property_add_child(obj, "mbox", OBJECT(&s->mboxes), NULL);
+ qdev_set_parent_bus(DEVICE(&s->mboxes), sysbus_get_default());
+
+ object_property_add_const_link(OBJECT(&s->mboxes), "mbox-mr",
+ OBJECT(&s->mbox_mr), &error_abort);
+
+ /* Property channel */
+ object_initialize(&s->property, sizeof(s->property), TYPE_BCM2835_PROPERTY);
+ object_property_add_child(obj, "property", OBJECT(&s->property), NULL);
+ qdev_set_parent_bus(DEVICE(&s->property), sysbus_get_default());
+
+ object_property_add_const_link(OBJECT(&s->property), "dma-mr",
+ OBJECT(&s->gpu_bus_mr), &error_abort);
+
+ /* Extended Mass Media Controller */
+ object_initialize(&s->sdhci, sizeof(s->sdhci), TYPE_SYSBUS_SDHCI);
+ object_property_add_child(obj, "sdhci", OBJECT(&s->sdhci), NULL);
+ qdev_set_parent_bus(DEVICE(&s->sdhci), sysbus_get_default());
+}
+
+static void bcm2835_peripherals_realize(DeviceState *dev, Error **errp)
+{
+ BCM2835PeripheralState *s = BCM2835_PERIPHERALS(dev);
+ Object *obj;
+ MemoryRegion *ram;
+ Error *err = NULL;
+ uint32_t ram_size;
+ int n;
+
+ obj = object_property_get_link(OBJECT(dev), "ram", &err);
+ if (obj == NULL) {
+ error_setg(errp, "%s: required ram link not found: %s",
+ __func__, error_get_pretty(err));
+ return;
+ }
+
+ ram = MEMORY_REGION(obj);
+ ram_size = memory_region_size(ram);
+
+ /* Map peripherals and RAM into the GPU address space. */
+ memory_region_init_alias(&s->peri_mr_alias, OBJECT(s),
+ "bcm2835-peripherals", &s->peri_mr, 0,
+ memory_region_size(&s->peri_mr));
+
+ memory_region_add_subregion_overlap(&s->gpu_bus_mr, BCM2835_VC_PERI_BASE,
+ &s->peri_mr_alias, 1);
+
+ /* RAM is aliased four times (different cache configurations) on the GPU */
+ for (n = 0; n < 4; n++) {
+ memory_region_init_alias(&s->ram_alias[n], OBJECT(s),
+ "bcm2835-gpu-ram-alias[*]", ram, 0, ram_size);
+ memory_region_add_subregion_overlap(&s->gpu_bus_mr, (hwaddr)n << 30,
+ &s->ram_alias[n], 0);
+ }
+
+ /* Interrupt Controller */
+ object_property_set_bool(OBJECT(&s->ic), true, "realized", &err);
+ if (err) {
+ error_propagate(errp, err);
+ return;
+ }
+
+ memory_region_add_subregion(&s->peri_mr, ARMCTRL_IC_OFFSET,
+ sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->ic), 0));
+ sysbus_pass_irq(SYS_BUS_DEVICE(s), SYS_BUS_DEVICE(&s->ic));
+
+ /* UART0 */
+ object_property_set_bool(OBJECT(s->uart0), true, "realized", &err);
+ if (err) {
+ error_propagate(errp, err);
+ return;
+ }
+
+ memory_region_add_subregion(&s->peri_mr, UART0_OFFSET,
+ sysbus_mmio_get_region(s->uart0, 0));
+ sysbus_connect_irq(s->uart0, 0,
+ qdev_get_gpio_in_named(DEVICE(&s->ic), BCM2835_IC_GPU_IRQ,
+ INTERRUPT_UART));
+
+ /* Mailboxes */
+ object_property_set_bool(OBJECT(&s->mboxes), true, "realized", &err);
+ if (err) {
+ error_propagate(errp, err);
+ return;
+ }
+
+ memory_region_add_subregion(&s->peri_mr, ARMCTRL_0_SBM_OFFSET,
+ sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->mboxes), 0));
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->mboxes), 0,
+ qdev_get_gpio_in_named(DEVICE(&s->ic), BCM2835_IC_ARM_IRQ,
+ INTERRUPT_ARM_MAILBOX));
+
+ /* Property channel */
+ object_property_set_int(OBJECT(&s->property), ram_size, "ram-size", &err);
+ if (err) {
+ error_propagate(errp, err);
+ return;
+ }
+
+ object_property_set_bool(OBJECT(&s->property), true, "realized", &err);
+ if (err) {
+ error_propagate(errp, err);
+ return;
+ }
+
+ memory_region_add_subregion(&s->mbox_mr,
+ MBOX_CHAN_PROPERTY << MBOX_AS_CHAN_SHIFT,
+ sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->property), 0));
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->property), 0,
+ qdev_get_gpio_in(DEVICE(&s->mboxes), MBOX_CHAN_PROPERTY));
+
+ /* Extended Mass Media Controller */
+ object_property_set_int(OBJECT(&s->sdhci), BCM2835_SDHC_CAPAREG, "capareg",
+ &err);
+ if (err) {
+ error_propagate(errp, err);
+ return;
+ }
+
+ object_property_set_bool(OBJECT(&s->sdhci), true, "realized", &err);
+ if (err) {
+ error_propagate(errp, err);
+ return;
+ }
+
+ memory_region_add_subregion(&s->peri_mr, EMMC_OFFSET,
+ sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->sdhci), 0));
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->sdhci), 0,
+ qdev_get_gpio_in_named(DEVICE(&s->ic), BCM2835_IC_GPU_IRQ,
+ INTERRUPT_ARASANSDIO));
+}
+
+static void bcm2835_peripherals_class_init(ObjectClass *oc, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(oc);
+
+ dc->realize = bcm2835_peripherals_realize;
+}
+
+static const TypeInfo bcm2835_peripherals_type_info = {
+ .name = TYPE_BCM2835_PERIPHERALS,
+ .parent = TYPE_SYS_BUS_DEVICE,
+ .instance_size = sizeof(BCM2835PeripheralState),
+ .instance_init = bcm2835_peripherals_init,
+ .class_init = bcm2835_peripherals_class_init,
+};
+
+static void bcm2835_peripherals_register_types(void)
+{
+ type_register_static(&bcm2835_peripherals_type_info);
+}
+
+type_init(bcm2835_peripherals_register_types)
diff --git a/hw/arm/bcm2836.c b/hw/arm/bcm2836.c
new file mode 100644
index 0000000000..69c7438317
--- /dev/null
+++ b/hw/arm/bcm2836.c
@@ -0,0 +1,165 @@
+/*
+ * Raspberry Pi emulation (c) 2012 Gregory Estrade
+ * Upstreaming code cleanup [including bcm2835_*] (c) 2013 Jan Petrous
+ *
+ * Rasperry Pi 2 emulation and refactoring Copyright (c) 2015, Microsoft
+ * Written by Andrew Baumann
+ *
+ * This code is licensed under the GNU GPLv2 and later.
+ */
+
+#include "hw/arm/bcm2836.h"
+#include "hw/arm/raspi_platform.h"
+#include "hw/sysbus.h"
+#include "exec/address-spaces.h"
+
+/* Peripheral base address seen by the CPU */
+#define BCM2836_PERI_BASE 0x3F000000
+
+/* "QA7" (Pi2) interrupt controller and mailboxes etc. */
+#define BCM2836_CONTROL_BASE 0x40000000
+
+static void bcm2836_init(Object *obj)
+{
+ BCM2836State *s = BCM2836(obj);
+ int n;
+
+ for (n = 0; n < BCM2836_NCPUS; n++) {
+ object_initialize(&s->cpus[n], sizeof(s->cpus[n]),
+ "cortex-a15-" TYPE_ARM_CPU);
+ object_property_add_child(obj, "cpu[*]", OBJECT(&s->cpus[n]),
+ &error_abort);
+ }
+
+ object_initialize(&s->control, sizeof(s->control), TYPE_BCM2836_CONTROL);
+ object_property_add_child(obj, "control", OBJECT(&s->control), NULL);
+ qdev_set_parent_bus(DEVICE(&s->control), sysbus_get_default());
+
+ object_initialize(&s->peripherals, sizeof(s->peripherals),
+ TYPE_BCM2835_PERIPHERALS);
+ object_property_add_child(obj, "peripherals", OBJECT(&s->peripherals),
+ &error_abort);
+ qdev_set_parent_bus(DEVICE(&s->peripherals), sysbus_get_default());
+}
+
+static void bcm2836_realize(DeviceState *dev, Error **errp)
+{
+ BCM2836State *s = BCM2836(dev);
+ Object *obj;
+ Error *err = NULL;
+ int n;
+
+ /* common peripherals from bcm2835 */
+
+ obj = object_property_get_link(OBJECT(dev), "ram", &err);
+ if (obj == NULL) {
+ error_setg(errp, "%s: required ram link not found: %s",
+ __func__, error_get_pretty(err));
+ return;
+ }
+
+ object_property_add_const_link(OBJECT(&s->peripherals), "ram", obj, &err);
+ if (err) {
+ error_propagate(errp, err);
+ return;
+ }
+
+ object_property_set_bool(OBJECT(&s->peripherals), true, "realized", &err);
+ if (err) {
+ error_propagate(errp, err);
+ return;
+ }
+
+ sysbus_mmio_map_overlap(SYS_BUS_DEVICE(&s->peripherals), 0,
+ BCM2836_PERI_BASE, 1);
+
+ /* bcm2836 interrupt controller (and mailboxes, etc.) */
+ object_property_set_bool(OBJECT(&s->control), true, "realized", &err);
+ if (err) {
+ error_propagate(errp, err);
+ return;
+ }
+
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->control), 0, BCM2836_CONTROL_BASE);
+
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->peripherals), 0,
+ qdev_get_gpio_in_named(DEVICE(&s->control), "gpu-irq", 0));
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->peripherals), 1,
+ qdev_get_gpio_in_named(DEVICE(&s->control), "gpu-fiq", 0));
+
+ for (n = 0; n < BCM2836_NCPUS; n++) {
+ /* Mirror bcm2836, which has clusterid set to 0xf
+ * TODO: this should be converted to a property of ARM_CPU
+ */
+ s->cpus[n].mp_affinity = 0xF00 | n;
+
+ /* set periphbase/CBAR value for CPU-local registers */
+ object_property_set_int(OBJECT(&s->cpus[n]),
+ BCM2836_PERI_BASE + MCORE_OFFSET,
+ "reset-cbar", &err);
+ if (err) {
+ error_propagate(errp, err);
+ return;
+ }
+
+ /* start powered off if not enabled */
+ object_property_set_bool(OBJECT(&s->cpus[n]), n >= s->enabled_cpus,
+ "start-powered-off", &err);
+ if (err) {
+ error_propagate(errp, err);
+ return;
+ }
+
+ object_property_set_bool(OBJECT(&s->cpus[n]), true, "realized", &err);
+ if (err) {
+ error_propagate(errp, err);
+ return;
+ }
+
+ /* Connect irq/fiq outputs from the interrupt controller. */
+ qdev_connect_gpio_out_named(DEVICE(&s->control), "irq", n,
+ qdev_get_gpio_in(DEVICE(&s->cpus[n]), ARM_CPU_IRQ));
+ qdev_connect_gpio_out_named(DEVICE(&s->control), "fiq", n,
+ qdev_get_gpio_in(DEVICE(&s->cpus[n]), ARM_CPU_FIQ));
+
+ /* Connect timers from the CPU to the interrupt controller */
+ qdev_connect_gpio_out(DEVICE(&s->cpus[n]), GTIMER_PHYS,
+ qdev_get_gpio_in_named(DEVICE(&s->control), "cntpsirq", n));
+ qdev_connect_gpio_out(DEVICE(&s->cpus[n]), GTIMER_VIRT,
+ qdev_get_gpio_in_named(DEVICE(&s->control), "cntvirq", n));
+ }
+}
+
+static Property bcm2836_props[] = {
+ DEFINE_PROP_UINT32("enabled-cpus", BCM2836State, enabled_cpus, BCM2836_NCPUS),
+ DEFINE_PROP_END_OF_LIST()
+};
+
+static void bcm2836_class_init(ObjectClass *oc, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(oc);
+
+ dc->props = bcm2836_props;
+ dc->realize = bcm2836_realize;
+
+ /*
+ * Reason: creates an ARM CPU, thus use after free(), see
+ * arm_cpu_class_init()
+ */
+ dc->cannot_destroy_with_object_finalize_yet = true;
+}
+
+static const TypeInfo bcm2836_type_info = {
+ .name = TYPE_BCM2836,
+ .parent = TYPE_SYS_BUS_DEVICE,
+ .instance_size = sizeof(BCM2836State),
+ .instance_init = bcm2836_init,
+ .class_init = bcm2836_class_init,
+};
+
+static void bcm2836_register_types(void)
+{
+ type_register_static(&bcm2836_type_info);
+}
+
+type_init(bcm2836_register_types)
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
index 7742dd3cb6..cce8c7cd1c 100644
--- a/hw/arm/boot.c
+++ b/hw/arm/boot.c
@@ -178,6 +178,57 @@ static void default_write_secondary(ARMCPU *cpu,
smpboot, fixupcontext);
}
+void arm_write_secure_board_setup_dummy_smc(ARMCPU *cpu,
+ const struct arm_boot_info *info,
+ hwaddr mvbar_addr)
+{
+ int n;
+ uint32_t mvbar_blob[] = {
+ /* mvbar_addr: secure monitor vectors
+ * Default unimplemented and unused vectors to spin. Makes it
+ * easier to debug (as opposed to the CPU running away).
+ */
+ 0xeafffffe, /* (spin) */
+ 0xeafffffe, /* (spin) */
+ 0xe1b0f00e, /* movs pc, lr ;SMC exception return */
+ 0xeafffffe, /* (spin) */
+ 0xeafffffe, /* (spin) */
+ 0xeafffffe, /* (spin) */
+ 0xeafffffe, /* (spin) */
+ 0xeafffffe, /* (spin) */
+ };
+ uint32_t board_setup_blob[] = {
+ /* board setup addr */
+ 0xe3a00e00 + (mvbar_addr >> 4), /* mov r0, #mvbar_addr */
+ 0xee0c0f30, /* mcr p15, 0, r0, c12, c0, 1 ;set MVBAR */
+ 0xee110f11, /* mrc p15, 0, r0, c1 , c1, 0 ;read SCR */
+ 0xe3800031, /* orr r0, #0x31 ;enable AW, FW, NS */
+ 0xee010f11, /* mcr p15, 0, r0, c1, c1, 0 ;write SCR */
+ 0xe1a0100e, /* mov r1, lr ;save LR across SMC */
+ 0xe1600070, /* smc #0 ;call monitor to flush SCR */
+ 0xe1a0f001, /* mov pc, r1 ;return */
+ };
+
+ /* check that mvbar_addr is correctly aligned and relocatable (using MOV) */
+ assert((mvbar_addr & 0x1f) == 0 && (mvbar_addr >> 4) < 0x100);
+
+ /* check that these blobs don't overlap */
+ assert((mvbar_addr + sizeof(mvbar_blob) <= info->board_setup_addr)
+ || (info->board_setup_addr + sizeof(board_setup_blob) <= mvbar_addr));
+
+ for (n = 0; n < ARRAY_SIZE(mvbar_blob); n++) {
+ mvbar_blob[n] = tswap32(mvbar_blob[n]);
+ }
+ rom_add_blob_fixed("board-setup-mvbar", mvbar_blob, sizeof(mvbar_blob),
+ mvbar_addr);
+
+ for (n = 0; n < ARRAY_SIZE(board_setup_blob); n++) {
+ board_setup_blob[n] = tswap32(board_setup_blob[n]);
+ }
+ rom_add_blob_fixed("board-setup", board_setup_blob,
+ sizeof(board_setup_blob), info->board_setup_addr);
+}
+
static void default_reset_secondary(ARMCPU *cpu,
const struct arm_boot_info *info)
{
@@ -488,7 +539,9 @@ static void do_cpu_reset(void *opaque)
* adjust.
*/
if (env->aarch64) {
+ env->cp15.scr_el3 |= SCR_RW;
if (arm_feature(env, ARM_FEATURE_EL2)) {
+ env->cp15.hcr_el2 |= HCR_RW;
env->pstate = PSTATE_MODE_EL2h;
} else {
env->pstate = PSTATE_MODE_EL1h;
diff --git a/hw/arm/highbank.c b/hw/arm/highbank.c
index 620b52631a..e25cf5e3f3 100644
--- a/hw/arm/highbank.c
+++ b/hw/arm/highbank.c
@@ -35,49 +35,16 @@
#define MPCORE_PERIPHBASE 0xfff10000
#define MVBAR_ADDR 0x200
+#define BOARD_SETUP_ADDR (MVBAR_ADDR + 8 * sizeof(uint32_t))
#define NIRQ_GIC 160
/* Board init. */
-/* MVBAR_ADDR is limited by precision of movw */
-
-QEMU_BUILD_BUG_ON(MVBAR_ADDR >= (1 << 16));
-
-#define ARMV7_IMM16(x) (extract32((x), 0, 12) | \
- extract32((x), 12, 4) << 16)
-
static void hb_write_board_setup(ARMCPU *cpu,
const struct arm_boot_info *info)
{
- int n;
- uint32_t board_setup_blob[] = {
- /* MVBAR_ADDR */
- /* Default unimplemented and unused vectors to spin. Makes it
- * easier to debug (as opposed to the CPU running away).
- */
- 0xeafffffe, /* notused1: b notused */
- 0xeafffffe, /* notused2: b notused */
- 0xe1b0f00e, /* smc: movs pc, lr - exception return */
- 0xeafffffe, /* prefetch_abort: b prefetch_abort */
- 0xeafffffe, /* data_abort: b data_abort */
- 0xeafffffe, /* notused3: b notused3 */
- 0xeafffffe, /* irq: b irq */
- 0xeafffffe, /* fiq: b fiq */
-#define BOARD_SETUP_ADDR (MVBAR_ADDR + 8 * sizeof(uint32_t))
- 0xe3000000 + ARMV7_IMM16(MVBAR_ADDR), /* movw r0, MVBAR_ADDR */
- 0xee0c0f30, /* mcr p15, 0, r0, c12, c0, 1 - set MVBAR */
- 0xee110f11, /* mrc p15, 0, r0, c1 , c1, 0 - get SCR */
- 0xe3810001, /* orr r0, #1 - set NS */
- 0xee010f11, /* mcr p15, 0, r0, c1 , c1, 0 - set SCR */
- 0xe1600070, /* smc - go to monitor mode to flush NS change */
- 0xe12fff1e, /* bx lr - return to caller */
- };
- for (n = 0; n < ARRAY_SIZE(board_setup_blob); n++) {
- board_setup_blob[n] = tswap32(board_setup_blob[n]);
- }
- rom_add_blob_fixed("board-setup", board_setup_blob,
- sizeof(board_setup_blob), MVBAR_ADDR);
+ arm_write_secure_board_setup_dummy_smc(cpu, info, MVBAR_ADDR);
}
static void hb_write_secondary(ARMCPU *cpu, const struct arm_boot_info *info)
diff --git a/hw/arm/raspi.c b/hw/arm/raspi.c
new file mode 100644
index 0000000000..0c9427c40e
--- /dev/null
+++ b/hw/arm/raspi.c
@@ -0,0 +1,152 @@
+/*
+ * Raspberry Pi emulation (c) 2012 Gregory Estrade
+ * Upstreaming code cleanup [including bcm2835_*] (c) 2013 Jan Petrous
+ *
+ * Rasperry Pi 2 emulation Copyright (c) 2015, Microsoft
+ * Written by Andrew Baumann
+ *
+ * This code is licensed under the GNU GPLv2 and later.
+ */
+
+#include "hw/arm/bcm2836.h"
+#include "qemu/error-report.h"
+#include "hw/boards.h"
+#include "hw/loader.h"
+#include "hw/arm/arm.h"
+#include "sysemu/sysemu.h"
+
+#define SMPBOOT_ADDR 0x300 /* this should leave enough space for ATAGS */
+#define MVBAR_ADDR 0x400 /* secure vectors */
+#define BOARDSETUP_ADDR (MVBAR_ADDR + 0x20) /* board setup code */
+#define FIRMWARE_ADDR 0x8000 /* Pi loads kernel.img here by default */
+
+/* Table of Linux board IDs for different Pi versions */
+static const int raspi_boardid[] = {[1] = 0xc42, [2] = 0xc43};
+
+typedef struct RasPiState {
+ BCM2836State soc;
+ MemoryRegion ram;
+} RasPiState;
+
+static void write_smpboot(ARMCPU *cpu, const struct arm_boot_info *info)
+{
+ static const uint32_t smpboot[] = {
+ 0xe1a0e00f, /* mov lr, pc */
+ 0xe3a0fe00 + (BOARDSETUP_ADDR >> 4), /* mov pc, BOARDSETUP_ADDR */
+ 0xee100fb0, /* mrc p15, 0, r0, c0, c0, 5;get core ID */
+ 0xe7e10050, /* ubfx r0, r0, #0, #2 ;extract LSB */
+ 0xe59f5014, /* ldr r5, =0x400000CC ;load mbox base */
+ 0xe320f001, /* 1: yield */
+ 0xe7953200, /* ldr r3, [r5, r0, lsl #4] ;read mbox for our core*/
+ 0xe3530000, /* cmp r3, #0 ;spin while zero */
+ 0x0afffffb, /* beq 1b */
+ 0xe7853200, /* str r3, [r5, r0, lsl #4] ;clear mbox */
+ 0xe12fff13, /* bx r3 ;jump to target */
+ 0x400000cc, /* (constant: mailbox 3 read/clear base) */
+ };
+
+ /* check that we don't overrun board setup vectors */
+ QEMU_BUILD_BUG_ON(SMPBOOT_ADDR + sizeof(smpboot) > MVBAR_ADDR);
+ /* check that board setup address is correctly relocated */
+ QEMU_BUILD_BUG_ON((BOARDSETUP_ADDR & 0xf) != 0
+ || (BOARDSETUP_ADDR >> 4) >= 0x100);
+
+ rom_add_blob_fixed("raspi_smpboot", smpboot, sizeof(smpboot),
+ info->smp_loader_start);
+}
+
+static void write_board_setup(ARMCPU *cpu, const struct arm_boot_info *info)
+{
+ arm_write_secure_board_setup_dummy_smc(cpu, info, MVBAR_ADDR);
+}
+
+static void reset_secondary(ARMCPU *cpu, const struct arm_boot_info *info)
+{
+ CPUState *cs = CPU(cpu);
+ cpu_set_pc(cs, info->smp_loader_start);
+}
+
+static void setup_boot(MachineState *machine, int version, size_t ram_size)
+{
+ static struct arm_boot_info binfo;
+ int r;
+
+ binfo.board_id = raspi_boardid[version];
+ binfo.ram_size = ram_size;
+ binfo.nb_cpus = smp_cpus;
+ binfo.board_setup_addr = BOARDSETUP_ADDR;
+ binfo.write_board_setup = write_board_setup;
+ binfo.secure_board_setup = true;
+ binfo.secure_boot = true;
+
+ /* Pi2 requires SMP setup */
+ if (version == 2) {
+ binfo.smp_loader_start = SMPBOOT_ADDR;
+ binfo.write_secondary_boot = write_smpboot;
+ binfo.secondary_cpu_reset_hook = reset_secondary;
+ }
+
+ /* If the user specified a "firmware" image (e.g. UEFI), we bypass
+ * the normal Linux boot process
+ */
+ if (machine->firmware) {
+ /* load the firmware image (typically kernel.img) */
+ r = load_image_targphys(machine->firmware, FIRMWARE_ADDR,
+ ram_size - FIRMWARE_ADDR);
+ if (r < 0) {
+ error_report("Failed to load firmware from %s", machine->firmware);
+ exit(1);
+ }
+
+ binfo.entry = FIRMWARE_ADDR;
+ binfo.firmware_loaded = true;
+ } else {
+ binfo.kernel_filename = machine->kernel_filename;
+ binfo.kernel_cmdline = machine->kernel_cmdline;
+ binfo.initrd_filename = machine->initrd_filename;
+ }
+
+ arm_load_kernel(ARM_CPU(first_cpu), &binfo);
+}
+
+static void raspi2_init(MachineState *machine)
+{
+ RasPiState *s = g_new0(RasPiState, 1);
+
+ object_initialize(&s->soc, sizeof(s->soc), TYPE_BCM2836);
+ object_property_add_child(OBJECT(machine), "soc", OBJECT(&s->soc),
+ &error_abort);
+
+ /* Allocate and map RAM */
+ memory_region_allocate_system_memory(&s->ram, OBJECT(machine), "ram",
+ machine->ram_size);
+ /* FIXME: Remove when we have custom CPU address space support */
+ memory_region_add_subregion_overlap(get_system_memory(), 0, &s->ram, 0);
+
+ /* Setup the SOC */
+ object_property_add_const_link(OBJECT(&s->soc), "ram", OBJECT(&s->ram),
+ &error_abort);
+ object_property_set_int(OBJECT(&s->soc), smp_cpus, "enabled-cpus",
+ &error_abort);
+ object_property_set_bool(OBJECT(&s->soc), true, "realized", &error_abort);
+
+ setup_boot(machine, 2, machine->ram_size);
+}
+
+static void raspi2_machine_init(MachineClass *mc)
+{
+ mc->desc = "Raspberry Pi 2";
+ mc->init = raspi2_init;
+ mc->block_default_type = IF_SD;
+ mc->no_parallel = 1;
+ mc->no_floppy = 1;
+ mc->no_cdrom = 1;
+ mc->max_cpus = BCM2836_NCPUS;
+
+ /* XXX: Temporary restriction in RAM size from the full 1GB. Since
+ * we do not yet support the framebuffer / GPU, we need to limit
+ * RAM usable by the OS to sit below the peripherals.
+ */
+ mc->default_ram_size = 0x3F000000; /* BCM2836_PERI_BASE */
+};
+DEFINE_MACHINE("raspi2", raspi2_machine_init)
diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
index 560764fab1..8cf9a2167f 100644
--- a/hw/arm/virt-acpi-build.c
+++ b/hw/arm/virt-acpi-build.c
@@ -46,20 +46,6 @@
#define ARM_SPI_BASE 32
#define ACPI_POWER_BUTTON_DEVICE "PWRB"
-typedef struct VirtAcpiCpuInfo {
- DECLARE_BITMAP(found_cpus, VIRT_ACPI_CPU_ID_LIMIT);
-} VirtAcpiCpuInfo;
-
-static void virt_acpi_get_cpu_info(VirtAcpiCpuInfo *cpuinfo)
-{
- CPUState *cpu;
-
- memset(cpuinfo->found_cpus, 0, sizeof cpuinfo->found_cpus);
- CPU_FOREACH(cpu) {
- set_bit(cpu->cpu_index, cpuinfo->found_cpus);
- }
-}
-
static void acpi_dsdt_add_cpus(Aml *scope, int smp_cpus)
{
uint16_t i;
@@ -443,7 +429,7 @@ build_gtdt(GArray *table_data, GArray *linker)
gtdt->secure_el1_flags = ACPI_EDGE_SENSITIVE;
gtdt->non_secure_el1_interrupt = ARCH_TIMER_NS_EL1_IRQ + 16;
- gtdt->non_secure_el1_flags = ACPI_EDGE_SENSITIVE;
+ gtdt->non_secure_el1_flags = ACPI_EDGE_SENSITIVE | ACPI_GTDT_ALWAYS_ON;
gtdt->virtual_timer_interrupt = ARCH_TIMER_VIRT_IRQ + 16;
gtdt->virtual_timer_flags = ACPI_EDGE_SENSITIVE;
@@ -458,8 +444,7 @@ build_gtdt(GArray *table_data, GArray *linker)
/* MADT */
static void
-build_madt(GArray *table_data, GArray *linker, VirtGuestInfo *guest_info,
- VirtAcpiCpuInfo *cpuinfo)
+build_madt(GArray *table_data, GArray *linker, VirtGuestInfo *guest_info)
{
int madt_start = table_data->len;
const MemMapEntry *memmap = guest_info->memmap;
@@ -489,9 +474,7 @@ build_madt(GArray *table_data, GArray *linker, VirtGuestInfo *guest_info,
gicc->cpu_interface_number = i;
gicc->arm_mpidr = armcpu->mp_affinity;
gicc->uid = i;
- if (test_bit(i, cpuinfo->found_cpus)) {
- gicc->flags = cpu_to_le32(ACPI_GICC_ENABLED);
- }
+ gicc->flags = cpu_to_le32(ACPI_GICC_ENABLED);
}
if (guest_info->gic_version == 3) {
@@ -599,11 +582,8 @@ void virt_acpi_build(VirtGuestInfo *guest_info, AcpiBuildTables *tables)
{
GArray *table_offsets;
unsigned dsdt, rsdt;
- VirtAcpiCpuInfo cpuinfo;
GArray *tables_blob = tables->table_data;
- virt_acpi_get_cpu_info(&cpuinfo);
-
table_offsets = g_array_new(false, true /* clear */,
sizeof(uint32_t));
@@ -630,7 +610,7 @@ void virt_acpi_build(VirtGuestInfo *guest_info, AcpiBuildTables *tables)
build_fadt(tables_blob, tables->linker, dsdt);
acpi_add_table(table_offsets, tables_blob);
- build_madt(tables_blob, tables->linker, guest_info, &cpuinfo);
+ build_madt(tables_blob, tables->linker, guest_info);
acpi_add_table(table_offsets, tables_blob);
build_gtdt(tables_blob, tables->linker);
diff --git a/hw/audio/cs4231a.c b/hw/audio/cs4231a.c
index b0c7c93e21..3ecd0582bf 100644
--- a/hw/audio/cs4231a.c
+++ b/hw/audio/cs4231a.c
@@ -70,6 +70,7 @@ typedef struct CSState {
uint32_t irq;
uint32_t dma;
uint32_t port;
+ IsaDma *isa_dma;
int shift;
int dma_running;
int audio_free;
@@ -265,6 +266,7 @@ static void cs_reset_voices (CSState *s, uint32_t val)
{
int xtal;
struct audsettings as;
+ IsaDmaClass *k = ISADMA_GET_CLASS(s->isa_dma);
#ifdef DEBUG_XLAW
if (val == 0 || val == 32)
@@ -328,7 +330,7 @@ static void cs_reset_voices (CSState *s, uint32_t val)
if (s->dregs[Interface_Configuration] & PEN) {
if (!s->dma_running) {
- DMA_hold_DREQ (s->dma);
+ k->hold_DREQ(s->isa_dma, s->dma);
AUD_set_active_out (s->voice, 1);
s->transferred = 0;
}
@@ -336,7 +338,7 @@ static void cs_reset_voices (CSState *s, uint32_t val)
}
else {
if (s->dma_running) {
- DMA_release_DREQ (s->dma);
+ k->release_DREQ(s->isa_dma, s->dma);
AUD_set_active_out (s->voice, 0);
}
s->dma_running = 0;
@@ -345,7 +347,7 @@ static void cs_reset_voices (CSState *s, uint32_t val)
error:
if (s->dma_running) {
- DMA_release_DREQ (s->dma);
+ k->release_DREQ(s->isa_dma, s->dma);
AUD_set_active_out (s->voice, 0);
}
}
@@ -453,7 +455,8 @@ static void cs_write (void *opaque, hwaddr addr,
}
else {
if (s->dma_running) {
- DMA_release_DREQ (s->dma);
+ IsaDmaClass *k = ISADMA_GET_CLASS(s->isa_dma);
+ k->release_DREQ(s->isa_dma, s->dma);
AUD_set_active_out (s->voice, 0);
s->dma_running = 0;
}
@@ -518,6 +521,7 @@ static int cs_write_audio (CSState *s, int nchan, int dma_pos,
{
int temp, net;
uint8_t tmpbuf[4096];
+ IsaDmaClass *k = ISADMA_GET_CLASS(s->isa_dma);
temp = len;
net = 0;
@@ -532,7 +536,7 @@ static int cs_write_audio (CSState *s, int nchan, int dma_pos,
to_copy = sizeof (tmpbuf);
}
- copied = DMA_read_memory (nchan, tmpbuf, dma_pos, to_copy);
+ copied = k->read_memory(s->isa_dma, nchan, tmpbuf, dma_pos, to_copy);
if (s->tab) {
int i;
int16_t linbuf[4096];
@@ -600,7 +604,8 @@ static int cs4231a_pre_load (void *opaque)
CSState *s = opaque;
if (s->dma_running) {
- DMA_release_DREQ (s->dma);
+ IsaDmaClass *k = ISADMA_GET_CLASS(s->isa_dma);
+ k->release_DREQ(s->isa_dma, s->dma);
AUD_set_active_out (s->voice, 0);
}
s->dma_running = 0;
@@ -656,13 +661,15 @@ static void cs4231a_realizefn (DeviceState *dev, Error **errp)
{
ISADevice *d = ISA_DEVICE (dev);
CSState *s = CS4231A (dev);
+ IsaDmaClass *k;
isa_init_irq (d, &s->pic, s->irq);
+ s->isa_dma = isa_get_dma(isa_bus_from_device(d), s->dma);
+ k = ISADMA_GET_CLASS(s->isa_dma);
+ k->register_channel(s->isa_dma, s->dma, cs_dma_read, s);
isa_register_ioport (d, &s->ioports, s->port);
- DMA_register_channel (s->dma, cs_dma_read, s);
-
AUD_register_card ("cs4231a", &s->card);
}
diff --git a/hw/audio/gus.c b/hw/audio/gus.c
index 47c0fcfb4c..b416a54909 100644
--- a/hw/audio/gus.c
+++ b/hw/audio/gus.c
@@ -58,6 +58,7 @@ typedef struct GUSState {
SWVoiceOut *voice;
int64_t last_ticks;
qemu_irq pic;
+ IsaDma *isa_dma;
} GUSState;
static uint32_t gus_readb(void *opaque, uint32_t nport)
@@ -168,34 +169,36 @@ void GUS_irqclear (GUSEmuState *emu, int hwirq)
#endif
}
-void GUS_dmarequest (GUSEmuState *der)
+void GUS_dmarequest (GUSEmuState *emu)
{
- /* GUSState *s = (GUSState *) der; */
+ GUSState *s = emu->opaque;
+ IsaDmaClass *k = ISADMA_GET_CLASS(s->isa_dma);
ldebug ("dma request %d\n", der->gusdma);
- DMA_hold_DREQ (der->gusdma);
+ k->hold_DREQ(s->isa_dma, s->emu.gusdma);
}
static int GUS_read_DMA (void *opaque, int nchan, int dma_pos, int dma_len)
{
GUSState *s = opaque;
+ IsaDmaClass *k = ISADMA_GET_CLASS(s->isa_dma);
char tmpbuf[4096];
int pos = dma_pos, mode, left = dma_len - dma_pos;
ldebug ("read DMA %#x %d\n", dma_pos, dma_len);
- mode = DMA_get_channel_mode (s->emu.gusdma);
+ mode = k->has_autoinitialization(s->isa_dma, s->emu.gusdma);
while (left) {
int to_copy = audio_MIN ((size_t) left, sizeof (tmpbuf));
int copied;
ldebug ("left=%d to_copy=%d pos=%d\n", left, to_copy, pos);
- copied = DMA_read_memory (nchan, tmpbuf, pos, to_copy);
+ copied = k->read_memory(s->isa_dma, nchan, tmpbuf, pos, to_copy);
gus_dma_transferdata (&s->emu, tmpbuf, copied, left == copied);
left -= copied;
pos += copied;
}
if (((mode >> 4) & 1) == 0) {
- DMA_release_DREQ (s->emu.gusdma);
+ k->release_DREQ(s->isa_dma, s->emu.gusdma);
}
return dma_len;
}
@@ -232,6 +235,7 @@ static void gus_realizefn (DeviceState *dev, Error **errp)
{
ISADevice *d = ISA_DEVICE(dev);
GUSState *s = GUS (dev);
+ IsaDmaClass *k;
struct audsettings as;
AUD_register_card ("gus", &s->card);
@@ -264,7 +268,9 @@ static void gus_realizefn (DeviceState *dev, Error **errp)
isa_register_portio_list (d, (s->port + 0x100) & 0xf00,
gus_portio_list2, s, "gus");
- DMA_register_channel (s->emu.gusdma, GUS_read_DMA, s);
+ s->isa_dma = isa_get_dma(isa_bus_from_device(d), s->emu.gusdma);
+ k = ISADMA_GET_CLASS(s->isa_dma);
+ k->register_channel(s->isa_dma, s->emu.gusdma, GUS_read_DMA, s);
s->emu.himemaddr = s->himem;
s->emu.gusdatapos = s->emu.himemaddr + 1024 * 1024 + 32;
s->emu.opaque = s;
diff --git a/hw/audio/sb16.c b/hw/audio/sb16.c
index 3b2dcfdad9..6f8816cf64 100644
--- a/hw/audio/sb16.c
+++ b/hw/audio/sb16.c
@@ -56,6 +56,8 @@ typedef struct SB16State {
uint32_t hdma;
uint32_t port;
uint32_t ver;
+ IsaDma *isa_dma;
+ IsaDma *isa_hdma;
int in_index;
int out_data_len;
@@ -166,16 +168,18 @@ static void speaker (SB16State *s, int on)
static void control (SB16State *s, int hold)
{
int dma = s->use_hdma ? s->hdma : s->dma;
+ IsaDma *isa_dma = s->use_hdma ? s->isa_hdma : s->isa_dma;
+ IsaDmaClass *k = ISADMA_GET_CLASS(isa_dma);
s->dma_running = hold;
ldebug ("hold %d high %d dma %d\n", hold, s->use_hdma, dma);
if (hold) {
- DMA_hold_DREQ (dma);
+ k->hold_DREQ(isa_dma, dma);
AUD_set_active_out (s->voice, 1);
}
else {
- DMA_release_DREQ (dma);
+ k->release_DREQ(isa_dma, dma);
AUD_set_active_out (s->voice, 0);
}
}
@@ -1137,6 +1141,8 @@ static uint32_t mixer_read(void *opaque, uint32_t nport)
static int write_audio (SB16State *s, int nchan, int dma_pos,
int dma_len, int len)
{
+ IsaDma *isa_dma = nchan == s->dma ? s->isa_dma : s->isa_hdma;
+ IsaDmaClass *k = ISADMA_GET_CLASS(isa_dma);
int temp, net;
uint8_t tmpbuf[4096];
@@ -1153,7 +1159,7 @@ static int write_audio (SB16State *s, int nchan, int dma_pos,
to_copy = sizeof (tmpbuf);
}
- copied = DMA_read_memory (nchan, tmpbuf, dma_pos, to_copy);
+ copied = k->read_memory(isa_dma, nchan, tmpbuf, dma_pos, to_copy);
copied = AUD_write (s->voice, tmpbuf, copied);
temp -= copied;
@@ -1355,6 +1361,7 @@ static void sb16_realizefn (DeviceState *dev, Error **errp)
{
ISADevice *isadev = ISA_DEVICE (dev);
SB16State *s = SB16 (dev);
+ IsaDmaClass *k;
isa_init_irq (isadev, &s->pic, s->irq);
@@ -1373,8 +1380,14 @@ static void sb16_realizefn (DeviceState *dev, Error **errp)
isa_register_portio_list (isadev, s->port, sb16_ioport_list, s, "sb16");
- DMA_register_channel (s->hdma, SB_read_DMA, s);
- DMA_register_channel (s->dma, SB_read_DMA, s);
+ s->isa_hdma = isa_get_dma(isa_bus_from_device(isadev), s->hdma);
+ k = ISADMA_GET_CLASS(s->isa_hdma);
+ k->register_channel(s->isa_hdma, s->hdma, SB_read_DMA, s);
+
+ s->isa_dma = isa_get_dma(isa_bus_from_device(isadev), s->dma);
+ k = ISADMA_GET_CLASS(s->isa_dma);
+ k->register_channel(s->isa_dma, s->dma, SB_read_DMA, s);
+
s->can_write = 1;
AUD_register_card ("sb16", &s->card);
diff --git a/hw/block/fdc.c b/hw/block/fdc.c
index 818e8a4072..a6f22ef200 100644
--- a/hw/block/fdc.c
+++ b/hw/block/fdc.c
@@ -179,6 +179,21 @@ typedef struct FDrive {
static FloppyDriveType get_fallback_drive_type(FDrive *drv);
+/* Hack: FD_SEEK is expected to work on empty drives. However, QEMU
+ * currently goes through some pains to keep seeks within the bounds
+ * established by last_sect and max_track. Correcting this is difficult,
+ * as refactoring FDC code tends to expose nasty bugs in the Linux kernel.
+ *
+ * For now: allow empty drives to have large bounds so we can seek around,
+ * with the understanding that when a diskette is inserted, the bounds will
+ * properly tighten to match the geometry of that inserted medium.
+ */
+static void fd_empty_seek_hack(FDrive *drv)
+{
+ drv->last_sect = 0xFF;
+ drv->max_track = 0xFF;
+}
+
static void fd_init(FDrive *drv)
{
/* Drive */
@@ -394,6 +409,7 @@ static void fd_revalidate(FDrive *drv)
if (!blk_is_inserted(drv->blk)) {
FLOPPY_DPRINTF("No disk in drive\n");
drv->disk = FLOPPY_DRIVE_TYPE_NONE;
+ fd_empty_seek_hack(drv);
} else if (!drv->media_validated) {
rc = pick_geometry(drv);
if (rc) {
@@ -628,6 +644,7 @@ struct FDCtrl {
QEMUTimer *result_timer;
int dma_chann;
uint8_t phase;
+ IsaDma *dma;
/* Controller's identification */
uint8_t version;
/* HW */
@@ -1413,7 +1430,8 @@ static void fdctrl_stop_transfer(FDCtrl *fdctrl, uint8_t status0,
fdctrl->fifo[6] = FD_SECTOR_SC;
fdctrl->data_dir = FD_DIR_READ;
if (!(fdctrl->msr & FD_MSR_NONDMA)) {
- DMA_release_DREQ(fdctrl->dma_chann);
+ IsaDmaClass *k = ISADMA_GET_CLASS(fdctrl->dma);
+ k->release_DREQ(fdctrl->dma, fdctrl->dma_chann);
}
fdctrl->msr |= FD_MSR_RQM | FD_MSR_DIO;
fdctrl->msr &= ~FD_MSR_NONDMA;
@@ -1499,27 +1517,43 @@ static void fdctrl_start_transfer(FDCtrl *fdctrl, int direction)
}
fdctrl->eot = fdctrl->fifo[6];
if (fdctrl->dor & FD_DOR_DMAEN) {
- int dma_mode;
+ IsaDmaTransferMode dma_mode;
+ IsaDmaClass *k = ISADMA_GET_CLASS(fdctrl->dma);
+ bool dma_mode_ok;
/* DMA transfer are enabled. Check if DMA channel is well programmed */
- dma_mode = DMA_get_channel_mode(fdctrl->dma_chann);
- dma_mode = (dma_mode >> 2) & 3;
+ dma_mode = k->get_transfer_mode(fdctrl->dma, fdctrl->dma_chann);
FLOPPY_DPRINTF("dma_mode=%d direction=%d (%d - %d)\n",
dma_mode, direction,
(128 << fdctrl->fifo[5]) *
(cur_drv->last_sect - ks + 1), fdctrl->data_len);
- if (((direction == FD_DIR_SCANE || direction == FD_DIR_SCANL ||
- direction == FD_DIR_SCANH) && dma_mode == 0) ||
- (direction == FD_DIR_WRITE && dma_mode == 2) ||
- (direction == FD_DIR_READ && dma_mode == 1) ||
- (direction == FD_DIR_VERIFY)) {
+ switch (direction) {
+ case FD_DIR_SCANE:
+ case FD_DIR_SCANL:
+ case FD_DIR_SCANH:
+ dma_mode_ok = (dma_mode == ISADMA_TRANSFER_VERIFY);
+ break;
+ case FD_DIR_WRITE:
+ dma_mode_ok = (dma_mode == ISADMA_TRANSFER_WRITE);
+ break;
+ case FD_DIR_READ:
+ dma_mode_ok = (dma_mode == ISADMA_TRANSFER_READ);
+ break;
+ case FD_DIR_VERIFY:
+ dma_mode_ok = true;
+ break;
+ default:
+ dma_mode_ok = false;
+ break;
+ }
+ if (dma_mode_ok) {
/* No access is allowed until DMA transfer has completed */
fdctrl->msr &= ~FD_MSR_RQM;
if (direction != FD_DIR_VERIFY) {
/* Now, we just have to wait for the DMA controller to
* recall us...
*/
- DMA_hold_DREQ(fdctrl->dma_chann);
- DMA_schedule();
+ k->hold_DREQ(fdctrl->dma, fdctrl->dma_chann);
+ k->schedule(fdctrl->dma);
} else {
/* Start transfer */
fdctrl_transfer_handler(fdctrl, fdctrl->dma_chann, 0,
@@ -1558,12 +1592,14 @@ static int fdctrl_transfer_handler (void *opaque, int nchan,
FDrive *cur_drv;
int len, start_pos, rel_pos;
uint8_t status0 = 0x00, status1 = 0x00, status2 = 0x00;
+ IsaDmaClass *k;
fdctrl = opaque;
if (fdctrl->msr & FD_MSR_RQM) {
FLOPPY_DPRINTF("Not in DMA transfer mode !\n");
return 0;
}
+ k = ISADMA_GET_CLASS(fdctrl->dma);
cur_drv = get_cur_drv(fdctrl);
if (fdctrl->data_dir == FD_DIR_SCANE || fdctrl->data_dir == FD_DIR_SCANL ||
fdctrl->data_dir == FD_DIR_SCANH)
@@ -1602,8 +1638,8 @@ static int fdctrl_transfer_handler (void *opaque, int nchan,
switch (fdctrl->data_dir) {
case FD_DIR_READ:
/* READ commands */
- DMA_write_memory (nchan, fdctrl->fifo + rel_pos,
- fdctrl->data_pos, len);
+ k->write_memory(fdctrl->dma, nchan, fdctrl->fifo + rel_pos,
+ fdctrl->data_pos, len);
break;
case FD_DIR_WRITE:
/* WRITE commands */
@@ -1617,8 +1653,8 @@ static int fdctrl_transfer_handler (void *opaque, int nchan,
goto transfer_error;
}
- DMA_read_memory (nchan, fdctrl->fifo + rel_pos,
- fdctrl->data_pos, len);
+ k->read_memory(fdctrl->dma, nchan, fdctrl->fifo + rel_pos,
+ fdctrl->data_pos, len);
if (blk_write(cur_drv->blk, fd_sector(cur_drv),
fdctrl->fifo, 1) < 0) {
FLOPPY_DPRINTF("error writing sector %d\n",
@@ -1635,7 +1671,8 @@ static int fdctrl_transfer_handler (void *opaque, int nchan,
{
uint8_t tmpbuf[FD_SECTOR_LEN];
int ret;
- DMA_read_memory (nchan, tmpbuf, fdctrl->data_pos, len);
+ k->read_memory(fdctrl->dma, nchan, tmpbuf, fdctrl->data_pos,
+ len);
ret = memcmp(tmpbuf, fdctrl->fifo + rel_pos, len);
if (ret == 0) {
status2 = FD_SR2_SEH;
@@ -2425,7 +2462,11 @@ static void fdctrl_realize_common(FDCtrl *fdctrl, Error **errp)
fdctrl->num_floppies = MAX_FD;
if (fdctrl->dma_chann != -1) {
- DMA_register_channel(fdctrl->dma_chann, &fdctrl_transfer_handler, fdctrl);
+ IsaDmaClass *k;
+ assert(fdctrl->dma);
+ k = ISADMA_GET_CLASS(fdctrl->dma);
+ k->register_channel(fdctrl->dma, fdctrl->dma_chann,
+ &fdctrl_transfer_handler, fdctrl);
}
fdctrl_connect_drives(fdctrl, errp);
}
@@ -2448,6 +2489,10 @@ static void isabus_fdc_realize(DeviceState *dev, Error **errp)
isa_init_irq(isadev, &fdctrl->irq, isa->irq);
fdctrl->dma_chann = isa->dma;
+ if (fdctrl->dma_chann != -1) {
+ fdctrl->dma = isa_get_dma(isa_bus_from_device(isadev), isa->dma);
+ assert(fdctrl->dma);
+ }
qdev_set_legacy_instance_id(dev, isa->iobase, 2);
fdctrl_realize_common(fdctrl, &err);
@@ -2476,6 +2521,8 @@ static void sun4m_fdc_initfn(Object *obj)
FDCtrlSysBus *sys = SYSBUS_FDC(obj);
FDCtrl *fdctrl = &sys->state;
+ fdctrl->dma_chann = -1;
+
memory_region_init_io(&fdctrl->iomem, obj, &fdctrl_mem_strict_ops,
fdctrl, "fdctrl", 0x08);
sysbus_init_mmio(sbd, &fdctrl->iomem);
diff --git a/hw/dma/i82374.c b/hw/dma/i82374.c
index 869721d848..6c0f975df0 100644
--- a/hw/dma/i82374.c
+++ b/hw/dma/i82374.c
@@ -25,6 +25,9 @@
#include "qemu/osdep.h"
#include "hw/isa/isa.h"
+#define TYPE_I82374 "i82374"
+#define I82374(obj) OBJECT_CHECK(I82374State, (obj), TYPE_I82374)
+
//#define DEBUG_I82374
#ifdef DEBUG_I82374
@@ -38,6 +41,9 @@ do {} while (0)
do { fprintf(stderr, "i82374 ERROR: " fmt , ## __VA_ARGS__); } while (0)
typedef struct I82374State {
+ ISADevice parent_obj;
+
+ uint32_t iobase;
uint8_t commands[8];
PortioList port_list;
} I82374State;
@@ -99,32 +105,6 @@ static uint32_t i82374_read_descriptor(void *opaque, uint32_t nport)
return val;
}
-static void i82374_realize(I82374State *s, Error **errp)
-{
- DMA_init(1);
- memset(s->commands, 0, sizeof(s->commands));
-}
-
-#define TYPE_I82374 "i82374"
-#define I82374(obj) OBJECT_CHECK(ISAi82374State, (obj), TYPE_I82374)
-
-typedef struct ISAi82374State {
- ISADevice parent_obj;
-
- uint32_t iobase;
- I82374State state;
-} ISAi82374State;
-
-static const VMStateDescription vmstate_isa_i82374 = {
- .name = "isa-i82374",
- .version_id = 0,
- .minimum_version_id = 0,
- .fields = (VMStateField[]) {
- VMSTATE_STRUCT(state, ISAi82374State, 0, vmstate_i82374, I82374State),
- VMSTATE_END_OF_LIST()
- },
-};
-
static const MemoryRegionPortio i82374_portio_list[] = {
{ 0x0A, 1, 1, .read = i82374_read_isr, },
{ 0x10, 8, 1, .write = i82374_write_command, },
@@ -134,21 +114,21 @@ static const MemoryRegionPortio i82374_portio_list[] = {
PORTIO_END_OF_LIST(),
};
-static void i82374_isa_realize(DeviceState *dev, Error **errp)
+static void i82374_realize(DeviceState *dev, Error **errp)
{
- ISAi82374State *isa = I82374(dev);
- I82374State *s = &isa->state;
+ I82374State *s = I82374(dev);
- portio_list_init(&s->port_list, OBJECT(isa), i82374_portio_list, s,
+ portio_list_init(&s->port_list, OBJECT(s), i82374_portio_list, s,
"i82374");
- portio_list_add(&s->port_list, isa_address_space_io(&isa->parent_obj),
- isa->iobase);
+ portio_list_add(&s->port_list, isa_address_space_io(&s->parent_obj),
+ s->iobase);
- i82374_realize(s, errp);
+ DMA_init(isa_bus_from_device(ISA_DEVICE(dev)), 1);
+ memset(s->commands, 0, sizeof(s->commands));
}
static Property i82374_properties[] = {
- DEFINE_PROP_UINT32("iobase", ISAi82374State, iobase, 0x400),
+ DEFINE_PROP_UINT32("iobase", I82374State, iobase, 0x400),
DEFINE_PROP_END_OF_LIST()
};
@@ -156,21 +136,21 @@ static void i82374_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
- dc->realize = i82374_isa_realize;
- dc->vmsd = &vmstate_isa_i82374;
+ dc->realize = i82374_realize;
+ dc->vmsd = &vmstate_i82374;
dc->props = i82374_properties;
}
-static const TypeInfo i82374_isa_info = {
+static const TypeInfo i82374_info = {
.name = TYPE_I82374,
.parent = TYPE_ISA_DEVICE,
- .instance_size = sizeof(ISAi82374State),
+ .instance_size = sizeof(I82374State),
.class_init = i82374_class_init,
};
static void i82374_register_types(void)
{
- type_register_static(&i82374_isa_info);
+ type_register_static(&i82374_info);
}
type_init(i82374_register_types)
diff --git a/hw/dma/i8257.c b/hw/dma/i8257.c
index 1ff6c4da71..5a52707ae2 100644
--- a/hw/dma/i8257.c
+++ b/hw/dma/i8257.c
@@ -24,9 +24,13 @@
#include "qemu/osdep.h"
#include "hw/hw.h"
#include "hw/isa/isa.h"
+#include "hw/isa/i8257.h"
#include "qemu/main-loop.h"
#include "trace.h"
+#define I8257(obj) \
+ OBJECT_CHECK(I8257State, (obj), TYPE_I8257)
+
/* #define DEBUG_DMA */
#define dolog(...) fprintf (stderr, "dma: " __VA_ARGS__)
@@ -38,32 +42,9 @@
#define ldebug(...)
#endif
-struct dma_regs {
- int now[2];
- uint16_t base[2];
- uint8_t mode;
- uint8_t page;
- uint8_t pageh;
- uint8_t dack;
- uint8_t eop;
- DMA_transfer_handler transfer_handler;
- void *opaque;
-};
-
#define ADDR 0
#define COUNT 1
-static struct dma_cont {
- uint8_t status;
- uint8_t command;
- uint8_t mask;
- uint8_t flip_flop;
- int dshift;
- struct dma_regs regs[4];
- MemoryRegion channel_io;
- MemoryRegion cont_io;
-} dma_controllers[2];
-
enum {
CMD_MEMORY_TO_MEMORY = 0x01,
CMD_FIXED_ADDRESS = 0x02,
@@ -79,13 +60,13 @@ enum {
};
-static void DMA_run (void);
+static void i8257_dma_run(void *opaque);
-static int channels[8] = {-1, 2, 3, 1, -1, -1, -1, 0};
+static const int channels[8] = {-1, 2, 3, 1, -1, -1, -1, 0};
-static void write_page (void *opaque, uint32_t nport, uint32_t data)
+static void i8257_write_page(void *opaque, uint32_t nport, uint32_t data)
{
- struct dma_cont *d = opaque;
+ I8257State *d = opaque;
int ichan;
ichan = channels[nport & 7];
@@ -96,9 +77,9 @@ static void write_page (void *opaque, uint32_t nport, uint32_t data)
d->regs[ichan].page = data;
}
-static void write_pageh (void *opaque, uint32_t nport, uint32_t data)
+static void i8257_write_pageh(void *opaque, uint32_t nport, uint32_t data)
{
- struct dma_cont *d = opaque;
+ I8257State *d = opaque;
int ichan;
ichan = channels[nport & 7];
@@ -109,9 +90,9 @@ static void write_pageh (void *opaque, uint32_t nport, uint32_t data)
d->regs[ichan].pageh = data;
}
-static uint32_t read_page (void *opaque, uint32_t nport)
+static uint32_t i8257_read_page(void *opaque, uint32_t nport)
{
- struct dma_cont *d = opaque;
+ I8257State *d = opaque;
int ichan;
ichan = channels[nport & 7];
@@ -122,9 +103,9 @@ static uint32_t read_page (void *opaque, uint32_t nport)
return d->regs[ichan].page;
}
-static uint32_t read_pageh (void *opaque, uint32_t nport)
+static uint32_t i8257_read_pageh(void *opaque, uint32_t nport)
{
- struct dma_cont *d = opaque;
+ I8257State *d = opaque;
int ichan;
ichan = channels[nport & 7];
@@ -135,16 +116,16 @@ static uint32_t read_pageh (void *opaque, uint32_t nport)
return d->regs[ichan].pageh;
}
-static inline void init_chan (struct dma_cont *d, int ichan)
+static inline void i8257_init_chan(I8257State *d, int ichan)
{
- struct dma_regs *r;
+ I8257Regs *r;
r = d->regs + ichan;
r->now[ADDR] = r->base[ADDR] << d->dshift;
r->now[COUNT] = 0;
}
-static inline int getff (struct dma_cont *d)
+static inline int i8257_getff(I8257State *d)
{
int ff;
@@ -153,11 +134,11 @@ static inline int getff (struct dma_cont *d)
return ff;
}
-static uint64_t read_chan(void *opaque, hwaddr nport, unsigned size)
+static uint64_t i8257_read_chan(void *opaque, hwaddr nport, unsigned size)
{
- struct dma_cont *d = opaque;
+ I8257State *d = opaque;
int ichan, nreg, iport, ff, val, dir;
- struct dma_regs *r;
+ I8257Regs *r;
iport = (nport >> d->dshift) & 0x0f;
ichan = iport >> 1;
@@ -165,7 +146,7 @@ static uint64_t read_chan(void *opaque, hwaddr nport, unsigned size)
r = d->regs + ichan;
dir = ((r->mode >> 5) & 1) ? -1 : 1;
- ff = getff (d);
+ ff = i8257_getff(d);
if (nreg)
val = (r->base[COUNT] << d->dshift) - r->now[COUNT];
else
@@ -175,29 +156,29 @@ static uint64_t read_chan(void *opaque, hwaddr nport, unsigned size)
return (val >> (d->dshift + (ff << 3))) & 0xff;
}
-static void write_chan(void *opaque, hwaddr nport, uint64_t data,
- unsigned size)
+static void i8257_write_chan(void *opaque, hwaddr nport, uint64_t data,
+ unsigned int size)
{
- struct dma_cont *d = opaque;
+ I8257State *d = opaque;
int iport, ichan, nreg;
- struct dma_regs *r;
+ I8257Regs *r;
iport = (nport >> d->dshift) & 0x0f;
ichan = iport >> 1;
nreg = iport & 1;
r = d->regs + ichan;
- if (getff (d)) {
+ if (i8257_getff(d)) {
r->base[nreg] = (r->base[nreg] & 0xff) | ((data << 8) & 0xff00);
- init_chan (d, ichan);
+ i8257_init_chan(d, ichan);
} else {
r->base[nreg] = (r->base[nreg] & 0xff00) | (data & 0xff);
}
}
-static void write_cont(void *opaque, hwaddr nport, uint64_t data,
- unsigned size)
+static void i8257_write_cont(void *opaque, hwaddr nport, uint64_t data,
+ unsigned int size)
{
- struct dma_cont *d = opaque;
+ I8257State *d = opaque;
int iport, ichan = 0;
iport = (nport >> d->dshift) & 0x0f;
@@ -219,7 +200,7 @@ static void write_cont(void *opaque, hwaddr nport, uint64_t data,
d->status &= ~(1 << (ichan + 4));
}
d->status &= ~(1 << ichan);
- DMA_run();
+ i8257_dma_run(d);
break;
case 0x02: /* single mask */
@@ -227,7 +208,7 @@ static void write_cont(void *opaque, hwaddr nport, uint64_t data,
d->mask |= 1 << (data & 3);
else
d->mask &= ~(1 << (data & 3));
- DMA_run();
+ i8257_dma_run(d);
break;
case 0x03: /* mode */
@@ -262,12 +243,12 @@ static void write_cont(void *opaque, hwaddr nport, uint64_t data,
case 0x06: /* clear mask for all channels */
d->mask = 0;
- DMA_run();
+ i8257_dma_run(d);
break;
case 0x07: /* write mask for all channels */
d->mask = data;
- DMA_run();
+ i8257_dma_run(d);
break;
default:
@@ -283,9 +264,9 @@ static void write_cont(void *opaque, hwaddr nport, uint64_t data,
#endif
}
-static uint64_t read_cont(void *opaque, hwaddr nport, unsigned size)
+static uint64_t i8257_read_cont(void *opaque, hwaddr nport, unsigned size)
{
- struct dma_cont *d = opaque;
+ I8257State *d = opaque;
int iport, val;
iport = (nport >> d->dshift) & 0x0f;
@@ -306,37 +287,43 @@ static uint64_t read_cont(void *opaque, hwaddr nport, unsigned size)
return val;
}
-int DMA_get_channel_mode (int nchan)
+static IsaDmaTransferMode i8257_dma_get_transfer_mode(IsaDma *obj, int nchan)
{
- return dma_controllers[nchan > 3].regs[nchan & 3].mode;
+ I8257State *d = I8257(obj);
+ return (d->regs[nchan & 3].mode >> 2) & 3;
}
-void DMA_hold_DREQ (int nchan)
+static bool i8257_dma_has_autoinitialization(IsaDma *obj, int nchan)
{
- int ncont, ichan;
+ I8257State *d = I8257(obj);
+ return (d->regs[nchan & 3].mode >> 4) & 1;
+}
+
+static void i8257_dma_hold_DREQ(IsaDma *obj, int nchan)
+{
+ I8257State *d = I8257(obj);
+ int ichan;
- ncont = nchan > 3;
ichan = nchan & 3;
- linfo ("held cont=%d chan=%d\n", ncont, ichan);
- dma_controllers[ncont].status |= 1 << (ichan + 4);
- DMA_run();
+ d->status |= 1 << (ichan + 4);
+ i8257_dma_run(d);
}
-void DMA_release_DREQ (int nchan)
+static void i8257_dma_release_DREQ(IsaDma *obj, int nchan)
{
- int ncont, ichan;
+ I8257State *d = I8257(obj);
+ int ichan;
- ncont = nchan > 3;
ichan = nchan & 3;
- linfo ("released cont=%d chan=%d\n", ncont, ichan);
- dma_controllers[ncont].status &= ~(1 << (ichan + 4));
- DMA_run();
+ d->status &= ~(1 << (ichan + 4));
+ i8257_dma_run(d);
}
-static void channel_run (int ncont, int ichan)
+static void i8257_channel_run(I8257State *d, int ichan)
{
+ int ncont = d->dshift;
int n;
- struct dma_regs *r = &dma_controllers[ncont].regs[ichan];
+ I8257Regs *r = &d->regs[ichan];
#ifdef DEBUG_DMA
int dir, opmode;
@@ -357,70 +344,58 @@ static void channel_run (int ncont, int ichan)
ldebug ("dma_pos %d size %d\n", n, (r->base[COUNT] + 1) << ncont);
}
-static QEMUBH *dma_bh;
-static bool dma_bh_scheduled;
-
-static void DMA_run (void)
+static void i8257_dma_run(void *opaque)
{
- struct dma_cont *d;
- int icont, ichan;
+ I8257State *d = opaque;
+ int ichan;
int rearm = 0;
- static int running = 0;
- if (running) {
+ if (d->running) {
rearm = 1;
goto out;
} else {
- running = 1;
+ d->running = 1;
}
- d = dma_controllers;
-
- for (icont = 0; icont < 2; icont++, d++) {
- for (ichan = 0; ichan < 4; ichan++) {
- int mask;
+ for (ichan = 0; ichan < 4; ichan++) {
+ int mask;
- mask = 1 << ichan;
+ mask = 1 << ichan;
- if ((0 == (d->mask & mask)) && (0 != (d->status & (mask << 4)))) {
- channel_run (icont, ichan);
- rearm = 1;
- }
+ if ((0 == (d->mask & mask)) && (0 != (d->status & (mask << 4)))) {
+ i8257_channel_run(d, ichan);
+ rearm = 1;
}
}
- running = 0;
+ d->running = 0;
out:
if (rearm) {
- qemu_bh_schedule_idle(dma_bh);
- dma_bh_scheduled = true;
+ qemu_bh_schedule_idle(d->dma_bh);
+ d->dma_bh_scheduled = true;
}
}
-static void DMA_run_bh(void *unused)
+static void i8257_dma_register_channel(IsaDma *obj, int nchan,
+ DMA_transfer_handler transfer_handler,
+ void *opaque)
{
- dma_bh_scheduled = false;
- DMA_run();
-}
-
-void DMA_register_channel (int nchan,
- DMA_transfer_handler transfer_handler,
- void *opaque)
-{
- struct dma_regs *r;
- int ichan, ncont;
+ I8257State *d = I8257(obj);
+ I8257Regs *r;
+ int ichan;
- ncont = nchan > 3;
ichan = nchan & 3;
- r = dma_controllers[ncont].regs + ichan;
+ r = d->regs + ichan;
r->transfer_handler = transfer_handler;
r->opaque = opaque;
}
-int DMA_read_memory (int nchan, void *buf, int pos, int len)
+static int i8257_dma_read_memory(IsaDma *obj, int nchan, void *buf, int pos,
+ int len)
{
- struct dma_regs *r = &dma_controllers[nchan > 3].regs[nchan & 3];
+ I8257State *d = I8257(obj);
+ I8257Regs *r = &d->regs[nchan & 3];
hwaddr addr = ((r->pageh & 0x7f) << 24) | (r->page << 16) | r->now[ADDR];
if (r->mode & 0x20) {
@@ -440,9 +415,11 @@ int DMA_read_memory (int nchan, void *buf, int pos, int len)
return len;
}
-int DMA_write_memory (int nchan, void *buf, int pos, int len)
+static int i8257_dma_write_memory(IsaDma *obj, int nchan, void *buf, int pos,
+ int len)
{
- struct dma_regs *r = &dma_controllers[nchan > 3].regs[nchan & 3];
+ I8257State *s = I8257(obj);
+ I8257Regs *r = &s->regs[nchan & 3];
hwaddr addr = ((r->pageh & 0x7f) << 24) | (r->page << 16) | r->now[ADDR];
if (r->mode & 0x20) {
@@ -465,20 +442,22 @@ int DMA_write_memory (int nchan, void *buf, int pos, int len)
/* request the emulator to transfer a new DMA memory block ASAP (even
* if the idle bottom half would not have exited the iothread yet).
*/
-void DMA_schedule(void)
+static void i8257_dma_schedule(IsaDma *obj)
{
- if (dma_bh_scheduled) {
+ I8257State *d = I8257(obj);
+ if (d->dma_bh_scheduled) {
qemu_notify_event();
}
}
-static void dma_reset(void *opaque)
+static void i8257_reset(DeviceState *dev)
{
- struct dma_cont *d = opaque;
- write_cont(d, (0x05 << d->dshift), 0, 1);
+ I8257State *d = I8257(dev);
+ i8257_write_cont(d, (0x05 << d->dshift), 0, 1);
}
-static int dma_phony_handler (void *opaque, int nchan, int dma_pos, int dma_len)
+static int i8257_phony_handler(void *opaque, int nchan, int dma_pos,
+ int dma_len)
{
trace_i8257_unregistered_dma(nchan, dma_pos, dma_len);
return dma_pos;
@@ -486,8 +465,8 @@ static int dma_phony_handler (void *opaque, int nchan, int dma_pos, int dma_len)
static const MemoryRegionOps channel_io_ops = {
- .read = read_chan,
- .write = write_chan,
+ .read = i8257_read_chan,
+ .write = i8257_write_chan,
.endianness = DEVICE_NATIVE_ENDIAN,
.impl = {
.min_access_size = 1,
@@ -497,21 +476,21 @@ static const MemoryRegionOps channel_io_ops = {
/* IOport from page_base */
static const MemoryRegionPortio page_portio_list[] = {
- { 0x01, 3, 1, .write = write_page, .read = read_page, },
- { 0x07, 1, 1, .write = write_page, .read = read_page, },
+ { 0x01, 3, 1, .write = i8257_write_page, .read = i8257_read_page, },
+ { 0x07, 1, 1, .write = i8257_write_page, .read = i8257_read_page, },
PORTIO_END_OF_LIST(),
};
/* IOport from pageh_base */
static const MemoryRegionPortio pageh_portio_list[] = {
- { 0x01, 3, 1, .write = write_pageh, .read = read_pageh, },
- { 0x07, 3, 1, .write = write_pageh, .read = read_pageh, },
+ { 0x01, 3, 1, .write = i8257_write_pageh, .read = i8257_read_pageh, },
+ { 0x07, 3, 1, .write = i8257_write_pageh, .read = i8257_read_pageh, },
PORTIO_END_OF_LIST(),
};
static const MemoryRegionOps cont_io_ops = {
- .read = read_cont,
- .write = write_cont,
+ .read = i8257_read_cont,
+ .write = i8257_write_cont,
.endianness = DEVICE_NATIVE_ENDIAN,
.impl = {
.min_access_size = 1,
@@ -519,82 +498,142 @@ static const MemoryRegionOps cont_io_ops = {
},
};
-/* dshift = 0: 8 bit DMA, 1 = 16 bit DMA */
-static void dma_init2(struct dma_cont *d, int base, int dshift,
- int page_base, int pageh_base)
+static const VMStateDescription vmstate_i8257_regs = {
+ .name = "dma_regs",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .fields = (VMStateField[]) {
+ VMSTATE_INT32_ARRAY(now, I8257Regs, 2),
+ VMSTATE_UINT16_ARRAY(base, I8257Regs, 2),
+ VMSTATE_UINT8(mode, I8257Regs),
+ VMSTATE_UINT8(page, I8257Regs),
+ VMSTATE_UINT8(pageh, I8257Regs),
+ VMSTATE_UINT8(dack, I8257Regs),
+ VMSTATE_UINT8(eop, I8257Regs),
+ VMSTATE_END_OF_LIST()
+ }
+};
+
+static int i8257_post_load(void *opaque, int version_id)
{
- int i;
+ I8257State *d = opaque;
+ i8257_dma_run(d);
- d->dshift = dshift;
+ return 0;
+}
+
+static const VMStateDescription vmstate_i8257 = {
+ .name = "dma",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .post_load = i8257_post_load,
+ .fields = (VMStateField[]) {
+ VMSTATE_UINT8(command, I8257State),
+ VMSTATE_UINT8(mask, I8257State),
+ VMSTATE_UINT8(flip_flop, I8257State),
+ VMSTATE_INT32(dshift, I8257State),
+ VMSTATE_STRUCT_ARRAY(regs, I8257State, 4, 1, vmstate_i8257_regs,
+ I8257Regs),
+ VMSTATE_END_OF_LIST()
+ }
+};
+
+static void i8257_realize(DeviceState *dev, Error **errp)
+{
+ ISADevice *isa = ISA_DEVICE(dev);
+ I8257State *d = I8257(dev);
+ int i;
memory_region_init_io(&d->channel_io, NULL, &channel_io_ops, d,
"dma-chan", 8 << d->dshift);
- memory_region_add_subregion(isa_address_space_io(NULL),
- base, &d->channel_io);
+ memory_region_add_subregion(isa_address_space_io(isa),
+ d->base, &d->channel_io);
- isa_register_portio_list(NULL, page_base, page_portio_list, d,
+ isa_register_portio_list(isa, d->page_base, page_portio_list, d,
"dma-page");
- if (pageh_base >= 0) {
- isa_register_portio_list(NULL, pageh_base, pageh_portio_list, d,
+ if (d->pageh_base >= 0) {
+ isa_register_portio_list(isa, d->pageh_base, pageh_portio_list, d,
"dma-pageh");
}
- memory_region_init_io(&d->cont_io, NULL, &cont_io_ops, d, "dma-cont",
- 8 << d->dshift);
- memory_region_add_subregion(isa_address_space_io(NULL),
- base + (8 << d->dshift), &d->cont_io);
+ memory_region_init_io(&d->cont_io, OBJECT(isa), &cont_io_ops, d,
+ "dma-cont", 8 << d->dshift);
+ memory_region_add_subregion(isa_address_space_io(isa),
+ d->base + (8 << d->dshift), &d->cont_io);
- qemu_register_reset(dma_reset, d);
- dma_reset(d);
- for (i = 0; i < ARRAY_SIZE (d->regs); ++i) {
- d->regs[i].transfer_handler = dma_phony_handler;
+ for (i = 0; i < ARRAY_SIZE(d->regs); ++i) {
+ d->regs[i].transfer_handler = i8257_phony_handler;
}
+
+ d->dma_bh = qemu_bh_new(i8257_dma_run, d);
}
-static const VMStateDescription vmstate_dma_regs = {
- .name = "dma_regs",
- .version_id = 1,
- .minimum_version_id = 1,
- .fields = (VMStateField[]) {
- VMSTATE_INT32_ARRAY(now, struct dma_regs, 2),
- VMSTATE_UINT16_ARRAY(base, struct dma_regs, 2),
- VMSTATE_UINT8(mode, struct dma_regs),
- VMSTATE_UINT8(page, struct dma_regs),
- VMSTATE_UINT8(pageh, struct dma_regs),
- VMSTATE_UINT8(dack, struct dma_regs),
- VMSTATE_UINT8(eop, struct dma_regs),
- VMSTATE_END_OF_LIST()
- }
+static Property i8257_properties[] = {
+ DEFINE_PROP_INT32("base", I8257State, base, 0x00),
+ DEFINE_PROP_INT32("page-base", I8257State, page_base, 0x80),
+ DEFINE_PROP_INT32("pageh-base", I8257State, pageh_base, 0x480),
+ DEFINE_PROP_INT32("dshift", I8257State, dshift, 0),
+ DEFINE_PROP_END_OF_LIST()
};
-static int dma_post_load(void *opaque, int version_id)
+static void i8257_class_init(ObjectClass *klass, void *data)
{
- DMA_run();
-
- return 0;
+ DeviceClass *dc = DEVICE_CLASS(klass);
+ IsaDmaClass *idc = ISADMA_CLASS(klass);
+
+ dc->realize = i8257_realize;
+ dc->reset = i8257_reset;
+ dc->vmsd = &vmstate_i8257;
+ dc->props = i8257_properties;
+
+ idc->get_transfer_mode = i8257_dma_get_transfer_mode;
+ idc->has_autoinitialization = i8257_dma_has_autoinitialization;
+ idc->read_memory = i8257_dma_read_memory;
+ idc->write_memory = i8257_dma_write_memory;
+ idc->hold_DREQ = i8257_dma_hold_DREQ;
+ idc->release_DREQ = i8257_dma_release_DREQ;
+ idc->schedule = i8257_dma_schedule;
+ idc->register_channel = i8257_dma_register_channel;
}
-static const VMStateDescription vmstate_dma = {
- .name = "dma",
- .version_id = 1,
- .minimum_version_id = 1,
- .post_load = dma_post_load,
- .fields = (VMStateField[]) {
- VMSTATE_UINT8(command, struct dma_cont),
- VMSTATE_UINT8(mask, struct dma_cont),
- VMSTATE_UINT8(flip_flop, struct dma_cont),
- VMSTATE_INT32(dshift, struct dma_cont),
- VMSTATE_STRUCT_ARRAY(regs, struct dma_cont, 4, 1, vmstate_dma_regs, struct dma_regs),
- VMSTATE_END_OF_LIST()
+static const TypeInfo i8257_info = {
+ .name = TYPE_I8257,
+ .parent = TYPE_ISA_DEVICE,
+ .instance_size = sizeof(I8257State),
+ .class_init = i8257_class_init,
+ .interfaces = (InterfaceInfo[]) {
+ { TYPE_ISADMA },
+ { }
}
};
-void DMA_init(int high_page_enable)
+static void i8257_register_types(void)
{
- dma_init2(&dma_controllers[0], 0x00, 0, 0x80, high_page_enable ? 0x480 : -1);
- dma_init2(&dma_controllers[1], 0xc0, 1, 0x88, high_page_enable ? 0x488 : -1);
- vmstate_register (NULL, 0, &vmstate_dma, &dma_controllers[0]);
- vmstate_register (NULL, 1, &vmstate_dma, &dma_controllers[1]);
+ type_register_static(&i8257_info);
+}
+
+type_init(i8257_register_types)
- dma_bh = qemu_bh_new(DMA_run_bh, NULL);
+void DMA_init(ISABus *bus, int high_page_enable)
+{
+ ISADevice *isa1, *isa2;
+ DeviceState *d;
+
+ isa1 = isa_create(bus, TYPE_I8257);
+ d = DEVICE(isa1);
+ qdev_prop_set_int32(d, "base", 0x00);
+ qdev_prop_set_int32(d, "page-base", 0x80);
+ qdev_prop_set_int32(d, "pageh-base", high_page_enable ? 0x480 : -1);
+ qdev_prop_set_int32(d, "dshift", 0);
+ qdev_init_nofail(d);
+
+ isa2 = isa_create(bus, TYPE_I8257);
+ d = DEVICE(isa2);
+ qdev_prop_set_int32(d, "base", 0xc0);
+ qdev_prop_set_int32(d, "page-base", 0x88);
+ qdev_prop_set_int32(d, "pageh-base", high_page_enable ? 0x488 : -1);
+ qdev_prop_set_int32(d, "dshift", 1);
+ qdev_init_nofail(d);
+
+ isa_bus_dma(bus, ISADMA(isa1), ISADMA(isa2));
}
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index ce185bbee9..af2fe84ffb 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -1527,7 +1527,7 @@ void pc_basic_device_init(ISABus *isa_bus, qemu_irq *gsi,
port92 = isa_create_simple(isa_bus, "port92");
port92_init(port92, &a20_line[1]);
- DMA_init(0);
+ DMA_init(isa_bus, 0);
for(i = 0; i < MAX_FD; i++) {
fd[i] = drive_get(IF_FLOPPY, 0, i);
diff --git a/hw/intc/Makefile.objs b/hw/intc/Makefile.objs
index 004b0c25e4..6a13a39519 100644
--- a/hw/intc/Makefile.objs
+++ b/hw/intc/Makefile.objs
@@ -24,6 +24,7 @@ obj-$(CONFIG_GRLIB) += grlib_irqmp.o
obj-$(CONFIG_IOAPIC) += ioapic.o
obj-$(CONFIG_OMAP) += omap_intc.o
obj-$(CONFIG_OPENPIC_KVM) += openpic_kvm.o
+obj-$(CONFIG_RASPI) += bcm2835_ic.o bcm2836_control.o
obj-$(CONFIG_SH4) += sh_intc.o
obj-$(CONFIG_XICS) += xics.o
obj-$(CONFIG_XICS_KVM) += xics_kvm.o
diff --git a/hw/intc/bcm2835_ic.c b/hw/intc/bcm2835_ic.c
new file mode 100644
index 0000000000..005a72b1e2
--- /dev/null
+++ b/hw/intc/bcm2835_ic.c
@@ -0,0 +1,236 @@
+/*
+ * Raspberry Pi emulation (c) 2012 Gregory Estrade
+ * Refactoring for Pi2 Copyright (c) 2015, Microsoft. Written by Andrew Baumann.
+ * This code is licensed under the GNU GPLv2 and later.
+ * Heavily based on pl190.c, copyright terms below:
+ *
+ * Arm PrimeCell PL190 Vector Interrupt Controller
+ *
+ * Copyright (c) 2006 CodeSourcery.
+ * Written by Paul Brook
+ *
+ * This code is licensed under the GPL.
+ */
+
+#include "hw/intc/bcm2835_ic.h"
+
+#define GPU_IRQS 64
+#define ARM_IRQS 8
+
+#define IRQ_PENDING_BASIC 0x00 /* IRQ basic pending */
+#define IRQ_PENDING_1 0x04 /* IRQ pending 1 */
+#define IRQ_PENDING_2 0x08 /* IRQ pending 2 */
+#define FIQ_CONTROL 0x0C /* FIQ register */
+#define IRQ_ENABLE_1 0x10 /* Interrupt enable register 1 */
+#define IRQ_ENABLE_2 0x14 /* Interrupt enable register 2 */
+#define IRQ_ENABLE_BASIC 0x18 /* Base interrupt enable register */
+#define IRQ_DISABLE_1 0x1C /* Interrupt disable register 1 */
+#define IRQ_DISABLE_2 0x20 /* Interrupt disable register 2 */
+#define IRQ_DISABLE_BASIC 0x24 /* Base interrupt disable register */
+
+/* Update interrupts. */
+static void bcm2835_ic_update(BCM2835ICState *s)
+{
+ bool set = false;
+
+ if (s->fiq_enable) {
+ if (s->fiq_select >= GPU_IRQS) {
+ /* ARM IRQ */
+ set = extract32(s->arm_irq_level, s->fiq_select - GPU_IRQS, 1);
+ } else {
+ set = extract64(s->gpu_irq_level, s->fiq_select, 1);
+ }
+ }
+ qemu_set_irq(s->fiq, set);
+
+ set = (s->gpu_irq_level & s->gpu_irq_enable)
+ || (s->arm_irq_level & s->arm_irq_enable);
+ qemu_set_irq(s->irq, set);
+
+}
+
+static void bcm2835_ic_set_gpu_irq(void *opaque, int irq, int level)
+{
+ BCM2835ICState *s = opaque;
+
+ assert(irq >= 0 && irq < 64);
+ s->gpu_irq_level = deposit64(s->gpu_irq_level, irq, 1, level != 0);
+ bcm2835_ic_update(s);
+}
+
+static void bcm2835_ic_set_arm_irq(void *opaque, int irq, int level)
+{
+ BCM2835ICState *s = opaque;
+
+ assert(irq >= 0 && irq < 8);
+ s->arm_irq_level = deposit32(s->arm_irq_level, irq, 1, level != 0);
+ bcm2835_ic_update(s);
+}
+
+static const int irq_dups[] = { 7, 9, 10, 18, 19, 53, 54, 55, 56, 57, 62 };
+
+static uint64_t bcm2835_ic_read(void *opaque, hwaddr offset, unsigned size)
+{
+ BCM2835ICState *s = opaque;
+ uint32_t res = 0;
+ uint64_t gpu_pending = s->gpu_irq_level & s->gpu_irq_enable;
+ int i;
+
+ switch (offset) {
+ case IRQ_PENDING_BASIC:
+ /* bits 0-7: ARM irqs */
+ res = s->arm_irq_level & s->arm_irq_enable;
+
+ /* bits 8 & 9: pending registers 1 & 2 */
+ res |= (((uint32_t)gpu_pending) != 0) << 8;
+ res |= ((gpu_pending >> 32) != 0) << 9;
+
+ /* bits 10-20: selected GPU IRQs */
+ for (i = 0; i < ARRAY_SIZE(irq_dups); i++) {
+ res |= extract64(gpu_pending, irq_dups[i], 1) << (i + 10);
+ }
+ break;
+ case IRQ_PENDING_1:
+ res = gpu_pending;
+ break;
+ case IRQ_PENDING_2:
+ res = gpu_pending >> 32;
+ break;
+ case FIQ_CONTROL:
+ res = (s->fiq_enable << 7) | s->fiq_select;
+ break;
+ case IRQ_ENABLE_1:
+ res = s->gpu_irq_enable;
+ break;
+ case IRQ_ENABLE_2:
+ res = s->gpu_irq_enable >> 32;
+ break;
+ case IRQ_ENABLE_BASIC:
+ res = s->arm_irq_enable;
+ break;
+ case IRQ_DISABLE_1:
+ res = ~s->gpu_irq_enable;
+ break;
+ case IRQ_DISABLE_2:
+ res = ~s->gpu_irq_enable >> 32;
+ break;
+ case IRQ_DISABLE_BASIC:
+ res = ~s->arm_irq_enable;
+ break;
+ default:
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset %"HWADDR_PRIx"\n",
+ __func__, offset);
+ return 0;
+ }
+
+ return res;
+}
+
+static void bcm2835_ic_write(void *opaque, hwaddr offset, uint64_t val,
+ unsigned size)
+{
+ BCM2835ICState *s = opaque;
+
+ switch (offset) {
+ case FIQ_CONTROL:
+ s->fiq_select = extract32(val, 0, 7);
+ s->fiq_enable = extract32(val, 7, 1);
+ break;
+ case IRQ_ENABLE_1:
+ s->gpu_irq_enable |= val;
+ break;
+ case IRQ_ENABLE_2:
+ s->gpu_irq_enable |= val << 32;
+ break;
+ case IRQ_ENABLE_BASIC:
+ s->arm_irq_enable |= val & 0xff;
+ break;
+ case IRQ_DISABLE_1:
+ s->gpu_irq_enable &= ~val;
+ break;
+ case IRQ_DISABLE_2:
+ s->gpu_irq_enable &= ~(val << 32);
+ break;
+ case IRQ_DISABLE_BASIC:
+ s->arm_irq_enable &= ~val & 0xff;
+ break;
+ default:
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset %"HWADDR_PRIx"\n",
+ __func__, offset);
+ return;
+ }
+ bcm2835_ic_update(s);
+}
+
+static const MemoryRegionOps bcm2835_ic_ops = {
+ .read = bcm2835_ic_read,
+ .write = bcm2835_ic_write,
+ .endianness = DEVICE_NATIVE_ENDIAN,
+ .valid.min_access_size = 4,
+ .valid.max_access_size = 4,
+};
+
+static void bcm2835_ic_reset(DeviceState *d)
+{
+ BCM2835ICState *s = BCM2835_IC(d);
+
+ s->gpu_irq_enable = 0;
+ s->arm_irq_enable = 0;
+ s->fiq_enable = false;
+ s->fiq_select = 0;
+}
+
+static void bcm2835_ic_init(Object *obj)
+{
+ BCM2835ICState *s = BCM2835_IC(obj);
+
+ memory_region_init_io(&s->iomem, obj, &bcm2835_ic_ops, s, TYPE_BCM2835_IC,
+ 0x200);
+ sysbus_init_mmio(SYS_BUS_DEVICE(s), &s->iomem);
+
+ qdev_init_gpio_in_named(DEVICE(s), bcm2835_ic_set_gpu_irq,
+ BCM2835_IC_GPU_IRQ, GPU_IRQS);
+ qdev_init_gpio_in_named(DEVICE(s), bcm2835_ic_set_arm_irq,
+ BCM2835_IC_ARM_IRQ, ARM_IRQS);
+
+ sysbus_init_irq(SYS_BUS_DEVICE(s), &s->irq);
+ sysbus_init_irq(SYS_BUS_DEVICE(s), &s->fiq);
+}
+
+static const VMStateDescription vmstate_bcm2835_ic = {
+ .name = TYPE_BCM2835_IC,
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .fields = (VMStateField[]) {
+ VMSTATE_UINT64(gpu_irq_level, BCM2835ICState),
+ VMSTATE_UINT64(gpu_irq_enable, BCM2835ICState),
+ VMSTATE_UINT8(arm_irq_level, BCM2835ICState),
+ VMSTATE_UINT8(arm_irq_enable, BCM2835ICState),
+ VMSTATE_BOOL(fiq_enable, BCM2835ICState),
+ VMSTATE_UINT8(fiq_select, BCM2835ICState),
+ VMSTATE_END_OF_LIST()
+ }
+};
+
+static void bcm2835_ic_class_init(ObjectClass *klass, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(klass);
+
+ dc->reset = bcm2835_ic_reset;
+ dc->vmsd = &vmstate_bcm2835_ic;
+}
+
+static TypeInfo bcm2835_ic_info = {
+ .name = TYPE_BCM2835_IC,
+ .parent = TYPE_SYS_BUS_DEVICE,
+ .instance_size = sizeof(BCM2835ICState),
+ .class_init = bcm2835_ic_class_init,
+ .instance_init = bcm2835_ic_init,
+};
+
+static void bcm2835_ic_register_types(void)
+{
+ type_register_static(&bcm2835_ic_info);
+}
+
+type_init(bcm2835_ic_register_types)
diff --git a/hw/intc/bcm2836_control.c b/hw/intc/bcm2836_control.c
new file mode 100644
index 0000000000..ad622aa99f
--- /dev/null
+++ b/hw/intc/bcm2836_control.c
@@ -0,0 +1,303 @@
+/*
+ * Rasperry Pi 2 emulation ARM control logic module.
+ * Copyright (c) 2015, Microsoft
+ * Written by Andrew Baumann
+ *
+ * Based on bcm2835_ic.c (Raspberry Pi emulation) (c) 2012 Gregory Estrade
+ * This code is licensed under the GNU GPLv2 and later.
+ *
+ * At present, only implements interrupt routing, and mailboxes (i.e.,
+ * not local timer, PMU interrupt, or AXI counters).
+ *
+ * Ref:
+ * https://www.raspberrypi.org/documentation/hardware/raspberrypi/bcm2836/QA7_rev3.4.pdf
+ */
+
+#include "hw/intc/bcm2836_control.h"
+
+#define REG_GPU_ROUTE 0x0c
+#define REG_TIMERCONTROL 0x40
+#define REG_MBOXCONTROL 0x50
+#define REG_IRQSRC 0x60
+#define REG_FIQSRC 0x70
+#define REG_MBOX0_WR 0x80
+#define REG_MBOX0_RDCLR 0xc0
+#define REG_LIMIT 0x100
+
+#define IRQ_BIT(cntrl, num) (((cntrl) & (1 << (num))) != 0)
+#define FIQ_BIT(cntrl, num) (((cntrl) & (1 << ((num) + 4))) != 0)
+
+#define IRQ_CNTPSIRQ 0
+#define IRQ_CNTPNSIRQ 1
+#define IRQ_CNTHPIRQ 2
+#define IRQ_CNTVIRQ 3
+#define IRQ_MAILBOX0 4
+#define IRQ_MAILBOX1 5
+#define IRQ_MAILBOX2 6
+#define IRQ_MAILBOX3 7
+#define IRQ_GPU 8
+#define IRQ_PMU 9
+#define IRQ_AXI 10
+#define IRQ_TIMER 11
+#define IRQ_MAX IRQ_TIMER
+
+static void deliver_local(BCM2836ControlState *s, uint8_t core, uint8_t irq,
+ uint32_t controlreg, uint8_t controlidx)
+{
+ if (FIQ_BIT(controlreg, controlidx)) {
+ /* deliver a FIQ */
+ s->fiqsrc[core] |= (uint32_t)1 << irq;
+ } else if (IRQ_BIT(controlreg, controlidx)) {
+ /* deliver an IRQ */
+ s->irqsrc[core] |= (uint32_t)1 << irq;
+ } else {
+ /* the interrupt is masked */
+ }
+}
+
+/* Update interrupts. */
+static void bcm2836_control_update(BCM2836ControlState *s)
+{
+ int i, j;
+
+ /* reset pending IRQs/FIQs */
+ for (i = 0; i < BCM2836_NCORES; i++) {
+ s->irqsrc[i] = s->fiqsrc[i] = 0;
+ }
+
+ /* apply routing logic, update status regs */
+ if (s->gpu_irq) {
+ assert(s->route_gpu_irq < BCM2836_NCORES);
+ s->irqsrc[s->route_gpu_irq] |= (uint32_t)1 << IRQ_GPU;
+ }
+
+ if (s->gpu_fiq) {
+ assert(s->route_gpu_fiq < BCM2836_NCORES);
+ s->fiqsrc[s->route_gpu_fiq] |= (uint32_t)1 << IRQ_GPU;
+ }
+
+ for (i = 0; i < BCM2836_NCORES; i++) {
+ /* handle local timer interrupts for this core */
+ if (s->timerirqs[i]) {
+ assert(s->timerirqs[i] < (1 << (IRQ_CNTVIRQ + 1))); /* sane mask? */
+ for (j = 0; j <= IRQ_CNTVIRQ; j++) {
+ if ((s->timerirqs[i] & (1 << j)) != 0) {
+ /* local interrupt j is set */
+ deliver_local(s, i, j, s->timercontrol[i], j);
+ }
+ }
+ }
+
+ /* handle mailboxes for this core */
+ for (j = 0; j < BCM2836_MBPERCORE; j++) {
+ if (s->mailboxes[i * BCM2836_MBPERCORE + j] != 0) {
+ /* mailbox j is set */
+ deliver_local(s, i, j + IRQ_MAILBOX0, s->mailboxcontrol[i], j);
+ }
+ }
+ }
+
+ /* call set_irq appropriately for each output */
+ for (i = 0; i < BCM2836_NCORES; i++) {
+ qemu_set_irq(s->irq[i], s->irqsrc[i] != 0);
+ qemu_set_irq(s->fiq[i], s->fiqsrc[i] != 0);
+ }
+}
+
+static void bcm2836_control_set_local_irq(void *opaque, int core, int local_irq,
+ int level)
+{
+ BCM2836ControlState *s = opaque;
+
+ assert(core >= 0 && core < BCM2836_NCORES);
+ assert(local_irq >= 0 && local_irq <= IRQ_CNTVIRQ);
+
+ s->timerirqs[core] = deposit32(s->timerirqs[core], local_irq, 1, !!level);
+
+ bcm2836_control_update(s);
+}
+
+/* XXX: the following wrapper functions are a kludgy workaround,
+ * needed because I can't seem to pass useful information in the "irq"
+ * parameter when using named interrupts. Feel free to clean this up!
+ */
+
+static void bcm2836_control_set_local_irq0(void *opaque, int core, int level)
+{
+ bcm2836_control_set_local_irq(opaque, core, 0, level);
+}
+
+static void bcm2836_control_set_local_irq1(void *opaque, int core, int level)
+{
+ bcm2836_control_set_local_irq(opaque, core, 1, level);
+}
+
+static void bcm2836_control_set_local_irq2(void *opaque, int core, int level)
+{
+ bcm2836_control_set_local_irq(opaque, core, 2, level);
+}
+
+static void bcm2836_control_set_local_irq3(void *opaque, int core, int level)
+{
+ bcm2836_control_set_local_irq(opaque, core, 3, level);
+}
+
+static void bcm2836_control_set_gpu_irq(void *opaque, int irq, int level)
+{
+ BCM2836ControlState *s = opaque;
+
+ s->gpu_irq = level;
+
+ bcm2836_control_update(s);
+}
+
+static void bcm2836_control_set_gpu_fiq(void *opaque, int irq, int level)
+{
+ BCM2836ControlState *s = opaque;
+
+ s->gpu_fiq = level;
+
+ bcm2836_control_update(s);
+}
+
+static uint64_t bcm2836_control_read(void *opaque, hwaddr offset, unsigned size)
+{
+ BCM2836ControlState *s = opaque;
+
+ if (offset == REG_GPU_ROUTE) {
+ assert(s->route_gpu_fiq < BCM2836_NCORES
+ && s->route_gpu_irq < BCM2836_NCORES);
+ return ((uint32_t)s->route_gpu_fiq << 2) | s->route_gpu_irq;
+ } else if (offset >= REG_TIMERCONTROL && offset < REG_MBOXCONTROL) {
+ return s->timercontrol[(offset - REG_TIMERCONTROL) >> 2];
+ } else if (offset >= REG_MBOXCONTROL && offset < REG_IRQSRC) {
+ return s->mailboxcontrol[(offset - REG_MBOXCONTROL) >> 2];
+ } else if (offset >= REG_IRQSRC && offset < REG_FIQSRC) {
+ return s->irqsrc[(offset - REG_IRQSRC) >> 2];
+ } else if (offset >= REG_FIQSRC && offset < REG_MBOX0_WR) {
+ return s->fiqsrc[(offset - REG_FIQSRC) >> 2];
+ } else if (offset >= REG_MBOX0_RDCLR && offset < REG_LIMIT) {
+ return s->mailboxes[(offset - REG_MBOX0_RDCLR) >> 2];
+ } else {
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset %"HWADDR_PRIx"\n",
+ __func__, offset);
+ return 0;
+ }
+}
+
+static void bcm2836_control_write(void *opaque, hwaddr offset,
+ uint64_t val, unsigned size)
+{
+ BCM2836ControlState *s = opaque;
+
+ if (offset == REG_GPU_ROUTE) {
+ s->route_gpu_irq = val & 0x3;
+ s->route_gpu_fiq = (val >> 2) & 0x3;
+ } else if (offset >= REG_TIMERCONTROL && offset < REG_MBOXCONTROL) {
+ s->timercontrol[(offset - REG_TIMERCONTROL) >> 2] = val & 0xff;
+ } else if (offset >= REG_MBOXCONTROL && offset < REG_IRQSRC) {
+ s->mailboxcontrol[(offset - REG_MBOXCONTROL) >> 2] = val & 0xff;
+ } else if (offset >= REG_MBOX0_WR && offset < REG_MBOX0_RDCLR) {
+ s->mailboxes[(offset - REG_MBOX0_WR) >> 2] |= val;
+ } else if (offset >= REG_MBOX0_RDCLR && offset < REG_LIMIT) {
+ s->mailboxes[(offset - REG_MBOX0_RDCLR) >> 2] &= ~val;
+ } else {
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset %"HWADDR_PRIx"\n",
+ __func__, offset);
+ return;
+ }
+
+ bcm2836_control_update(s);
+}
+
+static const MemoryRegionOps bcm2836_control_ops = {
+ .read = bcm2836_control_read,
+ .write = bcm2836_control_write,
+ .endianness = DEVICE_NATIVE_ENDIAN,
+ .valid.min_access_size = 4,
+ .valid.max_access_size = 4,
+};
+
+static void bcm2836_control_reset(DeviceState *d)
+{
+ BCM2836ControlState *s = BCM2836_CONTROL(d);
+ int i;
+
+ s->route_gpu_irq = s->route_gpu_fiq = 0;
+
+ for (i = 0; i < BCM2836_NCORES; i++) {
+ s->timercontrol[i] = 0;
+ s->mailboxcontrol[i] = 0;
+ }
+
+ for (i = 0; i < BCM2836_NCORES * BCM2836_MBPERCORE; i++) {
+ s->mailboxes[i] = 0;
+ }
+}
+
+static void bcm2836_control_init(Object *obj)
+{
+ BCM2836ControlState *s = BCM2836_CONTROL(obj);
+ DeviceState *dev = DEVICE(obj);
+
+ memory_region_init_io(&s->iomem, obj, &bcm2836_control_ops, s,
+ TYPE_BCM2836_CONTROL, REG_LIMIT);
+ sysbus_init_mmio(SYS_BUS_DEVICE(s), &s->iomem);
+
+ /* inputs from each CPU core */
+ qdev_init_gpio_in_named(dev, bcm2836_control_set_local_irq0, "cntpsirq",
+ BCM2836_NCORES);
+ qdev_init_gpio_in_named(dev, bcm2836_control_set_local_irq1, "cntpnsirq",
+ BCM2836_NCORES);
+ qdev_init_gpio_in_named(dev, bcm2836_control_set_local_irq2, "cnthpirq",
+ BCM2836_NCORES);
+ qdev_init_gpio_in_named(dev, bcm2836_control_set_local_irq3, "cntvirq",
+ BCM2836_NCORES);
+
+ /* IRQ and FIQ inputs from upstream bcm2835 controller */
+ qdev_init_gpio_in_named(dev, bcm2836_control_set_gpu_irq, "gpu-irq", 1);
+ qdev_init_gpio_in_named(dev, bcm2836_control_set_gpu_fiq, "gpu-fiq", 1);
+
+ /* outputs to CPU cores */
+ qdev_init_gpio_out_named(dev, s->irq, "irq", BCM2836_NCORES);
+ qdev_init_gpio_out_named(dev, s->fiq, "fiq", BCM2836_NCORES);
+}
+
+static const VMStateDescription vmstate_bcm2836_control = {
+ .name = TYPE_BCM2836_CONTROL,
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .fields = (VMStateField[]) {
+ VMSTATE_UINT32_ARRAY(mailboxes, BCM2836ControlState,
+ BCM2836_NCORES * BCM2836_MBPERCORE),
+ VMSTATE_UINT8(route_gpu_irq, BCM2836ControlState),
+ VMSTATE_UINT8(route_gpu_fiq, BCM2836ControlState),
+ VMSTATE_UINT32_ARRAY(timercontrol, BCM2836ControlState, BCM2836_NCORES),
+ VMSTATE_UINT32_ARRAY(mailboxcontrol, BCM2836ControlState,
+ BCM2836_NCORES),
+ VMSTATE_END_OF_LIST()
+ }
+};
+
+static void bcm2836_control_class_init(ObjectClass *klass, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(klass);
+
+ dc->reset = bcm2836_control_reset;
+ dc->vmsd = &vmstate_bcm2836_control;
+}
+
+static TypeInfo bcm2836_control_info = {
+ .name = TYPE_BCM2836_CONTROL,
+ .parent = TYPE_SYS_BUS_DEVICE,
+ .instance_size = sizeof(BCM2836ControlState),
+ .class_init = bcm2836_control_class_init,
+ .instance_init = bcm2836_control_init,
+};
+
+static void bcm2836_control_register_types(void)
+{
+ type_register_static(&bcm2836_control_info);
+}
+
+type_init(bcm2836_control_register_types)
diff --git a/hw/isa/isa-bus.c b/hw/isa/isa-bus.c
index b487cb1839..c3b7388529 100644
--- a/hw/isa/isa-bus.c
+++ b/hw/isa/isa-bus.c
@@ -37,6 +37,12 @@ static void isa_bus_class_init(ObjectClass *klass, void *data)
k->get_fw_dev_path = isabus_get_fw_dev_path;
}
+static const TypeInfo isa_dma_info = {
+ .name = TYPE_ISADMA,
+ .parent = TYPE_INTERFACE,
+ .class_size = sizeof(IsaDmaClass),
+};
+
static const TypeInfo isa_bus_info = {
.name = TYPE_ISA_BUS,
.parent = TYPE_BUS,
@@ -90,6 +96,20 @@ void isa_init_irq(ISADevice *dev, qemu_irq *p, int isairq)
dev->nirqs++;
}
+void isa_bus_dma(ISABus *bus, IsaDma *dma8, IsaDma *dma16)
+{
+ assert(bus && dma8 && dma16);
+ assert(!bus->dma[0] && !bus->dma[1]);
+ bus->dma[0] = dma8;
+ bus->dma[1] = dma16;
+}
+
+IsaDma *isa_get_dma(ISABus *bus, int nchan)
+{
+ assert(bus);
+ return bus->dma[nchan > 3 ? 1 : 0];
+}
+
static inline void isa_init_ioport(ISADevice *dev, uint16_t ioport)
{
if (dev && (dev->ioport_id == 0 || ioport < dev->ioport_id)) {
@@ -223,6 +243,7 @@ static const TypeInfo isa_device_type_info = {
static void isabus_register_types(void)
{
+ type_register_static(&isa_dma_info);
type_register_static(&isa_bus_info);
type_register_static(&isabus_bridge_info);
type_register_static(&isa_device_type_info);
diff --git a/hw/mips/mips_fulong2e.c b/hw/mips/mips_fulong2e.c
index 6748d89478..184c404454 100644
--- a/hw/mips/mips_fulong2e.c
+++ b/hw/mips/mips_fulong2e.c
@@ -366,7 +366,7 @@ static void mips_fulong2e_init(MachineState *machine)
/* init other devices */
pit = pit_init(isa_bus, 0x40, 0, NULL);
- DMA_init(0);
+ DMA_init(isa_bus, 0);
/* Super I/O */
isa_create_simple(isa_bus, "i8042");
diff --git a/hw/mips/mips_jazz.c b/hw/mips/mips_jazz.c
index 62527fdbe8..d6d8058602 100644
--- a/hw/mips/mips_jazz.c
+++ b/hw/mips/mips_jazz.c
@@ -225,7 +225,7 @@ static void mips_jazz_init(MachineState *machine,
/* ISA devices */
i8259 = i8259_init(isa_bus, env->irq[4]);
isa_bus_irqs(isa_bus, i8259);
- DMA_init(0);
+ DMA_init(isa_bus, 0);
pit = pit_init(isa_bus, 0x40, 0, NULL);
pcspk_init(isa_bus, pit);
@@ -297,7 +297,8 @@ static void mips_jazz_init(MachineState *machine,
for (n = 0; n < MAX_FD; n++) {
fds[n] = drive_get(IF_FLOPPY, 0, n);
}
- fdctrl_init_sysbus(qdev_get_gpio_in(rc4030, 1), 0, 0x80003000, fds);
+ /* FIXME: we should enable DMA with a custom IsaDma device */
+ fdctrl_init_sysbus(qdev_get_gpio_in(rc4030, 1), -1, 0x80003000, fds);
/* Real time clock */
rtc_init(isa_bus, 1980, NULL);
diff --git a/hw/mips/mips_malta.c b/hw/mips/mips_malta.c
index c5da83fde8..c04aa2b8cc 100644
--- a/hw/mips/mips_malta.c
+++ b/hw/mips/mips_malta.c
@@ -1166,7 +1166,7 @@ void mips_malta_init(MachineState *machine)
smbus_eeprom_init(smbus, 8, smbus_eeprom_buf, smbus_eeprom_size);
g_free(smbus_eeprom_buf);
pit = pit_init(isa_bus, 0x40, 0, NULL);
- DMA_init(0);
+ DMA_init(isa_bus, 0);
/* Super I/O */
isa_create_simple(isa_bus, "i8042");
diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
index d4765c2516..ea6cd3c9ff 100644
--- a/hw/misc/Makefile.objs
+++ b/hw/misc/Makefile.objs
@@ -36,6 +36,8 @@ obj-$(CONFIG_OMAP) += omap_gpmc.o
obj-$(CONFIG_OMAP) += omap_l4.o
obj-$(CONFIG_OMAP) += omap_sdrc.o
obj-$(CONFIG_OMAP) += omap_tap.o
+obj-$(CONFIG_RASPI) += bcm2835_mbox.o
+obj-$(CONFIG_RASPI) += bcm2835_property.o
obj-$(CONFIG_SLAVIO) += slavio_misc.o
obj-$(CONFIG_ZYNQ) += zynq_slcr.o
obj-$(CONFIG_ZYNQ) += zynq-xadc.o
diff --git a/hw/misc/bcm2835_mbox.c b/hw/misc/bcm2835_mbox.c
new file mode 100644
index 0000000000..df1d6e6ad6
--- /dev/null
+++ b/hw/misc/bcm2835_mbox.c
@@ -0,0 +1,333 @@
+/*
+ * Raspberry Pi emulation (c) 2012 Gregory Estrade
+ * This code is licensed under the GNU GPLv2 and later.
+ *
+ * This file models the system mailboxes, which are used for
+ * communication with low-bandwidth GPU peripherals. Refs:
+ * https://github.com/raspberrypi/firmware/wiki/Mailboxes
+ * https://github.com/raspberrypi/firmware/wiki/Accessing-mailboxes
+ */
+
+#include "hw/misc/bcm2835_mbox.h"
+
+#define MAIL0_PEEK 0x90
+#define MAIL0_SENDER 0x94
+#define MAIL1_STATUS 0xb8
+
+/* Mailbox status register */
+#define MAIL0_STATUS 0x98
+#define ARM_MS_FULL 0x80000000
+#define ARM_MS_EMPTY 0x40000000
+#define ARM_MS_LEVEL 0x400000FF /* Max. value depends on mailbox depth */
+
+/* MAILBOX config/status register */
+#define MAIL0_CONFIG 0x9c
+/* ANY write to this register clears the error bits! */
+#define ARM_MC_IHAVEDATAIRQEN 0x00000001 /* mbox irq enable: has data */
+#define ARM_MC_IHAVESPACEIRQEN 0x00000002 /* mbox irq enable: has space */
+#define ARM_MC_OPPISEMPTYIRQEN 0x00000004 /* mbox irq enable: Opp is empty */
+#define ARM_MC_MAIL_CLEAR 0x00000008 /* mbox clear write 1, then 0 */
+#define ARM_MC_IHAVEDATAIRQPEND 0x00000010 /* mbox irq pending: has space */
+#define ARM_MC_IHAVESPACEIRQPEND 0x00000020 /* mbox irq pending: Opp is empty */
+#define ARM_MC_OPPISEMPTYIRQPEND 0x00000040 /* mbox irq pending */
+/* Bit 7 is unused */
+#define ARM_MC_ERRNOOWN 0x00000100 /* error : none owner read from mailbox */
+#define ARM_MC_ERROVERFLW 0x00000200 /* error : write to fill mailbox */
+#define ARM_MC_ERRUNDRFLW 0x00000400 /* error : read from empty mailbox */
+
+static void mbox_update_status(BCM2835Mbox *mb)
+{
+ mb->status &= ~(ARM_MS_EMPTY | ARM_MS_FULL);
+ if (mb->count == 0) {
+ mb->status |= ARM_MS_EMPTY;
+ } else if (mb->count == MBOX_SIZE) {
+ mb->status |= ARM_MS_FULL;
+ }
+}
+
+static void mbox_reset(BCM2835Mbox *mb)
+{
+ int n;
+
+ mb->count = 0;
+ mb->config = 0;
+ for (n = 0; n < MBOX_SIZE; n++) {
+ mb->reg[n] = MBOX_INVALID_DATA;
+ }
+ mbox_update_status(mb);
+}
+
+static uint32_t mbox_pull(BCM2835Mbox *mb, int index)
+{
+ int n;
+ uint32_t val;
+
+ assert(mb->count > 0);
+ assert(index < mb->count);
+
+ val = mb->reg[index];
+ for (n = index + 1; n < mb->count; n++) {
+ mb->reg[n - 1] = mb->reg[n];
+ }
+ mb->count--;
+ mb->reg[mb->count] = MBOX_INVALID_DATA;
+
+ mbox_update_status(mb);
+
+ return val;
+}
+
+static void mbox_push(BCM2835Mbox *mb, uint32_t val)
+{
+ assert(mb->count < MBOX_SIZE);
+ mb->reg[mb->count++] = val;
+ mbox_update_status(mb);
+}
+
+static void bcm2835_mbox_update(BCM2835MboxState *s)
+{
+ uint32_t value;
+ bool set;
+ int n;
+
+ s->mbox_irq_disabled = true;
+
+ /* Get pending responses and put them in the vc->arm mbox,
+ * as long as it's not full
+ */
+ for (n = 0; n < MBOX_CHAN_COUNT; n++) {
+ while (s->available[n] && !(s->mbox[0].status & ARM_MS_FULL)) {
+ value = ldl_phys(&s->mbox_as, n << MBOX_AS_CHAN_SHIFT);
+ assert(value != MBOX_INVALID_DATA); /* Pending interrupt but no data */
+ mbox_push(&s->mbox[0], value);
+ }
+ }
+
+ /* TODO (?): Try to push pending requests from the arm->vc mbox */
+
+ /* Re-enable calls from the IRQ routine */
+ s->mbox_irq_disabled = false;
+
+ /* Update ARM IRQ status */
+ set = false;
+ s->mbox[0].config &= ~ARM_MC_IHAVEDATAIRQPEND;
+ if (!(s->mbox[0].status & ARM_MS_EMPTY)) {
+ s->mbox[0].config |= ARM_MC_IHAVEDATAIRQPEND;
+ if (s->mbox[0].config & ARM_MC_IHAVEDATAIRQEN) {
+ set = true;
+ }
+ }
+ qemu_set_irq(s->arm_irq, set);
+}
+
+static void bcm2835_mbox_set_irq(void *opaque, int irq, int level)
+{
+ BCM2835MboxState *s = opaque;
+
+ s->available[irq] = level;
+
+ /* avoid recursively calling bcm2835_mbox_update when the interrupt
+ * status changes due to the ldl_phys call within that function
+ */
+ if (!s->mbox_irq_disabled) {
+ bcm2835_mbox_update(s);
+ }
+}
+
+static uint64_t bcm2835_mbox_read(void *opaque, hwaddr offset, unsigned size)
+{
+ BCM2835MboxState *s = opaque;
+ uint32_t res = 0;
+
+ offset &= 0xff;
+
+ switch (offset) {
+ case 0x80 ... 0x8c: /* MAIL0_READ */
+ if (s->mbox[0].status & ARM_MS_EMPTY) {
+ res = MBOX_INVALID_DATA;
+ } else {
+ res = mbox_pull(&s->mbox[0], 0);
+ }
+ break;
+
+ case MAIL0_PEEK:
+ res = s->mbox[0].reg[0];
+ break;
+
+ case MAIL0_SENDER:
+ break;
+
+ case MAIL0_STATUS:
+ res = s->mbox[0].status;
+ break;
+
+ case MAIL0_CONFIG:
+ res = s->mbox[0].config;
+ break;
+
+ case MAIL1_STATUS:
+ res = s->mbox[1].status;
+ break;
+
+ default:
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset %"HWADDR_PRIx"\n",
+ __func__, offset);
+ return 0;
+ }
+
+ bcm2835_mbox_update(s);
+
+ return res;
+}
+
+static void bcm2835_mbox_write(void *opaque, hwaddr offset,
+ uint64_t value, unsigned size)
+{
+ BCM2835MboxState *s = opaque;
+ hwaddr childaddr;
+ uint8_t ch;
+
+ offset &= 0xff;
+
+ switch (offset) {
+ case MAIL0_SENDER:
+ break;
+
+ case MAIL0_CONFIG:
+ s->mbox[0].config &= ~ARM_MC_IHAVEDATAIRQEN;
+ s->mbox[0].config |= value & ARM_MC_IHAVEDATAIRQEN;
+ break;
+
+ case 0xa0 ... 0xac: /* MAIL1_WRITE */
+ if (s->mbox[1].status & ARM_MS_FULL) {
+ /* Mailbox full */
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: mailbox full\n", __func__);
+ } else {
+ ch = value & 0xf;
+ if (ch < MBOX_CHAN_COUNT) {
+ childaddr = ch << MBOX_AS_CHAN_SHIFT;
+ if (ldl_phys(&s->mbox_as, childaddr + MBOX_AS_PENDING)) {
+ /* Child busy, push delayed. Push it in the arm->vc mbox */
+ mbox_push(&s->mbox[1], value);
+ } else {
+ /* Push it directly to the child device */
+ stl_phys(&s->mbox_as, childaddr, value);
+ }
+ } else {
+ /* Invalid channel number */
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: invalid channel %u\n",
+ __func__, ch);
+ }
+ }
+ break;
+
+ default:
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset %"HWADDR_PRIx"\n",
+ __func__, offset);
+ return;
+ }
+
+ bcm2835_mbox_update(s);
+}
+
+static const MemoryRegionOps bcm2835_mbox_ops = {
+ .read = bcm2835_mbox_read,
+ .write = bcm2835_mbox_write,
+ .endianness = DEVICE_NATIVE_ENDIAN,
+ .valid.min_access_size = 4,
+ .valid.max_access_size = 4,
+};
+
+/* vmstate of a single mailbox */
+static const VMStateDescription vmstate_bcm2835_mbox_box = {
+ .name = TYPE_BCM2835_MBOX "_box",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .fields = (VMStateField[]) {
+ VMSTATE_UINT32_ARRAY(reg, BCM2835Mbox, MBOX_SIZE),
+ VMSTATE_UINT32(count, BCM2835Mbox),
+ VMSTATE_UINT32(status, BCM2835Mbox),
+ VMSTATE_UINT32(config, BCM2835Mbox),
+ VMSTATE_END_OF_LIST()
+ }
+};
+
+/* vmstate of the entire device */
+static const VMStateDescription vmstate_bcm2835_mbox = {
+ .name = TYPE_BCM2835_MBOX,
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .minimum_version_id_old = 1,
+ .fields = (VMStateField[]) {
+ VMSTATE_BOOL_ARRAY(available, BCM2835MboxState, MBOX_CHAN_COUNT),
+ VMSTATE_STRUCT_ARRAY(mbox, BCM2835MboxState, 2, 1,
+ vmstate_bcm2835_mbox_box, BCM2835Mbox),
+ VMSTATE_END_OF_LIST()
+ }
+};
+
+static void bcm2835_mbox_init(Object *obj)
+{
+ BCM2835MboxState *s = BCM2835_MBOX(obj);
+
+ memory_region_init_io(&s->iomem, obj, &bcm2835_mbox_ops, s,
+ TYPE_BCM2835_MBOX, 0x400);
+ sysbus_init_mmio(SYS_BUS_DEVICE(s), &s->iomem);
+ sysbus_init_irq(SYS_BUS_DEVICE(s), &s->arm_irq);
+ qdev_init_gpio_in(DEVICE(s), bcm2835_mbox_set_irq, MBOX_CHAN_COUNT);
+}
+
+static void bcm2835_mbox_reset(DeviceState *dev)
+{
+ BCM2835MboxState *s = BCM2835_MBOX(dev);
+ int n;
+
+ mbox_reset(&s->mbox[0]);
+ mbox_reset(&s->mbox[1]);
+ s->mbox_irq_disabled = false;
+ for (n = 0; n < MBOX_CHAN_COUNT; n++) {
+ s->available[n] = false;
+ }
+}
+
+static void bcm2835_mbox_realize(DeviceState *dev, Error **errp)
+{
+ BCM2835MboxState *s = BCM2835_MBOX(dev);
+ Object *obj;
+ Error *err = NULL;
+
+ obj = object_property_get_link(OBJECT(dev), "mbox-mr", &err);
+ if (obj == NULL) {
+ error_setg(errp, "%s: required mbox-mr link not found: %s",
+ __func__, error_get_pretty(err));
+ return;
+ }
+
+ s->mbox_mr = MEMORY_REGION(obj);
+ address_space_init(&s->mbox_as, s->mbox_mr, NULL);
+ bcm2835_mbox_reset(dev);
+}
+
+static void bcm2835_mbox_class_init(ObjectClass *klass, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(klass);
+
+ dc->realize = bcm2835_mbox_realize;
+ dc->reset = bcm2835_mbox_reset;
+ dc->vmsd = &vmstate_bcm2835_mbox;
+}
+
+static TypeInfo bcm2835_mbox_info = {
+ .name = TYPE_BCM2835_MBOX,
+ .parent = TYPE_SYS_BUS_DEVICE,
+ .instance_size = sizeof(BCM2835MboxState),
+ .class_init = bcm2835_mbox_class_init,
+ .instance_init = bcm2835_mbox_init,
+};
+
+static void bcm2835_mbox_register_types(void)
+{
+ type_register_static(&bcm2835_mbox_info);
+}
+
+type_init(bcm2835_mbox_register_types)
diff --git a/hw/misc/bcm2835_property.c b/hw/misc/bcm2835_property.c
new file mode 100644
index 0000000000..e42b43e72d
--- /dev/null
+++ b/hw/misc/bcm2835_property.c
@@ -0,0 +1,287 @@
+/*
+ * Raspberry Pi emulation (c) 2012 Gregory Estrade
+ * This code is licensed under the GNU GPLv2 and later.
+ */
+
+#include "hw/misc/bcm2835_property.h"
+#include "hw/misc/bcm2835_mbox_defs.h"
+#include "sysemu/dma.h"
+
+/* https://github.com/raspberrypi/firmware/wiki/Mailbox-property-interface */
+
+static void bcm2835_property_mbox_push(BCM2835PropertyState *s, uint32_t value)
+{
+ uint32_t tag;
+ uint32_t bufsize;
+ uint32_t tot_len;
+ size_t resplen;
+ uint32_t tmp;
+
+ value &= ~0xf;
+
+ s->addr = value;
+
+ tot_len = ldl_phys(&s->dma_as, value);
+
+ /* @(addr + 4) : Buffer response code */
+ value = s->addr + 8;
+ while (value + 8 <= s->addr + tot_len) {
+ tag = ldl_phys(&s->dma_as, value);
+ bufsize = ldl_phys(&s->dma_as, value + 4);
+ /* @(value + 8) : Request/response indicator */
+ resplen = 0;
+ switch (tag) {
+ case 0x00000000: /* End tag */
+ break;
+ case 0x00000001: /* Get firmware revision */
+ stl_phys(&s->dma_as, value + 12, 346337);
+ resplen = 4;
+ break;
+ case 0x00010001: /* Get board model */
+ qemu_log_mask(LOG_UNIMP,
+ "bcm2835_property: %x get board model NYI\n", tag);
+ resplen = 4;
+ break;
+ case 0x00010002: /* Get board revision */
+ qemu_log_mask(LOG_UNIMP,
+ "bcm2835_property: %x get board revision NYI\n", tag);
+ resplen = 4;
+ break;
+ case 0x00010003: /* Get board MAC address */
+ resplen = sizeof(s->macaddr.a);
+ dma_memory_write(&s->dma_as, value + 12, s->macaddr.a, resplen);
+ break;
+ case 0x00010004: /* Get board serial */
+ qemu_log_mask(LOG_UNIMP,
+ "bcm2835_property: %x get board serial NYI\n", tag);
+ resplen = 8;
+ break;
+ case 0x00010005: /* Get ARM memory */
+ /* base */
+ stl_phys(&s->dma_as, value + 12, 0);
+ /* size */
+ stl_phys(&s->dma_as, value + 16, s->ram_size);
+ resplen = 8;
+ break;
+ case 0x00028001: /* Set power state */
+ /* Assume that whatever device they asked for exists,
+ * and we'll just claim we set it to the desired state
+ */
+ tmp = ldl_phys(&s->dma_as, value + 16);
+ stl_phys(&s->dma_as, value + 16, (tmp & 1));
+ resplen = 8;
+ break;
+
+ /* Clocks */
+
+ case 0x00030001: /* Get clock state */
+ stl_phys(&s->dma_as, value + 16, 0x1);
+ resplen = 8;
+ break;
+
+ case 0x00038001: /* Set clock state */
+ qemu_log_mask(LOG_UNIMP,
+ "bcm2835_property: %x set clock state NYI\n", tag);
+ resplen = 8;
+ break;
+
+ case 0x00030002: /* Get clock rate */
+ case 0x00030004: /* Get max clock rate */
+ case 0x00030007: /* Get min clock rate */
+ switch (ldl_phys(&s->dma_as, value + 12)) {
+ case 1: /* EMMC */
+ stl_phys(&s->dma_as, value + 16, 50000000);
+ break;
+ case 2: /* UART */
+ stl_phys(&s->dma_as, value + 16, 3000000);
+ break;
+ default:
+ stl_phys(&s->dma_as, value + 16, 700000000);
+ break;
+ }
+ resplen = 8;
+ break;
+
+ case 0x00038002: /* Set clock rate */
+ case 0x00038004: /* Set max clock rate */
+ case 0x00038007: /* Set min clock rate */
+ qemu_log_mask(LOG_UNIMP,
+ "bcm2835_property: %x set clock rates NYI\n", tag);
+ resplen = 8;
+ break;
+
+ /* Temperature */
+
+ case 0x00030006: /* Get temperature */
+ stl_phys(&s->dma_as, value + 16, 25000);
+ resplen = 8;
+ break;
+
+ case 0x0003000A: /* Get max temperature */
+ stl_phys(&s->dma_as, value + 16, 99000);
+ resplen = 8;
+ break;
+
+
+ case 0x00060001: /* Get DMA channels */
+ /* channels 2-5 */
+ stl_phys(&s->dma_as, value + 12, 0x003C);
+ resplen = 4;
+ break;
+
+ case 0x00050001: /* Get command line */
+ resplen = 0;
+ break;
+
+ default:
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "bcm2835_property: unhandled tag %08x\n", tag);
+ break;
+ }
+
+ if (tag == 0) {
+ break;
+ }
+
+ stl_phys(&s->dma_as, value + 8, (1 << 31) | resplen);
+ value += bufsize + 12;
+ }
+
+ /* Buffer response code */
+ stl_phys(&s->dma_as, s->addr + 4, (1 << 31));
+}
+
+static uint64_t bcm2835_property_read(void *opaque, hwaddr offset,
+ unsigned size)
+{
+ BCM2835PropertyState *s = opaque;
+ uint32_t res = 0;
+
+ switch (offset) {
+ case MBOX_AS_DATA:
+ res = MBOX_CHAN_PROPERTY | s->addr;
+ s->pending = false;
+ qemu_set_irq(s->mbox_irq, 0);
+ break;
+
+ case MBOX_AS_PENDING:
+ res = s->pending;
+ break;
+
+ default:
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset %"HWADDR_PRIx"\n",
+ __func__, offset);
+ return 0;
+ }
+
+ return res;
+}
+
+static void bcm2835_property_write(void *opaque, hwaddr offset,
+ uint64_t value, unsigned size)
+{
+ BCM2835PropertyState *s = opaque;
+
+ switch (offset) {
+ case MBOX_AS_DATA:
+ /* bcm2835_mbox should check our pending status before pushing */
+ assert(!s->pending);
+ s->pending = true;
+ bcm2835_property_mbox_push(s, value);
+ qemu_set_irq(s->mbox_irq, 1);
+ break;
+
+ default:
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset %"HWADDR_PRIx"\n",
+ __func__, offset);
+ return;
+ }
+}
+
+static const MemoryRegionOps bcm2835_property_ops = {
+ .read = bcm2835_property_read,
+ .write = bcm2835_property_write,
+ .endianness = DEVICE_NATIVE_ENDIAN,
+ .valid.min_access_size = 4,
+ .valid.max_access_size = 4,
+};
+
+static const VMStateDescription vmstate_bcm2835_property = {
+ .name = TYPE_BCM2835_PROPERTY,
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .fields = (VMStateField[]) {
+ VMSTATE_MACADDR(macaddr, BCM2835PropertyState),
+ VMSTATE_UINT32(addr, BCM2835PropertyState),
+ VMSTATE_BOOL(pending, BCM2835PropertyState),
+ VMSTATE_END_OF_LIST()
+ }
+};
+
+static void bcm2835_property_init(Object *obj)
+{
+ BCM2835PropertyState *s = BCM2835_PROPERTY(obj);
+
+ memory_region_init_io(&s->iomem, OBJECT(s), &bcm2835_property_ops, s,
+ TYPE_BCM2835_PROPERTY, 0x10);
+ sysbus_init_mmio(SYS_BUS_DEVICE(s), &s->iomem);
+ sysbus_init_irq(SYS_BUS_DEVICE(s), &s->mbox_irq);
+}
+
+static void bcm2835_property_reset(DeviceState *dev)
+{
+ BCM2835PropertyState *s = BCM2835_PROPERTY(dev);
+
+ s->pending = false;
+}
+
+static void bcm2835_property_realize(DeviceState *dev, Error **errp)
+{
+ BCM2835PropertyState *s = BCM2835_PROPERTY(dev);
+ Object *obj;
+ Error *err = NULL;
+
+ obj = object_property_get_link(OBJECT(dev), "dma-mr", &err);
+ if (obj == NULL) {
+ error_setg(errp, "%s: required dma-mr link not found: %s",
+ __func__, error_get_pretty(err));
+ return;
+ }
+
+ s->dma_mr = MEMORY_REGION(obj);
+ address_space_init(&s->dma_as, s->dma_mr, NULL);
+
+ /* TODO: connect to MAC address of USB NIC device, once we emulate it */
+ qemu_macaddr_default_if_unset(&s->macaddr);
+
+ bcm2835_property_reset(dev);
+}
+
+static Property bcm2835_property_props[] = {
+ DEFINE_PROP_UINT32("ram-size", BCM2835PropertyState, ram_size, 0),
+ DEFINE_PROP_END_OF_LIST()
+};
+
+static void bcm2835_property_class_init(ObjectClass *klass, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(klass);
+
+ dc->props = bcm2835_property_props;
+ dc->realize = bcm2835_property_realize;
+ dc->vmsd = &vmstate_bcm2835_property;
+}
+
+static TypeInfo bcm2835_property_info = {
+ .name = TYPE_BCM2835_PROPERTY,
+ .parent = TYPE_SYS_BUS_DEVICE,
+ .instance_size = sizeof(BCM2835PropertyState),
+ .class_init = bcm2835_property_class_init,
+ .instance_init = bcm2835_property_init,
+};
+
+static void bcm2835_property_register_types(void)
+{
+ type_register_static(&bcm2835_property_info);
+}
+
+type_init(bcm2835_property_register_types)
diff --git a/hw/net/cadence_gem.c b/hw/net/cadence_gem.c
index f9e409192b..0346f3e335 100644
--- a/hw/net/cadence_gem.c
+++ b/hw/net/cadence_gem.c
@@ -678,6 +678,10 @@ static ssize_t gem_receive(NetClientState *nc, const uint8_t *buf, size_t size)
} else {
unsigned crc_val;
+ if (size > sizeof(rxbuf) - sizeof(crc_val)) {
+ size = sizeof(rxbuf) - sizeof(crc_val);
+ }
+ bytes_to_copy = size;
/* The application wants the FCS field, which QEMU does not provide.
* We must try and calculate one.
*/
@@ -863,6 +867,14 @@ static void gem_transmit(CadenceGEMState *s)
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.
*/
diff --git a/hw/net/e1000.c b/hw/net/e1000.c
index 4eda7a3289..0387fa0646 100644
--- a/hw/net/e1000.c
+++ b/hw/net/e1000.c
@@ -909,7 +909,8 @@ start_xmit(E1000State *s)
* bogus values to TDT/TDLEN.
* there's nothing too intelligent we could do about this.
*/
- if (s->mac_reg[TDH] == tdh_start) {
+ if (s->mac_reg[TDH] == tdh_start ||
+ tdh_start >= s->mac_reg[TDLEN] / sizeof(desc)) {
DBGOUT(TXERR, "TDH wraparound @%x, TDT %x, TDLEN %x\n",
tdh_start, s->mac_reg[TDT], s->mac_reg[TDLEN]);
break;
@@ -1166,7 +1167,8 @@ e1000_receive_iov(NetClientState *nc, const struct iovec *iov, int iovcnt)
if (++s->mac_reg[RDH] * sizeof(desc) >= s->mac_reg[RDLEN])
s->mac_reg[RDH] = 0;
/* see comment in start_xmit; same here */
- if (s->mac_reg[RDH] == rdh_start) {
+ if (s->mac_reg[RDH] == rdh_start ||
+ rdh_start >= s->mac_reg[RDLEN] / sizeof(desc)) {
DBGOUT(RXERR, "RDH wraparound @%x, RDT %x, RDLEN %x\n",
rdh_start, s->mac_reg[RDT], s->mac_reg[RDLEN]);
set_ics(s, 0, E1000_ICS_RXO);
diff --git a/hw/sparc/sun4m.c b/hw/sparc/sun4m.c
index 1fcec4478f..20dc341710 100644
--- a/hw/sparc/sun4m.c
+++ b/hw/sparc/sun4m.c
@@ -96,29 +96,7 @@ struct sun4m_hwdef {
uint8_t nvram_machine_id;
};
-int DMA_get_channel_mode (int nchan)
-{
- return 0;
-}
-int DMA_read_memory (int nchan, void *buf, int pos, int size)
-{
- return 0;
-}
-int DMA_write_memory (int nchan, void *buf, int pos, int size)
-{
- return 0;
-}
-void DMA_hold_DREQ (int nchan) {}
-void DMA_release_DREQ (int nchan) {}
-void DMA_schedule(void) {}
-
-void DMA_init(int high_page_enable)
-{
-}
-
-void DMA_register_channel (int nchan,
- DMA_transfer_handler transfer_handler,
- void *opaque)
+void DMA_init(ISABus *bus, int high_page_enable)
{
}
diff --git a/hw/sparc64/sun4u.c b/hw/sparc64/sun4u.c
index 124c376897..add1e752f3 100644
--- a/hw/sparc64/sun4u.c
+++ b/hw/sparc64/sun4u.c
@@ -99,29 +99,7 @@ typedef struct EbusState {
MemoryRegion bar1;
} EbusState;
-int DMA_get_channel_mode (int nchan)
-{
- return 0;
-}
-int DMA_read_memory (int nchan, void *buf, int pos, int size)
-{
- return 0;
-}
-int DMA_write_memory (int nchan, void *buf, int pos, int size)
-{
- return 0;
-}
-void DMA_hold_DREQ (int nchan) {}
-void DMA_release_DREQ (int nchan) {}
-void DMA_schedule(void) {}
-
-void DMA_init(int high_page_enable)
-{
-}
-
-void DMA_register_channel (int nchan,
- DMA_transfer_handler transfer_handler,
- void *opaque)
+void DMA_init(ISABus *bus, int high_page_enable)
{
}
@@ -816,6 +794,7 @@ static void sun4uv_init(MemoryRegion *address_space_mem,
qemu_irq *ivec_irqs, *pbm_irqs;
DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
DriveInfo *fd[MAX_FD];
+ DeviceState *dev;
FWCfgState *fw_cfg;
/* init CPUs */
@@ -852,10 +831,22 @@ static void sun4uv_init(MemoryRegion *address_space_mem,
pci_cmd646_ide_init(pci_bus, hd, 1);
isa_create_simple(isa_bus, "i8042");
+
+ /* Floppy */
for(i = 0; i < MAX_FD; i++) {
fd[i] = drive_get(IF_FLOPPY, 0, i);
}
- fdctrl_init_isa(isa_bus, fd);
+ dev = DEVICE(isa_create(isa_bus, TYPE_ISA_FDC));
+ if (fd[0]) {
+ qdev_prop_set_drive(dev, "driveA", blk_by_legacy_dinfo(fd[0]),
+ &error_abort);
+ }
+ if (fd[1]) {
+ qdev_prop_set_drive(dev, "driveB", blk_by_legacy_dinfo(fd[1]),
+ &error_abort);
+ }
+ qdev_prop_set_uint32(dev, "dma", -1);
+ qdev_init_nofail(dev);
/* Map NVRAM into I/O (ebus) space */
nvram = m48t59_init(NULL, 0, 0, NVRAM_SIZE, 1968, 59);
diff --git a/include/exec/ram_addr.h b/include/exec/ram_addr.h
index ef1489da77..606e277092 100644
--- a/include/exec/ram_addr.h
+++ b/include/exec/ram_addr.h
@@ -38,10 +38,14 @@ struct RAMBlock {
int fd;
};
+static inline bool offset_in_ramblock(RAMBlock *b, ram_addr_t offset)
+{
+ return (b && b->host && offset < b->used_length) ? true : false;
+}
+
static inline void *ramblock_ptr(RAMBlock *block, ram_addr_t offset)
{
- assert(offset < block->used_length);
- assert(block->host);
+ assert(offset_in_ramblock(block, offset));
return (char *)block->host + offset;
}
diff --git a/include/hw/arm/arm.h b/include/hw/arm/arm.h
index c26b0e357f..52ecf4aa8f 100644
--- a/include/hw/arm/arm.h
+++ b/include/hw/arm/arm.h
@@ -122,6 +122,11 @@ struct arm_boot_info {
*/
void arm_load_kernel(ARMCPU *cpu, struct arm_boot_info *info);
+/* Write a secure board setup routine with a dummy handler for SMCs */
+void arm_write_secure_board_setup_dummy_smc(ARMCPU *cpu,
+ const struct arm_boot_info *info,
+ hwaddr mvbar_addr);
+
/* Multiplication factor to convert from system clock ticks to qemu timer
ticks. */
extern int system_clock_scale;
diff --git a/include/hw/arm/bcm2835_peripherals.h b/include/hw/arm/bcm2835_peripherals.h
new file mode 100644
index 0000000000..5d888dca53
--- /dev/null
+++ b/include/hw/arm/bcm2835_peripherals.h
@@ -0,0 +1,42 @@
+/*
+ * Raspberry Pi emulation (c) 2012 Gregory Estrade
+ * Upstreaming code cleanup [including bcm2835_*] (c) 2013 Jan Petrous
+ *
+ * Rasperry Pi 2 emulation and refactoring Copyright (c) 2015, Microsoft
+ * Written by Andrew Baumann
+ *
+ * This code is licensed under the GNU GPLv2 and later.
+ */
+
+#ifndef BCM2835_PERIPHERALS_H
+#define BCM2835_PERIPHERALS_H
+
+#include "qemu-common.h"
+#include "exec/address-spaces.h"
+#include "hw/sysbus.h"
+#include "hw/intc/bcm2835_ic.h"
+#include "hw/misc/bcm2835_property.h"
+#include "hw/misc/bcm2835_mbox.h"
+#include "hw/sd/sdhci.h"
+
+#define TYPE_BCM2835_PERIPHERALS "bcm2835-peripherals"
+#define BCM2835_PERIPHERALS(obj) \
+ OBJECT_CHECK(BCM2835PeripheralState, (obj), TYPE_BCM2835_PERIPHERALS)
+
+typedef struct BCM2835PeripheralState {
+ /*< private >*/
+ SysBusDevice parent_obj;
+ /*< public >*/
+
+ MemoryRegion peri_mr, peri_mr_alias, gpu_bus_mr, mbox_mr;
+ MemoryRegion ram_alias[4];
+ qemu_irq irq, fiq;
+
+ SysBusDevice *uart0;
+ BCM2835ICState ic;
+ BCM2835PropertyState property;
+ BCM2835MboxState mboxes;
+ SDHCIState sdhci;
+} BCM2835PeripheralState;
+
+#endif /* BCM2835_PERIPHERALS_H */
diff --git a/include/hw/arm/bcm2836.h b/include/hw/arm/bcm2836.h
new file mode 100644
index 0000000000..76de1996af
--- /dev/null
+++ b/include/hw/arm/bcm2836.h
@@ -0,0 +1,35 @@
+/*
+ * Raspberry Pi emulation (c) 2012 Gregory Estrade
+ * Upstreaming code cleanup [including bcm2835_*] (c) 2013 Jan Petrous
+ *
+ * Rasperry Pi 2 emulation and refactoring Copyright (c) 2015, Microsoft
+ * Written by Andrew Baumann
+ *
+ * This code is licensed under the GNU GPLv2 and later.
+ */
+
+#ifndef BCM2836_H
+#define BCM2836_H
+
+#include "hw/arm/arm.h"
+#include "hw/arm/bcm2835_peripherals.h"
+#include "hw/intc/bcm2836_control.h"
+
+#define TYPE_BCM2836 "bcm2836"
+#define BCM2836(obj) OBJECT_CHECK(BCM2836State, (obj), TYPE_BCM2836)
+
+#define BCM2836_NCPUS 4
+
+typedef struct BCM2836State {
+ /*< private >*/
+ DeviceState parent_obj;
+ /*< public >*/
+
+ uint32_t enabled_cpus;
+
+ ARMCPU cpus[BCM2836_NCPUS];
+ BCM2836ControlState control;
+ BCM2835PeripheralState peripherals;
+} BCM2836State;
+
+#endif /* BCM2836_H */
diff --git a/include/hw/arm/raspi_platform.h b/include/hw/arm/raspi_platform.h
new file mode 100644
index 0000000000..6467e88ae6
--- /dev/null
+++ b/include/hw/arm/raspi_platform.h
@@ -0,0 +1,128 @@
+/*
+ * bcm2708 aka bcm2835/2836 aka Raspberry Pi/Pi2 SoC platform defines
+ *
+ * These definitions are derived from those in Raspbian Linux at
+ * arch/arm/mach-{bcm2708,bcm2709}/include/mach/platform.h
+ * where they carry the following notice:
+ *
+ * Copyright (C) 2010 Broadcom
+ *
+ * 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#define MCORE_OFFSET 0x0000 /* Fake frame buffer device
+ * (the multicore sync block) */
+#define IC0_OFFSET 0x2000
+#define ST_OFFSET 0x3000 /* System Timer */
+#define MPHI_OFFSET 0x6000 /* Message-based Parallel Host Intf. */
+#define DMA_OFFSET 0x7000 /* DMA controller, channels 0-14 */
+#define ARM_OFFSET 0xB000 /* BCM2708 ARM control block */
+#define ARMCTRL_OFFSET (ARM_OFFSET + 0x000)
+#define ARMCTRL_IC_OFFSET (ARM_OFFSET + 0x200) /* Interrupt controller */
+#define ARMCTRL_TIMER0_1_OFFSET (ARM_OFFSET + 0x400) /* Timer 0 and 1 */
+#define ARMCTRL_0_SBM_OFFSET (ARM_OFFSET + 0x800) /* User 0 (ARM) Semaphores
+ * Doorbells & Mailboxes */
+#define PM_OFFSET 0x100000 /* Power Management, Reset controller
+ * and Watchdog registers */
+#define PCM_CLOCK_OFFSET 0x101098
+#define RNG_OFFSET 0x104000
+#define GPIO_OFFSET 0x200000
+#define UART0_OFFSET 0x201000
+#define MMCI0_OFFSET 0x202000
+#define I2S_OFFSET 0x203000
+#define SPI0_OFFSET 0x204000
+#define BSC0_OFFSET 0x205000 /* BSC0 I2C/TWI */
+#define UART1_OFFSET 0x215000
+#define EMMC_OFFSET 0x300000
+#define SMI_OFFSET 0x600000
+#define BSC1_OFFSET 0x804000 /* BSC1 I2C/TWI */
+#define USB_OFFSET 0x980000 /* DTC_OTG USB controller */
+#define DMA15_OFFSET 0xE05000 /* DMA controller, channel 15 */
+
+/* GPU interrupts */
+#define INTERRUPT_TIMER0 0
+#define INTERRUPT_TIMER1 1
+#define INTERRUPT_TIMER2 2
+#define INTERRUPT_TIMER3 3
+#define INTERRUPT_CODEC0 4
+#define INTERRUPT_CODEC1 5
+#define INTERRUPT_CODEC2 6
+#define INTERRUPT_JPEG 7
+#define INTERRUPT_ISP 8
+#define INTERRUPT_USB 9
+#define INTERRUPT_3D 10
+#define INTERRUPT_TRANSPOSER 11
+#define INTERRUPT_MULTICORESYNC0 12
+#define INTERRUPT_MULTICORESYNC1 13
+#define INTERRUPT_MULTICORESYNC2 14
+#define INTERRUPT_MULTICORESYNC3 15
+#define INTERRUPT_DMA0 16
+#define INTERRUPT_DMA1 17
+#define INTERRUPT_DMA2 18
+#define INTERRUPT_DMA3 19
+#define INTERRUPT_DMA4 20
+#define INTERRUPT_DMA5 21
+#define INTERRUPT_DMA6 22
+#define INTERRUPT_DMA7 23
+#define INTERRUPT_DMA8 24
+#define INTERRUPT_DMA9 25
+#define INTERRUPT_DMA10 26
+#define INTERRUPT_DMA11 27
+#define INTERRUPT_DMA12 28
+#define INTERRUPT_AUX 29
+#define INTERRUPT_ARM 30
+#define INTERRUPT_VPUDMA 31
+#define INTERRUPT_HOSTPORT 32
+#define INTERRUPT_VIDEOSCALER 33
+#define INTERRUPT_CCP2TX 34
+#define INTERRUPT_SDC 35
+#define INTERRUPT_DSI0 36
+#define INTERRUPT_AVE 37
+#define INTERRUPT_CAM0 38
+#define INTERRUPT_CAM1 39
+#define INTERRUPT_HDMI0 40
+#define INTERRUPT_HDMI1 41
+#define INTERRUPT_PIXELVALVE1 42
+#define INTERRUPT_I2CSPISLV 43
+#define INTERRUPT_DSI1 44
+#define INTERRUPT_PWA0 45
+#define INTERRUPT_PWA1 46
+#define INTERRUPT_CPR 47
+#define INTERRUPT_SMI 48
+#define INTERRUPT_GPIO0 49
+#define INTERRUPT_GPIO1 50
+#define INTERRUPT_GPIO2 51
+#define INTERRUPT_GPIO3 52
+#define INTERRUPT_I2C 53
+#define INTERRUPT_SPI 54
+#define INTERRUPT_I2SPCM 55
+#define INTERRUPT_SDIO 56
+#define INTERRUPT_UART 57
+#define INTERRUPT_SLIMBUS 58
+#define INTERRUPT_VEC 59
+#define INTERRUPT_CPG 60
+#define INTERRUPT_RNG 61
+#define INTERRUPT_ARASANSDIO 62
+#define INTERRUPT_AVSPMON 63
+
+/* ARM CPU IRQs use a private number space */
+#define INTERRUPT_ARM_TIMER 0
+#define INTERRUPT_ARM_MAILBOX 1
+#define INTERRUPT_ARM_DOORBELL_0 2
+#define INTERRUPT_ARM_DOORBELL_1 3
+#define INTERRUPT_VPU0_HALTED 4
+#define INTERRUPT_VPU1_HALTED 5
+#define INTERRUPT_ILLEGAL_TYPE0 6
+#define INTERRUPT_ILLEGAL_TYPE1 7
diff --git a/include/hw/arm/virt-acpi-build.h b/include/hw/arm/virt-acpi-build.h
index 744b666385..7d3700ebf6 100644
--- a/include/hw/arm/virt-acpi-build.h
+++ b/include/hw/arm/virt-acpi-build.h
@@ -23,7 +23,6 @@
#include "qemu-common.h"
#include "hw/arm/virt.h"
-#define VIRT_ACPI_CPU_ID_LIMIT 8
#define ACPI_GICC_ENABLED 1
typedef struct VirtGuestInfo {
diff --git a/include/hw/intc/bcm2835_ic.h b/include/hw/intc/bcm2835_ic.h
new file mode 100644
index 0000000000..fb75fa0064
--- /dev/null
+++ b/include/hw/intc/bcm2835_ic.h
@@ -0,0 +1,33 @@
+/*
+ * Raspberry Pi emulation (c) 2012 Gregory Estrade
+ * This code is licensed under the GNU GPLv2 and later.
+ */
+
+#ifndef BCM2835_IC_H
+#define BCM2835_IC_H
+
+#include "hw/sysbus.h"
+
+#define TYPE_BCM2835_IC "bcm2835-ic"
+#define BCM2835_IC(obj) OBJECT_CHECK(BCM2835ICState, (obj), TYPE_BCM2835_IC)
+
+#define BCM2835_IC_GPU_IRQ "gpu-irq"
+#define BCM2835_IC_ARM_IRQ "arm-irq"
+
+typedef struct BCM2835ICState {
+ /*< private >*/
+ SysBusDevice busdev;
+ /*< public >*/
+
+ MemoryRegion iomem;
+ qemu_irq irq;
+ qemu_irq fiq;
+
+ /* 64 GPU IRQs + 8 ARM IRQs = 72 total (GPU first) */
+ uint64_t gpu_irq_level, gpu_irq_enable;
+ uint8_t arm_irq_level, arm_irq_enable;
+ bool fiq_enable;
+ uint8_t fiq_select;
+} BCM2835ICState;
+
+#endif
diff --git a/include/hw/intc/bcm2836_control.h b/include/hw/intc/bcm2836_control.h
new file mode 100644
index 0000000000..613f3c4186
--- /dev/null
+++ b/include/hw/intc/bcm2836_control.h
@@ -0,0 +1,51 @@
+/*
+ * Raspberry Pi emulation (c) 2012 Gregory Estrade
+ * Upstreaming code cleanup [including bcm2835_*] (c) 2013 Jan Petrous
+ *
+ * Rasperry Pi 2 emulation and refactoring Copyright (c) 2015, Microsoft
+ * Written by Andrew Baumann
+ *
+ * This code is licensed under the GNU GPLv2 and later.
+ */
+
+#ifndef BCM2836_CONTROL_H
+#define BCM2836_CONTROL_H
+
+#include "hw/sysbus.h"
+
+/* 4 mailboxes per core, for 16 total */
+#define BCM2836_NCORES 4
+#define BCM2836_MBPERCORE 4
+
+#define TYPE_BCM2836_CONTROL "bcm2836-control"
+#define BCM2836_CONTROL(obj) \
+ OBJECT_CHECK(BCM2836ControlState, (obj), TYPE_BCM2836_CONTROL)
+
+typedef struct BCM2836ControlState {
+ /*< private >*/
+ SysBusDevice busdev;
+ /*< public >*/
+ MemoryRegion iomem;
+
+ /* mailbox state */
+ uint32_t mailboxes[BCM2836_NCORES * BCM2836_MBPERCORE];
+
+ /* interrupt routing/control registers */
+ uint8_t route_gpu_irq, route_gpu_fiq;
+ uint32_t timercontrol[BCM2836_NCORES];
+ uint32_t mailboxcontrol[BCM2836_NCORES];
+
+ /* interrupt status regs (derived from input pins; not visible to user) */
+ bool gpu_irq, gpu_fiq;
+ uint8_t timerirqs[BCM2836_NCORES];
+
+ /* interrupt source registers, post-routing (also input-derived; visible) */
+ uint32_t irqsrc[BCM2836_NCORES];
+ uint32_t fiqsrc[BCM2836_NCORES];
+
+ /* outputs to CPU cores */
+ qemu_irq irq[BCM2836_NCORES];
+ qemu_irq fiq[BCM2836_NCORES];
+} BCM2836ControlState;
+
+#endif
diff --git a/include/hw/isa/i8257.h b/include/hw/isa/i8257.h
new file mode 100644
index 0000000000..8d34ed17b7
--- /dev/null
+++ b/include/hw/isa/i8257.h
@@ -0,0 +1,42 @@
+#ifndef HW_I8257_H
+#define HW_I8257_H
+
+#define TYPE_I8257 "i8257"
+
+typedef struct I8257Regs {
+ int now[2];
+ uint16_t base[2];
+ uint8_t mode;
+ uint8_t page;
+ uint8_t pageh;
+ uint8_t dack;
+ uint8_t eop;
+ DMA_transfer_handler transfer_handler;
+ void *opaque;
+} I8257Regs;
+
+typedef struct I8257State {
+ /* <private> */
+ ISADevice parent_obj;
+
+ /* <public> */
+ int32_t base;
+ int32_t page_base;
+ int32_t pageh_base;
+ int32_t dshift;
+
+ uint8_t status;
+ uint8_t command;
+ uint8_t mask;
+ uint8_t flip_flop;
+ I8257Regs regs[4];
+ MemoryRegion channel_io;
+ MemoryRegion cont_io;
+
+ QEMUBH *dma_bh;
+ bool dma_bh_scheduled;
+ int running;
+} I8257State;
+
+#endif
+
diff --git a/include/hw/isa/isa.h b/include/hw/isa/isa.h
index de3cd3d38a..0bbe21cd48 100644
--- a/include/hw/isa/isa.h
+++ b/include/hw/isa/isa.h
@@ -34,6 +34,41 @@ static inline uint16_t applesmc_port(void)
return 0;
}
+#define TYPE_ISADMA "isa-dma"
+
+#define ISADMA_CLASS(klass) \
+ OBJECT_CLASS_CHECK(IsaDmaClass, (klass), TYPE_ISADMA)
+#define ISADMA_GET_CLASS(obj) \
+ OBJECT_GET_CLASS(IsaDmaClass, (obj), TYPE_ISADMA)
+#define ISADMA(obj) \
+ INTERFACE_CHECK(IsaDma, (obj), TYPE_ISADMA)
+
+struct IsaDma {
+ Object parent;
+};
+
+typedef enum {
+ ISADMA_TRANSFER_VERIFY,
+ ISADMA_TRANSFER_READ,
+ ISADMA_TRANSFER_WRITE,
+ ISADMA_TRANSFER_ILLEGAL,
+} IsaDmaTransferMode;
+
+typedef struct IsaDmaClass {
+ InterfaceClass parent;
+
+ IsaDmaTransferMode (*get_transfer_mode)(IsaDma *obj, int nchan);
+ bool (*has_autoinitialization)(IsaDma *obj, int nchan);
+ int (*read_memory)(IsaDma *obj, int nchan, void *buf, int pos, int len);
+ int (*write_memory)(IsaDma *obj, int nchan, void *buf, int pos, int len);
+ void (*hold_DREQ)(IsaDma *obj, int nchan);
+ void (*release_DREQ)(IsaDma *obj, int nchan);
+ void (*schedule)(IsaDma *obj);
+ void (*register_channel)(IsaDma *obj, int nchan,
+ DMA_transfer_handler transfer_handler,
+ void *opaque);
+} IsaDmaClass;
+
typedef struct ISADeviceClass {
DeviceClass parent_class;
} ISADeviceClass;
@@ -46,6 +81,7 @@ struct ISABus {
MemoryRegion *address_space;
MemoryRegion *address_space_io;
qemu_irq *irqs;
+ IsaDma *dma[2];
};
struct ISADevice {
@@ -63,6 +99,8 @@ ISABus *isa_bus_new(DeviceState *dev, MemoryRegion *address_space,
void isa_bus_irqs(ISABus *bus, qemu_irq *irqs);
qemu_irq isa_get_irq(ISADevice *dev, int isairq);
void isa_init_irq(ISADevice *dev, qemu_irq *p, int isairq);
+void isa_bus_dma(ISABus *bus, IsaDma *dma8, IsaDma *dma16);
+IsaDma *isa_get_dma(ISABus *bus, int nchan);
MemoryRegion *isa_address_space(ISADevice *dev);
MemoryRegion *isa_address_space_io(ISADevice *dev);
ISADevice *isa_create(ISABus *bus, const char *name);
@@ -106,15 +144,6 @@ static inline ISABus *isa_bus_from_device(ISADevice *d)
return ISA_BUS(qdev_get_parent_bus(DEVICE(d)));
}
-/* dma.c */
-int DMA_get_channel_mode (int nchan);
-int DMA_read_memory (int nchan, void *buf, int pos, int size);
-int DMA_write_memory (int nchan, void *buf, int pos, int size);
-void DMA_hold_DREQ (int nchan);
-void DMA_release_DREQ (int nchan);
-void DMA_schedule(void);
-void DMA_init(int high_page_enable);
-void DMA_register_channel (int nchan,
- DMA_transfer_handler transfer_handler,
- void *opaque);
+/* i8257.c */
+void DMA_init(ISABus *bus, int high_page_enable);
#endif
diff --git a/include/hw/misc/bcm2835_mbox.h b/include/hw/misc/bcm2835_mbox.h
new file mode 100644
index 0000000000..f4e9ff9ef6
--- /dev/null
+++ b/include/hw/misc/bcm2835_mbox.h
@@ -0,0 +1,38 @@
+/*
+ * Raspberry Pi emulation (c) 2012 Gregory Estrade
+ * This code is licensed under the GNU GPLv2 and later.
+ */
+
+#ifndef BCM2835_MBOX_H
+#define BCM2835_MBOX_H
+
+#include "bcm2835_mbox_defs.h"
+#include "hw/sysbus.h"
+#include "exec/address-spaces.h"
+
+#define TYPE_BCM2835_MBOX "bcm2835-mbox"
+#define BCM2835_MBOX(obj) \
+ OBJECT_CHECK(BCM2835MboxState, (obj), TYPE_BCM2835_MBOX)
+
+typedef struct {
+ uint32_t reg[MBOX_SIZE];
+ uint32_t count;
+ uint32_t status;
+ uint32_t config;
+} BCM2835Mbox;
+
+typedef struct {
+ /*< private >*/
+ SysBusDevice busdev;
+ /*< public >*/
+ MemoryRegion *mbox_mr;
+ AddressSpace mbox_as;
+ MemoryRegion iomem;
+ qemu_irq arm_irq;
+
+ bool mbox_irq_disabled;
+ bool available[MBOX_CHAN_COUNT];
+ BCM2835Mbox mbox[2];
+} BCM2835MboxState;
+
+#endif
diff --git a/include/hw/misc/bcm2835_mbox_defs.h b/include/hw/misc/bcm2835_mbox_defs.h
new file mode 100644
index 0000000000..a18e520b22
--- /dev/null
+++ b/include/hw/misc/bcm2835_mbox_defs.h
@@ -0,0 +1,27 @@
+/*
+ * Raspberry Pi emulation (c) 2012 Gregory Estrade
+ * This code is licensed under the GNU GPLv2 and later.
+ */
+
+#ifndef BCM2835_MBOX_DEFS_H
+#define BCM2835_MBOX_DEFS_H
+
+/* Constants shared with the ARM identifying separate mailbox channels */
+#define MBOX_CHAN_POWER 0 /* for use by the power management interface */
+#define MBOX_CHAN_FB 1 /* for use by the frame buffer */
+#define MBOX_CHAN_VCHIQ 3 /* for use by the VCHIQ interface */
+#define MBOX_CHAN_PROPERTY 8 /* for use by the property channel */
+#define MBOX_CHAN_COUNT 9
+
+#define MBOX_SIZE 32
+#define MBOX_INVALID_DATA 0x0f
+
+/* Layout of the private address space used for communication between
+ * the mbox device emulation, and child devices: each channel occupies
+ * 16 bytes of address space, but only two registers are presently defined.
+ */
+#define MBOX_AS_CHAN_SHIFT 4
+#define MBOX_AS_DATA 0 /* request / response data (RW at offset 0) */
+#define MBOX_AS_PENDING 4 /* pending response status (RO at offset 4) */
+
+#endif /* BCM2835_MBOX_DEFS_H */
diff --git a/include/hw/misc/bcm2835_property.h b/include/hw/misc/bcm2835_property.h
new file mode 100644
index 0000000000..fcf5f3deca
--- /dev/null
+++ b/include/hw/misc/bcm2835_property.h
@@ -0,0 +1,31 @@
+/*
+ * Raspberry Pi emulation (c) 2012 Gregory Estrade
+ * This code is licensed under the GNU GPLv2 and later.
+ */
+
+#ifndef BCM2835_PROPERTY_H
+#define BCM2835_PROPERTY_H
+
+#include "hw/sysbus.h"
+#include "exec/address-spaces.h"
+#include "net/net.h"
+
+#define TYPE_BCM2835_PROPERTY "bcm2835-property"
+#define BCM2835_PROPERTY(obj) \
+ OBJECT_CHECK(BCM2835PropertyState, (obj), TYPE_BCM2835_PROPERTY)
+
+typedef struct {
+ /*< private >*/
+ SysBusDevice busdev;
+ /*< public >*/
+ MemoryRegion *dma_mr;
+ AddressSpace dma_as;
+ MemoryRegion iomem;
+ qemu_irq mbox_irq;
+ MACAddr macaddr;
+ uint32_t ram_size;
+ uint32_t addr;
+ bool pending;
+} BCM2835PropertyState;
+
+#endif
diff --git a/include/migration/migration.h b/include/migration/migration.h
index 0fc1ffa9a9..74684ad929 100644
--- a/include/migration/migration.h
+++ b/include/migration/migration.h
@@ -133,7 +133,7 @@ struct MigrationState
size_t xfer_limit;
QemuThread thread;
QEMUBH *cleanup_bh;
- QEMUFile *file;
+ QEMUFile *to_dst_file;
int parameters[MIGRATION_PARAMETER__MAX];
int state;
diff --git a/include/net/filter.h b/include/net/filter.h
index 2deda362a6..56399763cc 100644
--- a/include/net/filter.h
+++ b/include/net/filter.h
@@ -55,7 +55,6 @@ struct NetFilterState {
char *netdev_id;
NetClientState *netdev;
NetFilterDirection direction;
- char info_str[256];
QTAILQ_ENTRY(NetFilterState) next;
};
diff --git a/include/net/net.h b/include/net/net.h
index 7af3e15f83..73e4c466e2 100644
--- a/include/net/net.h
+++ b/include/net/net.h
@@ -92,7 +92,7 @@ struct NetClientState {
NetClientDestructor *destructor;
unsigned int queue_index;
unsigned rxfilter_notify_enabled:1;
- QTAILQ_HEAD(, NetFilterState) filters;
+ QTAILQ_HEAD(NetFilterHead, NetFilterState) filters;
};
typedef struct NICState {
diff --git a/include/qemu/typedefs.h b/include/qemu/typedefs.h
index 78fe6e86e3..6ed91b4968 100644
--- a/include/qemu/typedefs.h
+++ b/include/qemu/typedefs.h
@@ -33,6 +33,7 @@ typedef struct I2CBus I2CBus;
typedef struct I2SCodec I2SCodec;
typedef struct ISABus ISABus;
typedef struct ISADevice ISADevice;
+typedef struct IsaDma IsaDma;
typedef struct LoadStateEntry LoadStateEntry;
typedef struct MACAddr MACAddr;
typedef struct MachineClass MachineClass;
diff --git a/io/channel-buffer.c b/io/channel-buffer.c
index daebc92bd8..0f7c5671fe 100644
--- a/io/channel-buffer.c
+++ b/io/channel-buffer.c
@@ -18,6 +18,7 @@
*
*/
+#include "qemu/osdep.h"
#include "io/channel-buffer.h"
#include "io/channel-watch.h"
#include "qemu/sockets.h"
diff --git a/io/channel-command.c b/io/channel-command.c
index a9c67aa221..f53ce0f4f4 100644
--- a/io/channel-command.c
+++ b/io/channel-command.c
@@ -18,6 +18,7 @@
*
*/
+#include "qemu/osdep.h"
#include "io/channel-command.h"
#include "io/channel-watch.h"
#include "qemu/sockets.h"
diff --git a/io/channel-file.c b/io/channel-file.c
index 13609005f9..19a432562a 100644
--- a/io/channel-file.c
+++ b/io/channel-file.c
@@ -18,6 +18,7 @@
*
*/
+#include "qemu/osdep.h"
#include "io/channel-file.h"
#include "io/channel-watch.h"
#include "qemu/sockets.h"
diff --git a/io/channel-socket.c b/io/channel-socket.c
index bc117b1115..22d2fd67d4 100644
--- a/io/channel-socket.c
+++ b/io/channel-socket.c
@@ -18,6 +18,7 @@
*
*/
+#include "qemu/osdep.h"
#include "io/channel-socket.h"
#include "io/channel-watch.h"
#include "trace.h"
diff --git a/io/channel-tls.c b/io/channel-tls.c
index 8ac4f76f78..7608fd9de0 100644
--- a/io/channel-tls.c
+++ b/io/channel-tls.c
@@ -18,6 +18,7 @@
*
*/
+#include "qemu/osdep.h"
#include "io/channel-tls.h"
#include "trace.h"
diff --git a/io/channel-watch.c b/io/channel-watch.c
index 2f745f16c4..931fa4d49d 100644
--- a/io/channel-watch.c
+++ b/io/channel-watch.c
@@ -18,6 +18,7 @@
*
*/
+#include "qemu/osdep.h"
#include "io/channel-watch.h"
typedef struct QIOChannelFDSource QIOChannelFDSource;
diff --git a/io/channel-websock.c b/io/channel-websock.c
index 9273a8b31e..35860a2738 100644
--- a/io/channel-websock.c
+++ b/io/channel-websock.c
@@ -18,6 +18,7 @@
*
*/
+#include "qemu/osdep.h"
#include "io/channel-websock.h"
#include "crypto/hash.h"
#include "trace.h"
diff --git a/io/channel.c b/io/channel.c
index 5e94469de2..3fc09f887c 100644
--- a/io/channel.c
+++ b/io/channel.c
@@ -18,6 +18,7 @@
*
*/
+#include "qemu/osdep.h"
#include "io/channel.h"
#include "qemu/coroutine.h"
diff --git a/io/task.c b/io/task.c
index 3127fca771..bf1a3339b2 100644
--- a/io/task.c
+++ b/io/task.c
@@ -18,6 +18,7 @@
*
*/
+#include "qemu/osdep.h"
#include "io/task.h"
#include "qemu/thread.h"
#include "trace.h"
diff --git a/iohandler.c b/iohandler.c
index eb68083559..0abb4a7e7a 100644
--- a/iohandler.c
+++ b/iohandler.c
@@ -22,7 +22,7 @@
* THE SOFTWARE.
*/
-#include "config-host.h"
+#include "qemu/osdep.h"
#include "qemu-common.h"
#include "qemu/queue.h"
#include "block/aio.h"
diff --git a/ioport.c b/ioport.c
index 193ef7685c..7a84d5444e 100644
--- a/ioport.c
+++ b/ioport.c
@@ -25,6 +25,7 @@
* splitted out ioport related stuffs from vl.c.
*/
+#include "qemu/osdep.h"
#include "exec/ioport.h"
#include "trace.h"
#include "exec/memory.h"
diff --git a/iothread.c b/iothread.c
index 1b8c2bbecb..f183d380e6 100644
--- a/iothread.c
+++ b/iothread.c
@@ -11,6 +11,7 @@
*
*/
+#include "qemu/osdep.h"
#include "qom/object.h"
#include "qom/object_interfaces.h"
#include "qemu/module.h"
diff --git a/kvm-all.c b/kvm-all.c
index 9148889921..9cc9ba6ea6 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -13,10 +13,9 @@
*
*/
-#include <sys/types.h>
+#include "qemu/osdep.h"
#include <sys/ioctl.h>
#include <sys/mman.h>
-#include <stdarg.h>
#include <linux/kvm.h>
diff --git a/kvm-stub.c b/kvm-stub.c
index dc97a5edf1..b962b24831 100644
--- a/kvm-stub.c
+++ b/kvm-stub.c
@@ -10,6 +10,7 @@
*
*/
+#include "qemu/osdep.h"
#include "qemu-common.h"
#include "hw/hw.h"
#include "cpu.h"
diff --git a/main-loop.c b/main-loop.c
index 5877615387..19beae76ad 100644
--- a/main-loop.c
+++ b/main-loop.c
@@ -22,6 +22,7 @@
* THE SOFTWARE.
*/
+#include "qemu/osdep.h"
#include "qemu-common.h"
#include "qemu/timer.h"
#include "qemu/sockets.h" // struct in_addr needed for libslirp.h
diff --git a/memory.c b/memory.c
index d2d0a92810..39c539cd59 100644
--- a/memory.c
+++ b/memory.c
@@ -13,6 +13,7 @@
* GNU GPL, version 2 or (at your option) any later version.
*/
+#include "qemu/osdep.h"
#include "exec/memory.h"
#include "exec/address-spaces.h"
#include "exec/ioport.h"
@@ -21,7 +22,6 @@
#include "qemu/error-report.h"
#include "qom/object.h"
#include "trace.h"
-#include <assert.h>
#include "exec/memory-internal.h"
#include "exec/ram_addr.h"
diff --git a/memory_mapping.c b/memory_mapping.c
index 36d6b26046..04db3ac7fa 100644
--- a/memory_mapping.c
+++ b/memory_mapping.c
@@ -11,6 +11,7 @@
*
*/
+#include "qemu/osdep.h"
#include <glib.h>
#include "qemu-common.h"
diff --git a/migration/exec.c b/migration/exec.c
index f1b5e47200..62f892d4d9 100644
--- a/migration/exec.c
+++ b/migration/exec.c
@@ -36,8 +36,8 @@
void exec_start_outgoing_migration(MigrationState *s, const char *command, Error **errp)
{
- s->file = qemu_popen_cmd(command, "w");
- if (s->file == NULL) {
+ s->to_dst_file = qemu_popen_cmd(command, "w");
+ if (s->to_dst_file == NULL) {
error_setg_errno(errp, errno, "failed to popen the migration target");
return;
}
diff --git a/migration/fd.c b/migration/fd.c
index c0afc96c2a..085dd7c51e 100644
--- a/migration/fd.c
+++ b/migration/fd.c
@@ -51,9 +51,9 @@ void fd_start_outgoing_migration(MigrationState *s, const char *fdname, Error **
}
if (fd_is_socket(fd)) {
- s->file = qemu_fopen_socket(fd, "wb");
+ s->to_dst_file = qemu_fopen_socket(fd, "wb");
} else {
- s->file = qemu_fdopen(fd, "wb");
+ s->to_dst_file = qemu_fdopen(fd, "wb");
}
migrate_fd_connect(s);
diff --git a/migration/migration.c b/migration/migration.c
index 2c76998cdf..82604d240e 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -809,7 +809,7 @@ static void migrate_fd_cleanup(void *opaque)
flush_page_queue(s);
- if (s->file) {
+ if (s->to_dst_file) {
trace_migrate_fd_cleanup();
qemu_mutex_unlock_iothread();
if (s->migration_thread_running) {
@@ -819,8 +819,8 @@ static void migrate_fd_cleanup(void *opaque)
qemu_mutex_lock_iothread();
migrate_compress_threads_join();
- qemu_fclose(s->file);
- s->file = NULL;
+ qemu_fclose(s->to_dst_file);
+ s->to_dst_file = NULL;
}
assert((s->state != MIGRATION_STATUS_ACTIVE) &&
@@ -837,7 +837,7 @@ static void migrate_fd_cleanup(void *opaque)
void migrate_fd_error(MigrationState *s)
{
trace_migrate_fd_error();
- assert(s->file == NULL);
+ assert(s->to_dst_file == NULL);
migrate_set_state(&s->state, MIGRATION_STATUS_SETUP,
MIGRATION_STATUS_FAILED);
notifier_list_notify(&migration_state_notifiers, s);
@@ -846,7 +846,7 @@ void migrate_fd_error(MigrationState *s)
static void migrate_fd_cancel(MigrationState *s)
{
int old_state ;
- QEMUFile *f = migrate_get_current()->file;
+ QEMUFile *f = migrate_get_current()->to_dst_file;
trace_migrate_fd_cancel();
if (s->rp_state.from_dst_file) {
@@ -917,7 +917,7 @@ MigrationState *migrate_init(const MigrationParams *params)
s->bytes_xfer = 0;
s->xfer_limit = 0;
s->cleanup_bh = 0;
- s->file = NULL;
+ s->to_dst_file = NULL;
s->state = MIGRATION_STATUS_NONE;
s->params = *params;
s->rp_state.from_dst_file = NULL;
@@ -1007,12 +1007,6 @@ void qmp_migrate(const char *uri, bool has_blk, bool blk,
return;
}
- /* We are starting a new migration, so we want to start in a clean
- state. This change is only needed if previous migration
- failed/was cancelled. We don't use migrate_set_state() because
- we are setting the initial state, not changing it. */
- s->state = MIGRATION_STATUS_NONE;
-
s = migrate_init(&params);
if (strstart(uri, "tcp:", &p)) {
@@ -1096,8 +1090,9 @@ void qmp_migrate_set_speed(int64_t value, Error **errp)
s = migrate_get_current();
s->bandwidth_limit = value;
- if (s->file) {
- qemu_file_set_rate_limit(s->file, s->bandwidth_limit / XFER_LIMIT_RATIO);
+ if (s->to_dst_file) {
+ qemu_file_set_rate_limit(s->to_dst_file,
+ s->bandwidth_limit / XFER_LIMIT_RATIO);
}
}
@@ -1367,7 +1362,7 @@ out:
static int open_return_path_on_source(MigrationState *ms)
{
- ms->rp_state.from_dst_file = qemu_file_get_return_path(ms->file);
+ ms->rp_state.from_dst_file = qemu_file_get_return_path(ms->to_dst_file);
if (!ms->rp_state.from_dst_file) {
return -1;
}
@@ -1389,7 +1384,7 @@ static int await_return_path_close_on_source(MigrationState *ms)
* rp_thread will exit, however if there's an error we need to cause
* it to exit.
*/
- if (qemu_file_get_error(ms->file) && ms->rp_state.from_dst_file) {
+ if (qemu_file_get_error(ms->to_dst_file) && ms->rp_state.from_dst_file) {
/*
* shutdown(2), if we have it, will cause it to unblock if it's stuck
* waiting for the destination.
@@ -1436,7 +1431,7 @@ static int postcopy_start(MigrationState *ms, bool *old_vm_running)
* Cause any non-postcopiable, but iterative devices to
* send out their final data.
*/
- qemu_savevm_state_complete_precopy(ms->file, true);
+ qemu_savevm_state_complete_precopy(ms->to_dst_file, true);
/*
* in Finish migrate and with the io-lock held everything should
@@ -1454,9 +1449,9 @@ static int postcopy_start(MigrationState *ms, bool *old_vm_running)
* will notice we're in POSTCOPY_ACTIVE and not actually
* wrap their state up here
*/
- qemu_file_set_rate_limit(ms->file, INT64_MAX);
+ qemu_file_set_rate_limit(ms->to_dst_file, INT64_MAX);
/* Ping just for debugging, helps line traces up */
- qemu_savevm_send_ping(ms->file, 2);
+ qemu_savevm_send_ping(ms->to_dst_file, 2);
/*
* While loading the device state we may trigger page transfer
@@ -1490,7 +1485,7 @@ static int postcopy_start(MigrationState *ms, bool *old_vm_running)
qsb = qemu_buf_get(fb);
/* Now send that blob */
- if (qemu_savevm_send_packaged(ms->file, qsb)) {
+ if (qemu_savevm_send_packaged(ms->to_dst_file, qsb)) {
goto fail_closefb;
}
qemu_fclose(fb);
@@ -1502,9 +1497,9 @@ static int postcopy_start(MigrationState *ms, bool *old_vm_running)
* Although this ping is just for debug, it could potentially be
* used for getting a better measurement of downtime at the source.
*/
- qemu_savevm_send_ping(ms->file, 4);
+ qemu_savevm_send_ping(ms->to_dst_file, 4);
- ret = qemu_file_get_error(ms->file);
+ ret = qemu_file_get_error(ms->to_dst_file);
if (ret) {
error_report("postcopy_start: Migration stream errored");
migrate_set_state(&ms->state, MIGRATION_STATUS_POSTCOPY_ACTIVE,
@@ -1550,8 +1545,8 @@ static void migration_completion(MigrationState *s, int current_active_state,
ret = bdrv_inactivate_all();
}
if (ret >= 0) {
- qemu_file_set_rate_limit(s->file, INT64_MAX);
- qemu_savevm_state_complete_precopy(s->file, false);
+ qemu_file_set_rate_limit(s->to_dst_file, INT64_MAX);
+ qemu_savevm_state_complete_precopy(s->to_dst_file, false);
}
}
qemu_mutex_unlock_iothread();
@@ -1562,7 +1557,7 @@ static void migration_completion(MigrationState *s, int current_active_state,
} else if (s->state == MIGRATION_STATUS_POSTCOPY_ACTIVE) {
trace_migration_completion_postcopy_end();
- qemu_savevm_state_complete_postcopy(s->file);
+ qemu_savevm_state_complete_postcopy(s->to_dst_file);
trace_migration_completion_postcopy_end_after_complete();
}
@@ -1583,7 +1578,7 @@ static void migration_completion(MigrationState *s, int current_active_state,
}
}
- if (qemu_file_get_error(s->file)) {
+ if (qemu_file_get_error(s->to_dst_file)) {
trace_migration_completion_file_err();
goto fail;
}
@@ -1618,24 +1613,24 @@ static void *migration_thread(void *opaque)
rcu_register_thread();
- qemu_savevm_state_header(s->file);
+ qemu_savevm_state_header(s->to_dst_file);
if (migrate_postcopy_ram()) {
/* Now tell the dest that it should open its end so it can reply */
- qemu_savevm_send_open_return_path(s->file);
+ qemu_savevm_send_open_return_path(s->to_dst_file);
/* And do a ping that will make stuff easier to debug */
- qemu_savevm_send_ping(s->file, 1);
+ qemu_savevm_send_ping(s->to_dst_file, 1);
/*
* Tell the destination that we *might* want to do postcopy later;
* if the other end can't do postcopy it should fail now, nice and
* early.
*/
- qemu_savevm_send_postcopy_advise(s->file);
+ qemu_savevm_send_postcopy_advise(s->to_dst_file);
}
- qemu_savevm_state_begin(s->file, &s->params);
+ qemu_savevm_state_begin(s->to_dst_file, &s->params);
s->setup_time = qemu_clock_get_ms(QEMU_CLOCK_HOST) - setup_start;
current_active_state = MIGRATION_STATUS_ACTIVE;
@@ -1649,10 +1644,10 @@ static void *migration_thread(void *opaque)
int64_t current_time;
uint64_t pending_size;
- if (!qemu_file_rate_limit(s->file)) {
+ if (!qemu_file_rate_limit(s->to_dst_file)) {
uint64_t pend_post, pend_nonpost;
- qemu_savevm_state_pending(s->file, max_size, &pend_nonpost,
+ qemu_savevm_state_pending(s->to_dst_file, max_size, &pend_nonpost,
&pend_post);
pending_size = pend_nonpost + pend_post;
trace_migrate_pending(pending_size, max_size,
@@ -1673,7 +1668,7 @@ static void *migration_thread(void *opaque)
continue;
}
/* Just another iteration step */
- qemu_savevm_state_iterate(s->file, entered_postcopy);
+ qemu_savevm_state_iterate(s->to_dst_file, entered_postcopy);
} else {
trace_migration_thread_low_pending(pending_size);
migration_completion(s, current_active_state,
@@ -1682,7 +1677,7 @@ static void *migration_thread(void *opaque)
}
}
- if (qemu_file_get_error(s->file)) {
+ if (qemu_file_get_error(s->to_dst_file)) {
migrate_set_state(&s->state, current_active_state,
MIGRATION_STATUS_FAILED);
trace_migration_thread_file_err();
@@ -1690,7 +1685,8 @@ static void *migration_thread(void *opaque)
}
current_time = qemu_clock_get_ms(QEMU_CLOCK_REALTIME);
if (current_time >= initial_time + BUFFER_DELAY) {
- uint64_t transferred_bytes = qemu_ftell(s->file) - initial_bytes;
+ uint64_t transferred_bytes = qemu_ftell(s->to_dst_file) -
+ initial_bytes;
uint64_t time_spent = current_time - initial_time;
double bandwidth = (double)transferred_bytes / time_spent;
max_size = bandwidth * migrate_max_downtime() / 1000000;
@@ -1706,11 +1702,11 @@ static void *migration_thread(void *opaque)
s->expected_downtime = s->dirty_bytes_rate / bandwidth;
}
- qemu_file_reset_rate_limit(s->file);
+ qemu_file_reset_rate_limit(s->to_dst_file);
initial_time = current_time;
- initial_bytes = qemu_ftell(s->file);
+ initial_bytes = qemu_ftell(s->to_dst_file);
}
- if (qemu_file_rate_limit(s->file)) {
+ if (qemu_file_rate_limit(s->to_dst_file)) {
/* usleep expects microseconds */
g_usleep((initial_time + BUFFER_DELAY - current_time)*1000);
}
@@ -1724,7 +1720,7 @@ static void *migration_thread(void *opaque)
qemu_mutex_lock_iothread();
qemu_savevm_state_cleanup();
if (s->state == MIGRATION_STATUS_COMPLETED) {
- uint64_t transferred_bytes = qemu_ftell(s->file);
+ uint64_t transferred_bytes = qemu_ftell(s->to_dst_file);
s->total_time = end_time - s->total_time;
if (!entered_postcopy) {
s->downtime = end_time - start_time;
@@ -1752,7 +1748,7 @@ void migrate_fd_connect(MigrationState *s)
s->expected_downtime = max_downtime/1000000;
s->cleanup_bh = qemu_bh_new(migrate_fd_cleanup, s);
- qemu_file_set_rate_limit(s->file,
+ qemu_file_set_rate_limit(s->to_dst_file,
s->bandwidth_limit / XFER_LIMIT_RATIO);
/* Notify before starting migration thread */
diff --git a/migration/postcopy-ram.c b/migration/postcopy-ram.c
index 02b28edb72..254c629d48 100644
--- a/migration/postcopy-ram.c
+++ b/migration/postcopy-ram.c
@@ -725,7 +725,8 @@ void postcopy_discard_send_range(MigrationState *ms, PostcopyDiscardState *pds,
if (pds->cur_entry == MAX_DISCARDS_PER_COMMAND) {
/* Full set, ship it! */
- qemu_savevm_send_postcopy_ram_discard(ms->file, pds->ramblock_name,
+ qemu_savevm_send_postcopy_ram_discard(ms->to_dst_file,
+ pds->ramblock_name,
pds->cur_entry,
pds->start_list,
pds->length_list);
@@ -745,7 +746,8 @@ void postcopy_discard_send_finish(MigrationState *ms, PostcopyDiscardState *pds)
{
/* Anything unsent? */
if (pds->cur_entry) {
- qemu_savevm_send_postcopy_ram_discard(ms->file, pds->ramblock_name,
+ qemu_savevm_send_postcopy_ram_discard(ms->to_dst_file,
+ pds->ramblock_name,
pds->cur_entry,
pds->start_list,
pds->length_list);
diff --git a/migration/ram.c b/migration/ram.c
index 40d05330ab..3cdfea4a5c 100644
--- a/migration/ram.c
+++ b/migration/ram.c
@@ -729,7 +729,7 @@ static int save_zero_page(QEMUFile *f, RAMBlock *block, ram_addr_t offset,
* @last_stage: if we are at the completion stage
* @bytes_transferred: increase it with the number of transferred bytes
*/
-static int ram_save_page(QEMUFile *f, RAMBlock* block, ram_addr_t offset,
+static int ram_save_page(QEMUFile *f, PageSearchStatus *pss,
bool last_stage, uint64_t *bytes_transferred)
{
int pages = -1;
@@ -738,6 +738,8 @@ static int ram_save_page(QEMUFile *f, RAMBlock* block, ram_addr_t offset,
uint8_t *p;
int ret;
bool send_async = true;
+ RAMBlock *block = pss->block;
+ ram_addr_t offset = pss->offset;
p = block->host + offset;
@@ -912,14 +914,16 @@ static int compress_page_with_multi_thread(QEMUFile *f, RAMBlock *block,
* @last_stage: if we are at the completion stage
* @bytes_transferred: increase it with the number of transferred bytes
*/
-static int ram_save_compressed_page(QEMUFile *f, RAMBlock *block,
- ram_addr_t offset, bool last_stage,
+static int ram_save_compressed_page(QEMUFile *f, PageSearchStatus *pss,
+ bool last_stage,
uint64_t *bytes_transferred)
{
int pages = -1;
uint64_t bytes_xmit;
uint8_t *p;
int ret;
+ RAMBlock *block = pss->block;
+ ram_addr_t offset = pss->offset;
p = block->host + offset;
@@ -1229,7 +1233,7 @@ err:
* Returns: Number of pages written.
*/
static int ram_save_target_page(MigrationState *ms, QEMUFile *f,
- RAMBlock *block, ram_addr_t offset,
+ PageSearchStatus *pss,
bool last_stage,
uint64_t *bytes_transferred,
ram_addr_t dirty_ram_abs)
@@ -1240,11 +1244,11 @@ static int ram_save_target_page(MigrationState *ms, QEMUFile *f,
if (migration_bitmap_clear_dirty(dirty_ram_abs)) {
unsigned long *unsentmap;
if (compression_switch && migrate_use_compression()) {
- res = ram_save_compressed_page(f, block, offset,
+ res = ram_save_compressed_page(f, pss,
last_stage,
bytes_transferred);
} else {
- res = ram_save_page(f, block, offset, last_stage,
+ res = ram_save_page(f, pss, last_stage,
bytes_transferred);
}
@@ -1260,7 +1264,7 @@ static int ram_save_target_page(MigrationState *ms, QEMUFile *f,
* to the stream.
*/
if (res > 0) {
- last_sent_block = block;
+ last_sent_block = pss->block;
}
}
@@ -1284,26 +1288,27 @@ static int ram_save_target_page(MigrationState *ms, QEMUFile *f,
* @bytes_transferred: increase it with the number of transferred bytes
* @dirty_ram_abs: Address of the start of the dirty page in ram_addr_t space
*/
-static int ram_save_host_page(MigrationState *ms, QEMUFile *f, RAMBlock *block,
- ram_addr_t *offset, bool last_stage,
+static int ram_save_host_page(MigrationState *ms, QEMUFile *f,
+ PageSearchStatus *pss,
+ bool last_stage,
uint64_t *bytes_transferred,
ram_addr_t dirty_ram_abs)
{
int tmppages, pages = 0;
do {
- tmppages = ram_save_target_page(ms, f, block, *offset, last_stage,
+ tmppages = ram_save_target_page(ms, f, pss, last_stage,
bytes_transferred, dirty_ram_abs);
if (tmppages < 0) {
return tmppages;
}
pages += tmppages;
- *offset += TARGET_PAGE_SIZE;
+ pss->offset += TARGET_PAGE_SIZE;
dirty_ram_abs += TARGET_PAGE_SIZE;
- } while (*offset & (qemu_host_page_size - 1));
+ } while (pss->offset & (qemu_host_page_size - 1));
/* The offset we leave with is the last one we looked at */
- *offset -= TARGET_PAGE_SIZE;
+ pss->offset -= TARGET_PAGE_SIZE;
return pages;
}
@@ -1351,7 +1356,7 @@ static int ram_find_and_save_block(QEMUFile *f, bool last_stage,
}
if (found) {
- pages = ram_save_host_page(ms, f, pss.block, &pss.offset,
+ pages = ram_save_host_page(ms, f, &pss,
last_stage, bytes_transferred,
dirty_ram_abs);
}
@@ -2124,28 +2129,24 @@ static int load_xbzrle(QEMUFile *f, ram_addr_t addr, void *host)
* Returns a pointer from within the RCU-protected ram_list.
*/
/*
- * Read a RAMBlock ID from the stream f, find the host address of the
- * start of that block and add on 'offset'
+ * Read a RAMBlock ID from the stream f.
*
* f: Stream to read from
- * offset: Offset within the block
* flags: Page flags (mostly to see if it's a continuation of previous block)
*/
-static inline void *host_from_stream_offset(QEMUFile *f,
- ram_addr_t offset,
- int flags)
+static inline RAMBlock *ram_block_from_stream(QEMUFile *f,
+ int flags)
{
static RAMBlock *block = NULL;
char id[256];
uint8_t len;
if (flags & RAM_SAVE_FLAG_CONTINUE) {
- if (!block || block->max_length <= offset) {
+ if (!block) {
error_report("Ack, bad migration stream!");
return NULL;
}
-
- return block->host + offset;
+ return block;
}
len = qemu_get_byte(f);
@@ -2153,12 +2154,22 @@ static inline void *host_from_stream_offset(QEMUFile *f,
id[len] = 0;
block = qemu_ram_block_by_name(id);
- if (block && block->max_length > offset) {
- return block->host + offset;
+ if (!block) {
+ error_report("Can't find block %s", id);
+ return NULL;
}
- error_report("Can't find block %s", id);
- return NULL;
+ return block;
+}
+
+static inline void *host_from_ram_block_offset(RAMBlock *block,
+ ram_addr_t offset)
+{
+ if (!offset_in_ramblock(block, offset)) {
+ return NULL;
+ }
+
+ return block->host + offset;
}
/*
@@ -2302,7 +2313,9 @@ static int ram_load_postcopy(QEMUFile *f)
trace_ram_load_postcopy_loop((uint64_t)addr, flags);
place_needed = false;
if (flags & (RAM_SAVE_FLAG_COMPRESS | RAM_SAVE_FLAG_PAGE)) {
- host = host_from_stream_offset(f, addr, flags);
+ RAMBlock *block = ram_block_from_stream(f, flags);
+
+ host = host_from_ram_block_offset(block, addr);
if (!host) {
error_report("Illegal RAM offset " RAM_ADDR_FMT, addr);
ret = -EINVAL;
@@ -2433,7 +2446,9 @@ static int ram_load(QEMUFile *f, void *opaque, int version_id)
if (flags & (RAM_SAVE_FLAG_COMPRESS | RAM_SAVE_FLAG_PAGE |
RAM_SAVE_FLAG_COMPRESS_PAGE | RAM_SAVE_FLAG_XBZRLE)) {
- host = host_from_stream_offset(f, addr, flags);
+ RAMBlock *block = ram_block_from_stream(f, flags);
+
+ host = host_from_ram_block_offset(block, addr);
if (!host) {
error_report("Illegal RAM offset " RAM_ADDR_FMT, addr);
ret = -EINVAL;
diff --git a/migration/rdma.c b/migration/rdma.c
index 86a13b899f..bcae1e81b3 100644
--- a/migration/rdma.c
+++ b/migration/rdma.c
@@ -3504,7 +3504,7 @@ void rdma_start_outgoing_migration(void *opaque,
trace_rdma_start_outgoing_migration_after_rdma_connect();
- s->file = qemu_fopen_rdma(rdma, "wb");
+ s->to_dst_file = qemu_fopen_rdma(rdma, "wb");
migrate_fd_connect(s);
return;
err:
diff --git a/migration/savevm.c b/migration/savevm.c
index 954988d121..94f2894243 100644
--- a/migration/savevm.c
+++ b/migration/savevm.c
@@ -299,8 +299,8 @@ static int configuration_post_load(void *opaque, int version_id)
const char *current_name = MACHINE_GET_CLASS(current_machine)->name;
if (strncmp(state->name, current_name, state->len) != 0) {
- error_report("Machine type received is '%s' and local is '%s'",
- state->name, current_name);
+ error_report("Machine type received is '%.*s' and local is '%s'",
+ (int) state->len, state->name, current_name);
return -EINVAL;
}
return 0;
@@ -1163,7 +1163,7 @@ static int qemu_savevm_state(QEMUFile *f, Error **errp)
.shared = 0
};
MigrationState *ms = migrate_init(&params);
- ms->file = f;
+ ms->to_dst_file = f;
if (qemu_savevm_state_blocked(errp)) {
return -EINVAL;
@@ -1718,90 +1718,118 @@ void loadvm_free_handlers(MigrationIncomingState *mis)
}
}
+static int
+qemu_loadvm_section_start_full(QEMUFile *f, MigrationIncomingState *mis)
+{
+ uint32_t instance_id, version_id, section_id;
+ SaveStateEntry *se;
+ LoadStateEntry *le;
+ char idstr[256];
+ int ret;
+
+ /* Read section start */
+ section_id = qemu_get_be32(f);
+ if (!qemu_get_counted_string(f, idstr)) {
+ error_report("Unable to read ID string for section %u",
+ section_id);
+ return -EINVAL;
+ }
+ instance_id = qemu_get_be32(f);
+ version_id = qemu_get_be32(f);
+
+ trace_qemu_loadvm_state_section_startfull(section_id, idstr,
+ instance_id, version_id);
+ /* Find savevm section */
+ se = find_se(idstr, instance_id);
+ if (se == NULL) {
+ error_report("Unknown savevm section or instance '%s' %d",
+ idstr, instance_id);
+ return -EINVAL;
+ }
+
+ /* Validate version */
+ if (version_id > se->version_id) {
+ error_report("savevm: unsupported version %d for '%s' v%d",
+ version_id, idstr, se->version_id);
+ return -EINVAL;
+ }
+
+ /* Add entry */
+ le = g_malloc0(sizeof(*le));
+
+ le->se = se;
+ le->section_id = section_id;
+ le->version_id = version_id;
+ QLIST_INSERT_HEAD(&mis->loadvm_handlers, le, entry);
+
+ ret = vmstate_load(f, le->se, le->version_id);
+ if (ret < 0) {
+ error_report("error while loading state for instance 0x%x of"
+ " device '%s'", instance_id, idstr);
+ return ret;
+ }
+ if (!check_section_footer(f, le)) {
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int
+qemu_loadvm_section_part_end(QEMUFile *f, MigrationIncomingState *mis)
+{
+ uint32_t section_id;
+ LoadStateEntry *le;
+ int ret;
+
+ section_id = qemu_get_be32(f);
+
+ trace_qemu_loadvm_state_section_partend(section_id);
+ QLIST_FOREACH(le, &mis->loadvm_handlers, entry) {
+ if (le->section_id == section_id) {
+ break;
+ }
+ }
+ if (le == NULL) {
+ error_report("Unknown savevm section %d", section_id);
+ return -EINVAL;
+ }
+
+ ret = vmstate_load(f, le->se, le->version_id);
+ if (ret < 0) {
+ error_report("error while loading state section id %d(%s)",
+ section_id, le->se->idstr);
+ return ret;
+ }
+ if (!check_section_footer(f, le)) {
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
static int qemu_loadvm_state_main(QEMUFile *f, MigrationIncomingState *mis)
{
uint8_t section_type;
int ret;
while ((section_type = qemu_get_byte(f)) != QEMU_VM_EOF) {
- uint32_t instance_id, version_id, section_id;
- SaveStateEntry *se;
- LoadStateEntry *le;
- char idstr[256];
trace_qemu_loadvm_state_section(section_type);
switch (section_type) {
case QEMU_VM_SECTION_START:
case QEMU_VM_SECTION_FULL:
- /* Read section start */
- section_id = qemu_get_be32(f);
- if (!qemu_get_counted_string(f, idstr)) {
- error_report("Unable to read ID string for section %u",
- section_id);
- return -EINVAL;
- }
- instance_id = qemu_get_be32(f);
- version_id = qemu_get_be32(f);
-
- trace_qemu_loadvm_state_section_startfull(section_id, idstr,
- instance_id, version_id);
- /* Find savevm section */
- se = find_se(idstr, instance_id);
- if (se == NULL) {
- error_report("Unknown savevm section or instance '%s' %d",
- idstr, instance_id);
- return -EINVAL;
- }
-
- /* Validate version */
- if (version_id > se->version_id) {
- error_report("savevm: unsupported version %d for '%s' v%d",
- version_id, idstr, se->version_id);
- return -EINVAL;
- }
-
- /* Add entry */
- le = g_malloc0(sizeof(*le));
-
- le->se = se;
- le->section_id = section_id;
- le->version_id = version_id;
- QLIST_INSERT_HEAD(&mis->loadvm_handlers, le, entry);
-
- ret = vmstate_load(f, le->se, le->version_id);
+ ret = qemu_loadvm_section_start_full(f, mis);
if (ret < 0) {
- error_report("error while loading state for instance 0x%x of"
- " device '%s'", instance_id, idstr);
return ret;
}
- if (!check_section_footer(f, le)) {
- return -EINVAL;
- }
break;
case QEMU_VM_SECTION_PART:
case QEMU_VM_SECTION_END:
- section_id = qemu_get_be32(f);
-
- trace_qemu_loadvm_state_section_partend(section_id);
- QLIST_FOREACH(le, &mis->loadvm_handlers, entry) {
- if (le->section_id == section_id) {
- break;
- }
- }
- if (le == NULL) {
- error_report("Unknown savevm section %d", section_id);
- return -EINVAL;
- }
-
- ret = vmstate_load(f, le->se, le->version_id);
+ ret = qemu_loadvm_section_part_end(f, mis);
if (ret < 0) {
- error_report("error while loading state section id %d(%s)",
- section_id, le->se->idstr);
return ret;
}
- if (!check_section_footer(f, le)) {
- return -EINVAL;
- }
break;
case QEMU_VM_COMMAND:
ret = loadvm_process_command(f);
diff --git a/migration/tcp.c b/migration/tcp.c
index ae80e9443d..e888a4e490 100644
--- a/migration/tcp.c
+++ b/migration/tcp.c
@@ -39,11 +39,11 @@ static void tcp_wait_for_connect(int fd, Error *err, void *opaque)
if (fd < 0) {
DPRINTF("migrate connect error: %s\n", error_get_pretty(err));
- s->file = NULL;
+ s->to_dst_file = NULL;
migrate_fd_error(s);
} else {
DPRINTF("migrate connect success\n");
- s->file = qemu_fopen_socket(fd, "wb");
+ s->to_dst_file = qemu_fopen_socket(fd, "wb");
migrate_fd_connect(s);
}
}
diff --git a/migration/unix.c b/migration/unix.c
index a721c4aaf3..d9aac36b9a 100644
--- a/migration/unix.c
+++ b/migration/unix.c
@@ -39,11 +39,11 @@ static void unix_wait_for_connect(int fd, Error *err, void *opaque)
if (fd < 0) {
DPRINTF("migrate connect error: %s\n", error_get_pretty(err));
- s->file = NULL;
+ s->to_dst_file = NULL;
migrate_fd_error(s);
} else {
DPRINTF("migrate connect success\n");
- s->file = qemu_fopen_socket(fd, "wb");
+ s->to_dst_file = qemu_fopen_socket(fd, "wb");
migrate_fd_connect(s);
}
}
diff --git a/module-common.c b/module-common.c
index 50c67500b1..0a3cb8aeab 100644
--- a/module-common.c
+++ b/module-common.c
@@ -1,4 +1,4 @@
-#include "config-host.h"
+#include "qemu/osdep.h"
#include "qemu/module.h"
void qemu_module_dummy(void)
diff --git a/monitor.c b/monitor.c
index c53a453c7c..73eac17952 100644
--- a/monitor.c
+++ b/monitor.c
@@ -21,6 +21,7 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
+#include "qemu/osdep.h"
#include <dirent.h>
#include "hw/hw.h"
#include "monitor/qdev.h"
@@ -59,7 +60,6 @@
#include "qapi/qmp/json-streamer.h"
#include "qapi/qmp/json-parser.h"
#include <qom/object_interfaces.h>
-#include "qemu/osdep.h"
#include "cpu.h"
#include "trace.h"
#include "trace/control.h"
diff --git a/nbd/client.c b/nbd/client.c
index 83df7ba378..f07cb4822d 100644
--- a/nbd/client.c
+++ b/nbd/client.c
@@ -16,6 +16,7 @@
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
+#include "qemu/osdep.h"
#include "nbd-internal.h"
static int nbd_errno_to_system_errno(int err)
diff --git a/nbd/common.c b/nbd/common.c
index 7b089b0f3b..178d4a7ff2 100644
--- a/nbd/common.c
+++ b/nbd/common.c
@@ -16,6 +16,7 @@
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
+#include "qemu/osdep.h"
#include "nbd-internal.h"
ssize_t nbd_wr_sync(int fd, void *buffer, size_t size, bool do_read)
diff --git a/nbd/server.c b/nbd/server.c
index 1ec79cf411..43135306b4 100644
--- a/nbd/server.c
+++ b/nbd/server.c
@@ -16,6 +16,7 @@
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
+#include "qemu/osdep.h"
#include "nbd-internal.h"
static int system_errno_to_nbd_errno(int err)
diff --git a/net/checksum.c b/net/checksum.c
index 14c08550e0..b5016ab40c 100644
--- a/net/checksum.c
+++ b/net/checksum.c
@@ -15,6 +15,7 @@
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
+#include "qemu/osdep.h"
#include "qemu-common.h"
#include "net/checksum.h"
diff --git a/net/dump.c b/net/dump.c
index 88d9582334..dc0f33948d 100644
--- a/net/dump.c
+++ b/net/dump.c
@@ -22,6 +22,7 @@
* THE SOFTWARE.
*/
+#include "qemu/osdep.h"
#include "clients.h"
#include "qemu-common.h"
#include "qemu/error-report.h"
diff --git a/net/eth.c b/net/eth.c
index 7c61132cbb..7e32d274c7 100644
--- a/net/eth.c
+++ b/net/eth.c
@@ -15,6 +15,7 @@
*
*/
+#include "qemu/osdep.h"
#include "net/eth.h"
#include "net/checksum.h"
#include "qemu-common.h"
diff --git a/net/filter-buffer.c b/net/filter-buffer.c
index 57be149413..2353d5bc75 100644
--- a/net/filter-buffer.c
+++ b/net/filter-buffer.c
@@ -6,6 +6,7 @@
* later. See the COPYING file in the top-level directory.
*/
+#include "qemu/osdep.h"
#include "net/filter.h"
#include "net/queue.h"
#include "qemu-common.h"
diff --git a/net/filter.c b/net/filter.c
index 5d90f83429..d2a514eb8d 100644
--- a/net/filter.c
+++ b/net/filter.c
@@ -6,6 +6,7 @@
* later. See the COPYING file in the top-level directory.
*/
+#include "qemu/osdep.h"
#include "qemu-common.h"
#include "qapi/qmp/qerror.h"
#include "qemu/error-report.h"
@@ -15,7 +16,6 @@
#include "net/vhost_net.h"
#include "qom/object_interfaces.h"
#include "qemu/iov.h"
-#include "qapi/string-output-visitor.h"
ssize_t qemu_netfilter_receive(NetFilterState *nf,
NetFilterDirection direction,
@@ -34,6 +34,22 @@ ssize_t qemu_netfilter_receive(NetFilterState *nf,
return 0;
}
+static NetFilterState *netfilter_next(NetFilterState *nf,
+ NetFilterDirection dir)
+{
+ NetFilterState *next;
+
+ if (dir == NET_FILTER_DIRECTION_TX) {
+ /* forward walk through filters */
+ next = QTAILQ_NEXT(nf, next);
+ } else {
+ /* reverse order */
+ next = QTAILQ_PREV(nf, NetFilterHead, next);
+ }
+
+ return next;
+}
+
ssize_t qemu_netfilter_pass_to_next(NetClientState *sender,
unsigned flags,
const struct iovec *iov,
@@ -43,7 +59,7 @@ ssize_t qemu_netfilter_pass_to_next(NetClientState *sender,
int ret = 0;
int direction;
NetFilterState *nf = opaque;
- NetFilterState *next = QTAILQ_NEXT(nf, next);
+ NetFilterState *next = NULL;
if (!sender || !sender->peer) {
/* no receiver, or sender been deleted, no need to pass it further */
@@ -61,6 +77,7 @@ ssize_t qemu_netfilter_pass_to_next(NetClientState *sender,
direction = nf->direction;
}
+ next = netfilter_next(nf, direction);
while (next) {
/*
* if qemu_netfilter_pass_to_next been called, means that
@@ -73,7 +90,7 @@ ssize_t qemu_netfilter_pass_to_next(NetClientState *sender,
if (ret) {
return ret;
}
- next = QTAILQ_NEXT(next, next);
+ next = netfilter_next(next, direction);
}
/*
@@ -135,10 +152,6 @@ static void netfilter_complete(UserCreatable *uc, Error **errp)
NetFilterClass *nfc = NETFILTER_GET_CLASS(uc);
int queues;
Error *local_err = NULL;
- char *str, *info;
- ObjectProperty *prop;
- ObjectPropertyIterator iter;
- StringOutputVisitor *ov;
if (!nf->netdev_id) {
error_setg(errp, "Parameter 'netdev' is required");
@@ -172,23 +185,6 @@ static void netfilter_complete(UserCreatable *uc, Error **errp)
}
}
QTAILQ_INSERT_TAIL(&nf->netdev->filters, nf, next);
-
- /* generate info str */
- object_property_iter_init(&iter, OBJECT(nf));
- while ((prop = object_property_iter_next(&iter))) {
- if (!strcmp(prop->name, "type")) {
- continue;
- }
- ov = string_output_visitor_new(false);
- object_property_get(OBJECT(nf), string_output_get_visitor(ov),
- prop->name, errp);
- str = string_output_get_string(ov);
- string_output_visitor_cleanup(ov);
- info = g_strdup_printf(",%s=%s", prop->name, str);
- g_strlcat(nf->info_str, info, sizeof(nf->info_str));
- g_free(str);
- g_free(info);
- }
}
static void netfilter_finalize(Object *obj)
diff --git a/net/hub.c b/net/hub.c
index 9ae9f012cb..b6d44fd75b 100644
--- a/net/hub.c
+++ b/net/hub.c
@@ -12,6 +12,7 @@
*
*/
+#include "qemu/osdep.h"
#include "monitor/monitor.h"
#include "net/net.h"
#include "clients.h"
diff --git a/net/l2tpv3.c b/net/l2tpv3.c
index 21d6119ed4..824161c5b8 100644
--- a/net/l2tpv3.c
+++ b/net/l2tpv3.c
@@ -23,9 +23,9 @@
* THE SOFTWARE.
*/
+#include "qemu/osdep.h"
#include <linux/ip.h>
#include <netdb.h>
-#include "config-host.h"
#include "net/net.h"
#include "clients.h"
#include "qemu-common.h"
diff --git a/net/net.c b/net/net.c
index 87dd3568dc..c5e414fe3c 100644
--- a/net/net.c
+++ b/net/net.c
@@ -21,7 +21,7 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
-#include "config-host.h"
+#include "qemu/osdep.h"
#include "net/net.h"
#include "clients.h"
@@ -45,6 +45,7 @@
#include "qapi/dealloc-visitor.h"
#include "sysemu/sysemu.h"
#include "net/filter.h"
+#include "qapi/string-output-visitor.h"
/* Net bridge is currently not supported for W32. */
#if !defined(_WIN32)
@@ -580,11 +581,21 @@ static ssize_t filter_receive_iov(NetClientState *nc,
ssize_t ret = 0;
NetFilterState *nf = NULL;
- QTAILQ_FOREACH(nf, &nc->filters, next) {
- ret = qemu_netfilter_receive(nf, direction, sender, flags, iov,
- iovcnt, sent_cb);
- if (ret) {
- return ret;
+ if (direction == NET_FILTER_DIRECTION_TX) {
+ QTAILQ_FOREACH(nf, &nc->filters, next) {
+ ret = qemu_netfilter_receive(nf, direction, sender, flags, iov,
+ iovcnt, sent_cb);
+ if (ret) {
+ return ret;
+ }
+ }
+ } else {
+ QTAILQ_FOREACH_REVERSE(nf, &nc->filters, NetFilterHead, next) {
+ ret = qemu_netfilter_receive(nf, direction, sender, flags, iov,
+ iovcnt, sent_cb);
+ if (ret) {
+ return ret;
+ }
}
}
@@ -1185,6 +1196,30 @@ void qmp_netdev_del(const char *id, Error **errp)
qemu_opts_del(opts);
}
+static void netfilter_print_info(Monitor *mon, NetFilterState *nf)
+{
+ char *str;
+ ObjectProperty *prop;
+ ObjectPropertyIterator iter;
+ StringOutputVisitor *ov;
+
+ /* generate info str */
+ object_property_iter_init(&iter, OBJECT(nf));
+ while ((prop = object_property_iter_next(&iter))) {
+ if (!strcmp(prop->name, "type")) {
+ continue;
+ }
+ ov = string_output_visitor_new(false);
+ object_property_get(OBJECT(nf), string_output_get_visitor(ov),
+ prop->name, NULL);
+ str = string_output_get_string(ov);
+ string_output_visitor_cleanup(ov);
+ monitor_printf(mon, ",%s=%s", prop->name, str);
+ g_free(str);
+ }
+ monitor_printf(mon, "\n");
+}
+
void print_net_client(Monitor *mon, NetClientState *nc)
{
NetFilterState *nf;
@@ -1198,9 +1233,10 @@ void print_net_client(Monitor *mon, NetClientState *nc)
}
QTAILQ_FOREACH(nf, &nc->filters, next) {
char *path = object_get_canonical_path_component(OBJECT(nf));
- monitor_printf(mon, " - %s: type=%s%s\n", path,
- object_get_typename(OBJECT(nf)),
- nf->info_str);
+
+ monitor_printf(mon, " - %s: type=%s", path,
+ object_get_typename(OBJECT(nf)));
+ netfilter_print_info(mon, nf);
g_free(path);
}
}
diff --git a/net/netmap.c b/net/netmap.c
index 555836829e..971032120c 100644
--- a/net/netmap.c
+++ b/net/netmap.c
@@ -23,11 +23,10 @@
*/
+#include "qemu/osdep.h"
#include <sys/ioctl.h>
#include <net/if.h>
#include <sys/mman.h>
-#include <stdint.h>
-#include <stdio.h>
#define NETMAP_WITH_LIBS
#include <net/netmap.h>
#include <net/netmap_user.h>
@@ -39,21 +38,12 @@
#include "qemu/error-report.h"
#include "qemu/iov.h"
-/* Private netmap device info. */
-typedef struct NetmapPriv {
- int fd;
- size_t memsize;
- void *mem;
- struct netmap_if *nifp;
- struct netmap_ring *rx;
- struct netmap_ring *tx;
- char fdname[PATH_MAX]; /* Normally "/dev/netmap". */
- char ifname[IFNAMSIZ];
-} NetmapPriv;
-
typedef struct NetmapState {
NetClientState nc;
- NetmapPriv me;
+ struct nm_desc *nmd;
+ char ifname[IFNAMSIZ];
+ struct netmap_ring *tx;
+ struct netmap_ring *rx;
bool read_poll;
bool write_poll;
struct iovec iov[IOV_MAX];
@@ -90,44 +80,23 @@ pkt_copy(const void *_src, void *_dst, int l)
* Open a netmap device. We assume there is only one queue
* (which is the case for the VALE bridge).
*/
-static void netmap_open(NetmapPriv *me, Error **errp)
+static struct nm_desc *netmap_open(const NetdevNetmapOptions *nm_opts,
+ Error **errp)
{
- int fd;
- int err;
- size_t l;
+ struct nm_desc *nmd;
struct nmreq req;
- me->fd = fd = open(me->fdname, O_RDWR);
- if (fd < 0) {
- error_setg_file_open(errp, errno, me->fdname);
- return;
- }
memset(&req, 0, sizeof(req));
- pstrcpy(req.nr_name, sizeof(req.nr_name), me->ifname);
- req.nr_ringid = NETMAP_NO_TX_POLL;
- req.nr_version = NETMAP_API;
- err = ioctl(fd, NIOCREGIF, &req);
- if (err) {
- error_setg_errno(errp, errno, "Unable to register %s", me->ifname);
- goto error;
- }
- l = me->memsize = req.nr_memsize;
- me->mem = mmap(0, l, PROT_WRITE | PROT_READ, MAP_SHARED, fd, 0);
- if (me->mem == MAP_FAILED) {
- error_setg_errno(errp, errno, "Unable to mmap netmap shared memory");
- me->mem = NULL;
- goto error;
+ nmd = nm_open(nm_opts->ifname, &req, NETMAP_NO_TX_POLL,
+ NULL);
+ if (nmd == NULL) {
+ error_setg_errno(errp, errno, "Failed to nm_open() %s",
+ nm_opts->ifname);
+ return NULL;
}
- me->nifp = NETMAP_IF(me->mem, req.nr_offset);
- me->tx = NETMAP_TXRING(me->nifp, 0);
- me->rx = NETMAP_RXRING(me->nifp, 0);
-
- return;
-
-error:
- close(me->fd);
+ return nmd;
}
static void netmap_send(void *opaque);
@@ -136,7 +105,7 @@ static void netmap_writable(void *opaque);
/* Set the event-loop handlers for the netmap backend. */
static void netmap_update_fd_handler(NetmapState *s)
{
- qemu_set_fd_handler(s->me.fd,
+ qemu_set_fd_handler(s->nmd->fd,
s->read_poll ? netmap_send : NULL,
s->write_poll ? netmap_writable : NULL,
s);
@@ -188,7 +157,7 @@ static ssize_t netmap_receive(NetClientState *nc,
const uint8_t *buf, size_t size)
{
NetmapState *s = DO_UPCAST(NetmapState, nc, nc);
- struct netmap_ring *ring = s->me.tx;
+ struct netmap_ring *ring = s->tx;
uint32_t i;
uint32_t idx;
uint8_t *dst;
@@ -218,7 +187,7 @@ static ssize_t netmap_receive(NetClientState *nc,
ring->slot[i].flags = 0;
pkt_copy(buf, dst, size);
ring->cur = ring->head = nm_ring_next(ring, i);
- ioctl(s->me.fd, NIOCTXSYNC, NULL);
+ ioctl(s->nmd->fd, NIOCTXSYNC, NULL);
return size;
}
@@ -227,7 +196,7 @@ static ssize_t netmap_receive_iov(NetClientState *nc,
const struct iovec *iov, int iovcnt)
{
NetmapState *s = DO_UPCAST(NetmapState, nc, nc);
- struct netmap_ring *ring = s->me.tx;
+ struct netmap_ring *ring = s->tx;
uint32_t last;
uint32_t idx;
uint8_t *dst;
@@ -284,7 +253,7 @@ static ssize_t netmap_receive_iov(NetClientState *nc,
/* Now update ring->cur and ring->head. */
ring->cur = ring->head = i;
- ioctl(s->me.fd, NIOCTXSYNC, NULL);
+ ioctl(s->nmd->fd, NIOCTXSYNC, NULL);
return iov_size(iov, iovcnt);
}
@@ -301,7 +270,7 @@ static void netmap_send_completed(NetClientState *nc, ssize_t len)
static void netmap_send(void *opaque)
{
NetmapState *s = opaque;
- struct netmap_ring *ring = s->me.rx;
+ struct netmap_ring *ring = s->rx;
/* Keep sending while there are available packets into the netmap
RX ring and the forwarding path towards the peer is open. */
@@ -349,10 +318,8 @@ static void netmap_cleanup(NetClientState *nc)
qemu_purge_queued_packets(nc);
netmap_poll(nc, false);
- munmap(s->me.mem, s->me.memsize);
- close(s->me.fd);
-
- s->me.fd = -1;
+ nm_close(s->nmd);
+ s->nmd = NULL;
}
/* Offloading manipulation support callbacks. */
@@ -383,17 +350,17 @@ static void netmap_set_vnet_hdr_len(NetClientState *nc, int len)
struct nmreq req;
/* Issue a NETMAP_BDG_VNET_HDR command to change the virtio-net header
- * length for the netmap adapter associated to 'me->ifname'.
+ * length for the netmap adapter associated to 's->ifname'.
*/
memset(&req, 0, sizeof(req));
- pstrcpy(req.nr_name, sizeof(req.nr_name), s->me.ifname);
+ pstrcpy(req.nr_name, sizeof(req.nr_name), s->ifname);
req.nr_version = NETMAP_API;
req.nr_cmd = NETMAP_BDG_VNET_HDR;
req.nr_arg1 = len;
- err = ioctl(s->me.fd, NIOCREGIF, &req);
+ err = ioctl(s->nmd->fd, NIOCREGIF, &req);
if (err) {
error_report("Unable to execute NETMAP_BDG_VNET_HDR on %s: %s",
- s->me.ifname, strerror(errno));
+ s->ifname, strerror(errno));
} else {
/* Keep track of the current length. */
s->vnet_hdr_len = len;
@@ -437,16 +404,12 @@ int net_init_netmap(const NetClientOptions *opts,
const char *name, NetClientState *peer, Error **errp)
{
const NetdevNetmapOptions *netmap_opts = opts->u.netmap;
+ struct nm_desc *nmd;
NetClientState *nc;
Error *err = NULL;
- NetmapPriv me;
NetmapState *s;
- pstrcpy(me.fdname, sizeof(me.fdname),
- netmap_opts->has_devname ? netmap_opts->devname : "/dev/netmap");
- /* Set default name for the port if not supplied. */
- pstrcpy(me.ifname, sizeof(me.ifname), netmap_opts->ifname);
- netmap_open(&me, &err);
+ nmd = netmap_open(netmap_opts, &err);
if (err) {
error_propagate(errp, err);
return -1;
@@ -454,8 +417,11 @@ int net_init_netmap(const NetClientOptions *opts,
/* Create the object. */
nc = qemu_new_net_client(&net_netmap_info, peer, "netmap", name);
s = DO_UPCAST(NetmapState, nc, nc);
- s->me = me;
+ s->nmd = nmd;
+ s->tx = NETMAP_TXRING(nmd->nifp, 0);
+ s->rx = NETMAP_RXRING(nmd->nifp, 0);
s->vnet_hdr_len = 0;
+ pstrcpy(s->ifname, sizeof(s->ifname), netmap_opts->ifname);
netmap_read_poll(s, true); /* Initially only poll for reads. */
return 0;
diff --git a/net/queue.c b/net/queue.c
index de8b9d31c6..9c32abdb8f 100644
--- a/net/queue.c
+++ b/net/queue.c
@@ -21,6 +21,7 @@
* THE SOFTWARE.
*/
+#include "qemu/osdep.h"
#include "net/queue.h"
#include "qemu/queue.h"
#include "net/net.h"
diff --git a/net/slirp.c b/net/slirp.c
index f505570adb..6b51fbc306 100644
--- a/net/slirp.c
+++ b/net/slirp.c
@@ -21,9 +21,9 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
+#include "qemu/osdep.h"
#include "net/slirp.h"
-#include "config-host.h"
#ifndef _WIN32
#include <pwd.h>
@@ -784,6 +784,9 @@ int net_slirp_parse_legacy(QemuOptsList *opts_list, const char *optarg, int *ret
return 0;
}
+ error_report("The '-net channel' option is deprecated. "
+ "Please use '-netdev user,guestfwd=...' instead.");
+
/* handle legacy -net channel,port:chr */
optarg += strlen("channel,");
diff --git a/net/socket.c b/net/socket.c
index e8605d4ded..e32e3cb996 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -21,7 +21,7 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
-#include "config-host.h"
+#include "qemu/osdep.h"
#include "net/net.h"
#include "clients.h"
diff --git a/net/tap-aix.c b/net/tap-aix.c
index e84fc39136..9d830b7a32 100644
--- a/net/tap-aix.c
+++ b/net/tap-aix.c
@@ -22,8 +22,8 @@
* THE SOFTWARE.
*/
+#include "qemu/osdep.h"
#include "tap_int.h"
-#include <stdio.h>
int tap_open(char *ifname, int ifname_size, int *vnet_hdr,
int vnet_hdr_required, int mq_required, Error **errp)
diff --git a/net/tap-bsd.c b/net/tap-bsd.c
index 0103a97bf6..83de19a646 100644
--- a/net/tap-bsd.c
+++ b/net/tap-bsd.c
@@ -22,6 +22,7 @@
* THE SOFTWARE.
*/
+#include "qemu/osdep.h"
#include "tap_int.h"
#include "qemu-common.h"
#include "sysemu/sysemu.h"
diff --git a/net/tap-haiku.c b/net/tap-haiku.c
index 2e738ec6a3..397e53235e 100644
--- a/net/tap-haiku.c
+++ b/net/tap-haiku.c
@@ -22,8 +22,8 @@
* THE SOFTWARE.
*/
+#include "qemu/osdep.h"
#include "tap_int.h"
-#include <stdio.h>
int tap_open(char *ifname, int ifname_size, int *vnet_hdr,
int vnet_hdr_required, int mq_required, Error **errp)
diff --git a/net/tap-linux.c b/net/tap-linux.c
index 5bd9d21898..0929cf76f5 100644
--- a/net/tap-linux.c
+++ b/net/tap-linux.c
@@ -23,6 +23,7 @@
* THE SOFTWARE.
*/
+#include "qemu/osdep.h"
#include "tap_int.h"
#include "tap-linux.h"
#include "net/tap.h"
diff --git a/net/tap-solaris.c b/net/tap-solaris.c
index 0f60f78dd0..e3907a8218 100644
--- a/net/tap-solaris.c
+++ b/net/tap-solaris.c
@@ -22,10 +22,10 @@
* THE SOFTWARE.
*/
+#include "qemu/osdep.h"
#include "tap_int.h"
#include "sysemu/sysemu.h"
-#include <sys/stat.h>
#include <sys/ethernet.h>
#include <sys/sockio.h>
#include <netinet/arp.h>
diff --git a/net/tap-win32.c b/net/tap-win32.c
index 7fddb20b51..38bbac0cd9 100644
--- a/net/tap-win32.c
+++ b/net/tap-win32.c
@@ -26,6 +26,7 @@
* distribution); if not, see <http://www.gnu.org/licenses/>.
*/
+#include "qemu/osdep.h"
#include "tap_int.h"
#include "qemu-common.h"
@@ -34,7 +35,6 @@
#include "net/tap.h" /* tap_has_ufo, ... */
#include "sysemu/sysemu.h"
#include "qemu/error-report.h"
-#include <stdio.h>
#include <windows.h>
#include <winioctl.h>
diff --git a/net/tap.c b/net/tap.c
index 85c4142d15..cfb6831988 100644
--- a/net/tap.c
+++ b/net/tap.c
@@ -23,12 +23,11 @@
* THE SOFTWARE.
*/
+#include "qemu/osdep.h"
#include "tap_int.h"
-#include "config-host.h"
#include <sys/ioctl.h>
-#include <sys/stat.h>
#include <sys/wait.h>
#include <sys/socket.h>
#include <net/if.h>
diff --git a/net/util.c b/net/util.c
index 7e9507679d..0b3dbfe5d3 100644
--- a/net/util.c
+++ b/net/util.c
@@ -22,9 +22,8 @@
* THE SOFTWARE.
*/
+#include "qemu/osdep.h"
#include "util.h"
-#include <errno.h>
-#include <stdlib.h>
int net_parse_macaddr(uint8_t *macaddr, const char *p)
{
diff --git a/net/vde.c b/net/vde.c
index 4475d929e6..973faf5090 100644
--- a/net/vde.c
+++ b/net/vde.c
@@ -21,7 +21,7 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
-#include "config-host.h"
+#include "qemu/osdep.h"
#include <libvdeplug.h>
diff --git a/net/vhost-user.c b/net/vhost-user.c
index e4dd089c5c..451dbbfb27 100644
--- a/net/vhost-user.c
+++ b/net/vhost-user.c
@@ -8,6 +8,7 @@
*
*/
+#include "qemu/osdep.h"
#include "clients.h"
#include "net/vhost_net.h"
#include "net/vhost-user.h"
diff --git a/numa.c b/numa.c
index 23a5d83024..e1a05698a9 100644
--- a/numa.c
+++ b/numa.c
@@ -22,6 +22,7 @@
* THE SOFTWARE.
*/
+#include "qemu/osdep.h"
#include "sysemu/numa.h"
#include "exec/cpu-common.h"
#include "qemu/bitmap.h"
diff --git a/os-posix.c b/os-posix.c
index e4da406f38..cce62ed92b 100644
--- a/os-posix.c
+++ b/os-posix.c
@@ -23,10 +23,7 @@
* THE SOFTWARE.
*/
-#include <unistd.h>
-#include <fcntl.h>
-#include <signal.h>
-#include <sys/types.h>
+#include "qemu/osdep.h"
#include <sys/wait.h>
/*needed for MAP_POPULATE before including qemu-options.h */
#include <sys/mman.h>
@@ -35,11 +32,11 @@
#include <libgen.h>
/* Needed early for CONFIG_BSD etc. */
-#include "config-host.h"
#include "sysemu/sysemu.h"
#include "net/slirp.h"
#include "qemu-options.h"
#include "qemu/rcu.h"
+#include "qemu/error-report.h"
#ifdef CONFIG_LINUX
#include <sys/prctl.h>
@@ -139,6 +136,8 @@ void os_parse_cmd_args(int index, const char *optarg)
switch (index) {
#ifdef CONFIG_SLIRP
case QEMU_OPTION_smb:
+ error_report("The -smb option is deprecated. "
+ "Please use '-netdev user,smb=...' instead.");
if (net_slirp_smb(optarg) < 0)
exit(1);
break;
diff --git a/os-win32.c b/os-win32.c
index cc09196d8b..ae9857448f 100644
--- a/os-win32.c
+++ b/os-win32.c
@@ -22,14 +22,9 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
+#include "qemu/osdep.h"
#include <windows.h>
#include <mmsystem.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <time.h>
-#include <errno.h>
-#include <sys/time.h>
-#include "config-host.h"
#include "sysemu/sysemu.h"
#include "qemu-options.h"
diff --git a/page_cache.c b/page_cache.c
index a9eb0769b3..cb8a69e964 100644
--- a/page_cache.c
+++ b/page_cache.c
@@ -12,13 +12,7 @@
*
*/
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/time.h>
-#include <sys/types.h>
-#include <stdbool.h>
+#include "qemu/osdep.h"
#include <glib.h>
#include "qemu-common.h"
diff --git a/pc-bios/openbios-ppc b/pc-bios/openbios-ppc
index a419bfd031..e44c0b3098 100644
--- a/pc-bios/openbios-ppc
+++ b/pc-bios/openbios-ppc
Binary files differ
diff --git a/pc-bios/openbios-sparc32 b/pc-bios/openbios-sparc32
index cf52787034..c75c835d54 100644
--- a/pc-bios/openbios-sparc32
+++ b/pc-bios/openbios-sparc32
Binary files differ
diff --git a/pc-bios/openbios-sparc64 b/pc-bios/openbios-sparc64
index 08eecdf225..b3304b44e7 100644
--- a/pc-bios/openbios-sparc64
+++ b/pc-bios/openbios-sparc64
Binary files differ
diff --git a/qapi/opts-visitor.c b/qapi/opts-visitor.c
index ef5fb8b815..eb7d85b0ec 100644
--- a/qapi/opts-visitor.c
+++ b/qapi/opts-visitor.c
@@ -10,6 +10,7 @@
*
*/
+#include "qemu/osdep.h"
#include "qemu-common.h"
#include "qapi/qmp/qerror.h"
#include "qapi/opts-visitor.h"
diff --git a/qapi/qapi-dealloc-visitor.c b/qapi/qapi-dealloc-visitor.c
index 737deab9e5..9340446633 100644
--- a/qapi/qapi-dealloc-visitor.c
+++ b/qapi/qapi-dealloc-visitor.c
@@ -11,6 +11,7 @@
*
*/
+#include "qemu/osdep.h"
#include "qapi/dealloc-visitor.h"
#include "qemu/queue.h"
#include "qemu-common.h"
diff --git a/qapi/qapi-util.c b/qapi/qapi-util.c
index bcdc94d5a9..8afb12eb43 100644
--- a/qapi/qapi-util.c
+++ b/qapi/qapi-util.c
@@ -10,8 +10,8 @@
*
*/
+#include "qemu/osdep.h"
#include "qemu-common.h"
-#include "qapi/error.h"
#include "qapi/util.h"
int qapi_enum_parse(const char * const lookup[], const char *buf,
diff --git a/qapi/qapi-visit-core.c b/qapi/qapi-visit-core.c
index 6d63e40234..8473d3c571 100644
--- a/qapi/qapi-visit-core.c
+++ b/qapi/qapi-visit-core.c
@@ -11,6 +11,7 @@
*
*/
+#include "qemu/osdep.h"
#include "qemu-common.h"
#include "qapi/qmp/qobject.h"
#include "qapi/qmp/qerror.h"
diff --git a/qapi/qmp-dispatch.c b/qapi/qmp-dispatch.c
index f36933de64..8f27c3456d 100644
--- a/qapi/qmp-dispatch.c
+++ b/qapi/qmp-dispatch.c
@@ -11,11 +11,11 @@
*
*/
+#include "qemu/osdep.h"
#include "qapi/qmp/types.h"
#include "qapi/qmp/dispatch.h"
#include "qapi/qmp/json-parser.h"
#include "qapi-types.h"
-#include "qapi/error.h"
#include "qapi/qmp/qerror.h"
static QDict *qmp_dispatch_check_obj(const QObject *request, Error **errp)
diff --git a/qapi/qmp-event.c b/qapi/qmp-event.c
index c0e435f994..8bba165bfb 100644
--- a/qapi/qmp-event.c
+++ b/qapi/qmp-event.c
@@ -11,7 +11,7 @@
*
*/
-#include <inttypes.h>
+#include "qemu/osdep.h"
#include "qemu-common.h"
#include "qapi/qmp-event.h"
diff --git a/qapi/qmp-input-visitor.c b/qapi/qmp-input-visitor.c
index 932b5f3ced..edb8bd2d68 100644
--- a/qapi/qmp-input-visitor.c
+++ b/qapi/qmp-input-visitor.c
@@ -11,6 +11,7 @@
*
*/
+#include "qemu/osdep.h"
#include "qapi/qmp-input-visitor.h"
#include "qapi/visitor-impl.h"
#include "qemu/queue.h"
diff --git a/qapi/qmp-output-visitor.c b/qapi/qmp-output-visitor.c
index 29899acd46..b064fb5a91 100644
--- a/qapi/qmp-output-visitor.c
+++ b/qapi/qmp-output-visitor.c
@@ -11,6 +11,7 @@
*
*/
+#include "qemu/osdep.h"
#include "qapi/qmp-output-visitor.h"
#include "qapi/visitor-impl.h"
#include "qemu/queue.h"
diff --git a/qapi/qmp-registry.c b/qapi/qmp-registry.c
index 3e4498a3f6..4ebfbccd46 100644
--- a/qapi/qmp-registry.c
+++ b/qapi/qmp-registry.c
@@ -12,8 +12,8 @@
*
*/
+#include "qemu/osdep.h"
#include <glib.h>
-#include <string.h>
#include "qapi/qmp/dispatch.h"
static QTAILQ_HEAD(QmpCommandList, QmpCommand) qmp_commands =
diff --git a/qapi/string-input-visitor.c b/qapi/string-input-visitor.c
index dee780a2da..8c5ff7e1d2 100644
--- a/qapi/string-input-visitor.c
+++ b/qapi/string-input-visitor.c
@@ -10,6 +10,7 @@
*
*/
+#include "qemu/osdep.h"
#include "qemu-common.h"
#include "qapi/string-input-visitor.h"
#include "qapi/visitor-impl.h"
diff --git a/qapi/string-output-visitor.c b/qapi/string-output-visitor.c
index b86ce2cd07..b04cec4cf7 100644
--- a/qapi/string-output-visitor.c
+++ b/qapi/string-output-visitor.c
@@ -10,6 +10,7 @@
*
*/
+#include "qemu/osdep.h"
#include "qemu-common.h"
#include "qapi/string-output-visitor.h"
#include "qapi/visitor-impl.h"
diff --git a/qdev-monitor.c b/qdev-monitor.c
index 3ce47109e3..81e3ff34a9 100644
--- a/qdev-monitor.c
+++ b/qdev-monitor.c
@@ -17,6 +17,7 @@
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
+#include "qemu/osdep.h"
#include "hw/qdev.h"
#include "hw/sysbus.h"
#include "monitor/monitor.h"
diff --git a/qemu-bridge-helper.c b/qemu-bridge-helper.c
index 36eb3bcfd6..830fb9e269 100644
--- a/qemu-bridge-helper.c
+++ b/qemu-bridge-helper.c
@@ -13,19 +13,10 @@
*
*/
-#include "config-host.h"
-
-#include <stdio.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <string.h>
-#include <stdlib.h>
-#include <stdbool.h>
-#include <ctype.h>
+#include "qemu/osdep.h"
+
#include <glib.h>
-#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/un.h>
diff --git a/qemu-char.c b/qemu-char.c
index 1605b30c33..927c47e503 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -21,6 +21,7 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
+#include "qemu/osdep.h"
#include "qemu-common.h"
#include "monitor/monitor.h"
#include "sysemu/sysemu.h"
@@ -37,11 +38,6 @@
#include "io/channel-file.h"
#include "io/channel-tls.h"
-#include <unistd.h>
-#include <fcntl.h>
-#include <time.h>
-#include <errno.h>
-#include <sys/time.h>
#include <zlib.h>
#ifndef _WIN32
@@ -58,7 +54,6 @@
#include <netdb.h>
#include <sys/select.h>
#ifdef CONFIG_BSD
-#include <sys/stat.h>
#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
#include <dev/ppbus/ppi.h>
#include <dev/ppbus/ppbconf.h>
@@ -72,7 +67,6 @@
#include <linux/parport.h>
#endif
#ifdef __sun__
-#include <sys/stat.h>
#include <sys/ethernet.h>
#include <sys/sockio.h>
#include <netinet/arp.h>
diff --git a/qemu-doc.texi b/qemu-doc.texi
index ca4d9de15e..212aba3c08 100644
--- a/qemu-doc.texi
+++ b/qemu-doc.texi
@@ -1237,9 +1237,9 @@ echo 100 100 > /proc/sys/net/ipv4/ping_group_range
When using the built-in TFTP server, the router is also the TFTP
server.
-When using the @option{-redir} option, TCP or UDP connections can be
-redirected from the host to the guest. It allows for example to
-redirect X11, telnet or SSH connections.
+When using the @option{'-netdev user,hostfwd=...'} option, TCP or UDP
+connections can be redirected from the host to the guest. It allows for
+example to redirect X11, telnet or SSH connections.
@subsection Connecting VLANs between QEMU instances
@@ -1889,7 +1889,8 @@ correctly instructs QEMU to shutdown at the appropriate moment.
@subsubsection Share a directory between Unix and Windows
-See @ref{sec_invocation} about the help of the option @option{-smb}.
+See @ref{sec_invocation} about the help of the option
+@option{'-netdev user,smb=...'}.
@subsubsection Windows XP security problem
diff --git a/qemu-nbd.c b/qemu-nbd.c
index ede4a54d4e..d374015125 100644
--- a/qemu-nbd.c
+++ b/qemu-nbd.c
@@ -16,6 +16,7 @@
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
+#include "qemu/osdep.h"
#include "qemu-common.h"
#include "sysemu/block-backend.h"
#include "block/block_int.h"
@@ -27,15 +28,11 @@
#include "qapi/util.h"
#include "qapi/qmp/qstring.h"
-#include <stdarg.h>
-#include <stdio.h>
#include <getopt.h>
-#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <arpa/inet.h>
-#include <signal.h>
#include <libgen.h>
#include <pthread.h>
diff --git a/qemu-seccomp.c b/qemu-seccomp.c
index c831fe83ad..2866e3c2a6 100644
--- a/qemu-seccomp.c
+++ b/qemu-seccomp.c
@@ -12,7 +12,7 @@
* Contributions after 2012-01-13 are licensed under the terms of the
* GNU GPL, version 2 or (at your option) any later version.
*/
-#include <stdio.h>
+#include "qemu/osdep.h"
#include <seccomp.h>
#include "sysemu/seccomp.h"
diff --git a/qemu-timer.c b/qemu-timer.c
index f16e422837..e98ecc9733 100644
--- a/qemu-timer.c
+++ b/qemu-timer.c
@@ -22,6 +22,7 @@
* THE SOFTWARE.
*/
+#include "qemu/osdep.h"
#include "qemu/main-loop.h"
#include "qemu/timer.h"
#include "sysemu/replay.h"
diff --git a/qga/channel-posix.c b/qga/channel-posix.c
index 50d9dd3747..7ad3c00765 100644
--- a/qga/channel-posix.c
+++ b/qga/channel-posix.c
@@ -1,11 +1,6 @@
+#include "qemu/osdep.h"
#include <glib.h>
#include <termios.h>
-#include <errno.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <stdlib.h>
-#include <string.h>
-#include "qemu/osdep.h"
#include "qemu/sockets.h"
#include "qga/channel.h"
diff --git a/qga/channel-win32.c b/qga/channel-win32.c
index 0452b9f75e..bb59661240 100644
--- a/qga/channel-win32.c
+++ b/qga/channel-win32.c
@@ -1,9 +1,6 @@
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdbool.h>
+#include "qemu/osdep.h"
#include <glib.h>
#include <windows.h>
-#include <errno.h>
#include <io.h>
#include "qga/guest-agent-core.h"
#include "qga/channel.h"
diff --git a/qga/commands-posix.c b/qga/commands-posix.c
index 5f91275484..9589b2d634 100644
--- a/qga/commands-posix.c
+++ b/qga/commands-posix.c
@@ -11,18 +11,11 @@
* See the COPYING file in the top-level directory.
*/
+#include "qemu/osdep.h"
#include <glib.h>
-#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/wait.h>
-#include <unistd.h>
-#include <errno.h>
-#include <fcntl.h>
#include <dirent.h>
-#include <stdio.h>
-#include <string.h>
-#include <sys/stat.h>
-#include <inttypes.h>
#include "qga/guest-agent-core.h"
#include "qga-qmp-commands.h"
#include "qapi/qmp/qerror.h"
diff --git a/qga/commands-win32.c b/qga/commands-win32.c
index 61ffbdf1ee..cf0757cd0f 100644
--- a/qga/commands-win32.c
+++ b/qga/commands-win32.c
@@ -11,11 +11,10 @@
* See the COPYING file in the top-level directory.
*/
+#include "qemu/osdep.h"
#include <glib.h>
#include <wtypes.h>
#include <powrprof.h>
-#include <stdio.h>
-#include <string.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <iptypes.h>
diff --git a/qga/commands.c b/qga/commands.c
index 58568d8452..5b56786ef6 100644
--- a/qga/commands.c
+++ b/qga/commands.c
@@ -10,6 +10,7 @@
* See the COPYING file in the top-level directory.
*/
+#include "qemu/osdep.h"
#include <glib.h>
#include "qga/guest-agent-core.h"
#include "qga-qmp-commands.h"
diff --git a/qga/guest-agent-command-state.c b/qga/guest-agent-command-state.c
index 128c549edb..20b9b22224 100644
--- a/qga/guest-agent-command-state.c
+++ b/qga/guest-agent-command-state.c
@@ -9,6 +9,7 @@
* This work is licensed under the terms of the GNU GPL, version 2 or later.
* See the COPYING file in the top-level directory.
*/
+#include "qemu/osdep.h"
#include <glib.h>
#include "qga/guest-agent-core.h"
diff --git a/qga/main.c b/qga/main.c
index f83a97d245..0a168e2da8 100644
--- a/qga/main.c
+++ b/qga/main.c
@@ -10,16 +10,13 @@
* This work is licensed under the terms of the GNU GPL, version 2 or later.
* See the COPYING file in the top-level directory.
*/
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdbool.h>
+#include "qemu/osdep.h"
#include <glib.h>
#include <getopt.h>
#include <glib/gstdio.h>
#ifndef _WIN32
#include <syslog.h>
#include <sys/wait.h>
-#include <sys/stat.h>
#endif
#include "qapi/qmp/json-streamer.h"
#include "qapi/qmp/json-parser.h"
diff --git a/qga/service-win32.c b/qga/service-win32.c
index aef41f04f1..72437587b0 100644
--- a/qga/service-win32.c
+++ b/qga/service-win32.c
@@ -10,8 +10,7 @@
* This work is licensed under the terms of the GNU GPL, version 2 or later.
* See the COPYING file in the top-level directory.
*/
-#include <stdlib.h>
-#include <stdio.h>
+#include "qemu/osdep.h"
#include <glib.h>
#include <windows.h>
#include "qga/service-win32.h"
diff --git a/qga/vss-win32.c b/qga/vss-win32.c
index 2142b4964d..5182e3be91 100644
--- a/qga/vss-win32.c
+++ b/qga/vss-win32.c
@@ -10,7 +10,7 @@
* See the COPYING file in the top-level directory.
*/
-#include <stdio.h>
+#include "qemu/osdep.h"
#include <windows.h>
#include "qga/guest-agent-core.h"
#include "qga/vss-win32.h"
diff --git a/qjson.c b/qjson.c
index e478802a46..b65ca6ee5e 100644
--- a/qjson.c
+++ b/qjson.c
@@ -11,8 +11,8 @@
*
*/
+#include "qemu/osdep.h"
#include <qapi/qmp/qstring.h>
-#include <stdbool.h>
#include <glib.h>
#include <qjson.h>
#include <qemu/module.h>
diff --git a/qmp-commands.hx b/qmp-commands.hx
index db072a6e4c..020e5ee96c 100644
--- a/qmp-commands.hx
+++ b/qmp-commands.hx
@@ -3647,7 +3647,9 @@ Enable/Disable migration capabilities
- "rdma-pin-all": pin all pages when using RDMA during migration
- "auto-converge": throttle down guest to help convergence of migration
- "zero-blocks": compress zero blocks during block migration
+- "compress": use multiple compression threads to accelerate live migration
- "events": generate events for each migration state change
+- "x-postcopy-ram": postcopy mode for live migration
Arguments:
@@ -3675,13 +3677,24 @@ Query current migration capabilities
- "rdma-pin-all" : RDMA Pin Page state (json-bool)
- "auto-converge" : Auto Converge state (json-bool)
- "zero-blocks" : Zero Blocks state (json-bool)
+ - "compress": Multiple compression threads state (json-bool)
+ - "events": Migration state change event state (json-bool)
+ - "x-postcopy-ram": postcopy ram state (json-bool)
Arguments:
Example:
-> { "execute": "query-migrate-capabilities" }
-<- { "return": [ { "state": false, "capability": "xbzrle" } ] }
+<- {"return": [
+ {"state": false, "capability": "xbzrle"},
+ {"state": false, "capability": "rdma-pin-all"},
+ {"state": false, "capability": "auto-converge"},
+ {"state": false, "capability": "zero-blocks"},
+ {"state": false, "capability": "compress"},
+ {"state": true, "capability": "events"},
+ {"state": false, "capability": "x-postcopy-ram"}
+ ]}
EQMP
@@ -3700,6 +3713,10 @@ Set migration parameters
- "compress-level": set compression level during migration (json-int)
- "compress-threads": set compression thread count for migration (json-int)
- "decompress-threads": set decompression thread count for migration (json-int)
+- "x-cpu-throttle-initial": set initial percentage of time guest cpus are
+ throttled for auto-converge (json-int)
+- "x-cpu-throttle-increment": set throttle increasing percentage for
+ auto-converge (json-int)
Arguments:
@@ -3713,7 +3730,7 @@ EQMP
{
.name = "migrate-set-parameters",
.args_type =
- "compress-level:i?,compress-threads:i?,decompress-threads:i?",
+ "compress-level:i?,compress-threads:i?,decompress-threads:i?,x-cpu-throttle-initial:i?,x-cpu-throttle-increment:i?",
.mhandler.cmd_new = qmp_marshal_migrate_set_parameters,
},
SQMP
@@ -3726,6 +3743,10 @@ Query current migration parameters
- "compress-level" : compression level value (json-int)
- "compress-threads" : compression thread count value (json-int)
- "decompress-threads" : decompression thread count value (json-int)
+ - "x-cpu-throttle-initial" : initial percentage of time guest cpus are
+ throttled (json-int)
+ - "x-cpu-throttle-increment" : throttle increasing percentage for
+ auto-converge (json-int)
Arguments:
@@ -3734,9 +3755,11 @@ Example:
-> { "execute": "query-migrate-parameters" }
<- {
"return": {
- "decompress-threads", 2,
- "compress-threads", 8,
- "compress-level", 1
+ "decompress-threads": 2,
+ "x-cpu-throttle-increment": 10,
+ "compress-threads": 8,
+ "compress-level": 1,
+ "x-cpu-throttle-initial": 20
}
}
diff --git a/qmp.c b/qmp.c
index 53affe2cfd..6ae723022e 100644
--- a/qmp.c
+++ b/qmp.c
@@ -13,6 +13,7 @@
* GNU GPL, version 2 or (at your option) any later version.
*/
+#include "qemu/osdep.h"
#include "qemu-common.h"
#include "monitor/monitor.h"
#include "sysemu/sysemu.h"
diff --git a/qobject/json-lexer.c b/qobject/json-lexer.c
index 92798ae3a4..496374d9ab 100644
--- a/qobject/json-lexer.c
+++ b/qobject/json-lexer.c
@@ -11,9 +11,9 @@
*
*/
+#include "qemu/osdep.h"
#include "qemu-common.h"
#include "qapi/qmp/json-lexer.h"
-#include <stdint.h>
#define MAX_TOKEN_SIZE (64ULL << 20)
diff --git a/qobject/json-parser.c b/qobject/json-parser.c
index 3c5d35d7b0..77c9382c5e 100644
--- a/qobject/json-parser.c
+++ b/qobject/json-parser.c
@@ -11,7 +11,7 @@
*
*/
-#include <stdarg.h>
+#include "qemu/osdep.h"
#include "qemu-common.h"
#include "qapi/qmp/qstring.h"
diff --git a/qobject/json-streamer.c b/qobject/json-streamer.c
index a4db4b832e..02516853a1 100644
--- a/qobject/json-streamer.c
+++ b/qobject/json-streamer.c
@@ -11,6 +11,7 @@
*
*/
+#include "qemu/osdep.h"
#include "qemu-common.h"
#include "qapi/qmp/json-lexer.h"
#include "qapi/qmp/json-streamer.h"
diff --git a/qobject/qbool.c b/qobject/qbool.c
index 856c743357..0606bbd2a3 100644
--- a/qobject/qbool.c
+++ b/qobject/qbool.c
@@ -11,6 +11,7 @@
*
*/
+#include "qemu/osdep.h"
#include "qapi/qmp/qbool.h"
#include "qapi/qmp/qobject.h"
#include "qemu-common.h"
diff --git a/qobject/qdict.c b/qobject/qdict.c
index 19df837c55..9833bd0730 100644
--- a/qobject/qdict.c
+++ b/qobject/qdict.c
@@ -10,6 +10,7 @@
* See the COPYING.LIB file in the top-level directory.
*/
+#include "qemu/osdep.h"
#include "qapi/qmp/qint.h"
#include "qapi/qmp/qfloat.h"
#include "qapi/qmp/qdict.h"
diff --git a/qobject/qfloat.c b/qobject/qfloat.c
index 87d89a7721..d5da847701 100644
--- a/qobject/qfloat.c
+++ b/qobject/qfloat.c
@@ -11,6 +11,7 @@
*
*/
+#include "qemu/osdep.h"
#include "qapi/qmp/qfloat.h"
#include "qapi/qmp/qobject.h"
#include "qemu-common.h"
diff --git a/qobject/qint.c b/qobject/qint.c
index 7cba9adf40..d7d1b3021f 100644
--- a/qobject/qint.c
+++ b/qobject/qint.c
@@ -10,6 +10,7 @@
* See the COPYING.LIB file in the top-level directory.
*/
+#include "qemu/osdep.h"
#include "qapi/qmp/qint.h"
#include "qapi/qmp/qobject.h"
#include "qemu-common.h"
diff --git a/qobject/qjson.c b/qobject/qjson.c
index a3e6a7ca42..b8cc4ca964 100644
--- a/qobject/qjson.c
+++ b/qobject/qjson.c
@@ -11,6 +11,7 @@
*
*/
+#include "qemu/osdep.h"
#include "qapi/qmp/json-lexer.h"
#include "qapi/qmp/json-parser.h"
#include "qapi/qmp/json-streamer.h"
diff --git a/qobject/qlist.c b/qobject/qlist.c
index 3c045aed11..1ec74de2b3 100644
--- a/qobject/qlist.c
+++ b/qobject/qlist.c
@@ -10,6 +10,7 @@
* See the COPYING.LIB file in the top-level directory.
*/
+#include "qemu/osdep.h"
#include "qapi/qmp/qlist.h"
#include "qapi/qmp/qobject.h"
#include "qemu/queue.h"
diff --git a/qobject/qnull.c b/qobject/qnull.c
index 5f7ba4d01a..c124d0585e 100644
--- a/qobject/qnull.c
+++ b/qobject/qnull.c
@@ -10,6 +10,7 @@
* or later. See the COPYING.LIB file in the top-level directory.
*/
+#include "qemu/osdep.h"
#include "qemu-common.h"
#include "qapi/qmp/qobject.h"
diff --git a/qobject/qobject.c b/qobject/qobject.c
index a3ef14eb55..cd41fb940b 100644
--- a/qobject/qobject.c
+++ b/qobject/qobject.c
@@ -7,6 +7,7 @@
* or later. See the COPYING.LIB file in the top-level directory.
*/
+#include "qemu/osdep.h"
#include "qemu-common.h"
#include "qapi/qmp/qbool.h"
#include "qapi/qmp/qdict.h"
diff --git a/qobject/qstring.c b/qobject/qstring.c
index f44c5c424d..5da7b5f37c 100644
--- a/qobject/qstring.c
+++ b/qobject/qstring.c
@@ -10,6 +10,7 @@
* See the COPYING.LIB file in the top-level directory.
*/
+#include "qemu/osdep.h"
#include "qapi/qmp/qobject.h"
#include "qapi/qmp/qstring.h"
#include "qemu-common.h"
diff --git a/qom/container.c b/qom/container.c
index 62b1648add..c9eb49b01e 100644
--- a/qom/container.c
+++ b/qom/container.c
@@ -10,9 +10,9 @@
* See the COPYING file in the top-level directory.
*/
+#include "qemu/osdep.h"
#include "qom/object.h"
#include "qemu/module.h"
-#include <assert.h>
static const TypeInfo container_info = {
.name = "container",
diff --git a/qom/object.c b/qom/object.c
index 5ff97ab91e..5904081ba9 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -10,6 +10,7 @@
* See the COPYING file in the top-level directory.
*/
+#include "qemu/osdep.h"
#include "qom/object.h"
#include "qom/object_interfaces.h"
#include "qemu-common.h"
diff --git a/qom/object_interfaces.c b/qom/object_interfaces.c
index a66cd6026c..f1218f0cc1 100644
--- a/qom/object_interfaces.c
+++ b/qom/object_interfaces.c
@@ -1,3 +1,4 @@
+#include "qemu/osdep.h"
#include "qom/object_interfaces.h"
#include "qemu/module.h"
diff --git a/qom/qom-qobject.c b/qom/qom-qobject.c
index 964989065b..9cbc4c69a6 100644
--- a/qom/qom-qobject.c
+++ b/qom/qom-qobject.c
@@ -9,6 +9,7 @@
* See the COPYING file in the top-level directory.
*/
+#include "qemu/osdep.h"
#include "qemu-common.h"
#include "qom/object.h"
#include "qom/qom-qobject.h"
diff --git a/qtest.c b/qtest.c
index 05cefd2800..58a7732ef3 100644
--- a/qtest.c
+++ b/qtest.c
@@ -11,6 +11,7 @@
*
*/
+#include "qemu/osdep.h"
#include "sysemu/qtest.h"
#include "hw/qdev.h"
#include "sysemu/char.h"
diff --git a/replay/replay-events.c b/replay/replay-events.c
index 402f644067..2628109ed8 100644
--- a/replay/replay-events.c
+++ b/replay/replay-events.c
@@ -9,6 +9,7 @@
*
*/
+#include "qemu/osdep.h"
#include "qemu-common.h"
#include "qemu/error-report.h"
#include "sysemu/replay.h"
diff --git a/replay/replay-input.c b/replay/replay-input.c
index bc15f592dc..4270ca1837 100644
--- a/replay/replay-input.c
+++ b/replay/replay-input.c
@@ -9,6 +9,7 @@
*
*/
+#include "qemu/osdep.h"
#include "qemu-common.h"
#include "sysemu/replay.h"
#include "replay-internal.h"
diff --git a/replay/replay-internal.c b/replay/replay-internal.c
index 35cff44a36..5835e8def3 100644
--- a/replay/replay-internal.c
+++ b/replay/replay-internal.c
@@ -9,6 +9,7 @@
*
*/
+#include "qemu/osdep.h"
#include "qemu-common.h"
#include "sysemu/replay.h"
#include "replay-internal.h"
diff --git a/replay/replay-time.c b/replay/replay-time.c
index 6d06951f5e..fffe072c55 100644
--- a/replay/replay-time.c
+++ b/replay/replay-time.c
@@ -9,6 +9,7 @@
*
*/
+#include "qemu/osdep.h"
#include "qemu-common.h"
#include "sysemu/replay.h"
#include "replay-internal.h"
diff --git a/replay/replay.c b/replay/replay.c
index e4673b3d92..9cac178697 100644
--- a/replay/replay.c
+++ b/replay/replay.c
@@ -9,6 +9,7 @@
*
*/
+#include "qemu/osdep.h"
#include "qemu-common.h"
#include "sysemu/replay.h"
#include "replay-internal.h"
diff --git a/roms/openbios b/roms/openbios
-Subproject 3caee1794ac3f742315823d8447d21f33ce019e
+Subproject bd95e4c193905d5ed867e96f1a720ce4cb53b59
diff --git a/scripts/vmstate-static-checker.py b/scripts/vmstate-static-checker.py
index b6c0bbead9..b5ecaf644d 100755
--- a/scripts/vmstate-static-checker.py
+++ b/scripts/vmstate-static-checker.py
@@ -99,6 +99,7 @@ def get_changed_sec_name(sec):
# Section names can change -- see commit 292b1634 for an example.
changes = {
"ICH9 LPC": "ICH9-LPC",
+ "e1000-82540em": "e1000",
}
for item in changes:
diff --git a/slirp/arp_table.c b/slirp/arp_table.c
index bcaeb44860..3547043555 100644
--- a/slirp/arp_table.c
+++ b/slirp/arp_table.c
@@ -22,6 +22,7 @@
* THE SOFTWARE.
*/
+#include "qemu/osdep.h"
#include "slirp.h"
void arp_table_add(Slirp *slirp, uint32_t ip_addr, uint8_t ethaddr[ETH_ALEN])
diff --git a/slirp/bootp.c b/slirp/bootp.c
index 1baaab1ab1..7b3232bdc4 100644
--- a/slirp/bootp.c
+++ b/slirp/bootp.c
@@ -21,6 +21,7 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
+#include "qemu/osdep.h"
#include <slirp.h>
#if defined(_WIN32)
@@ -325,7 +326,7 @@ static void bootp_reply(Slirp *slirp, const struct bootp_t *bp)
m->m_len = sizeof(struct bootp_t) -
sizeof(struct ip) - sizeof(struct udphdr);
- udp_output2(NULL, m, &saddr, &daddr, IPTOS_LOWDELAY);
+ udp_output(NULL, m, &saddr, &daddr, IPTOS_LOWDELAY);
}
void bootp_input(struct mbuf *m)
diff --git a/slirp/cksum.c b/slirp/cksum.c
index 63286600e7..bc0d017d24 100644
--- a/slirp/cksum.c
+++ b/slirp/cksum.c
@@ -30,6 +30,7 @@
* in_cksum.c,v 1.2 1994/08/02 07:48:16 davidg Exp
*/
+#include "qemu/osdep.h"
#include <slirp.h>
/*
diff --git a/slirp/dnssearch.c b/slirp/dnssearch.c
index 4c9064ecb6..aed2f13af5 100644
--- a/slirp/dnssearch.c
+++ b/slirp/dnssearch.c
@@ -22,9 +22,7 @@
* THE SOFTWARE.
*/
-#include <stdlib.h>
-#include <string.h>
-#include <stdio.h>
+#include "qemu/osdep.h"
#include <glib.h>
#include "slirp.h"
diff --git a/slirp/if.c b/slirp/if.c
index 8325a2afb5..93d7cc0b43 100644
--- a/slirp/if.c
+++ b/slirp/if.c
@@ -5,6 +5,7 @@
* terms and conditions of the copyright.
*/
+#include "qemu/osdep.h"
#include <slirp.h>
#include "qemu/timer.h"
diff --git a/slirp/ip_icmp.c b/slirp/ip_icmp.c
index 23b9f0fa45..ace39821d9 100644
--- a/slirp/ip_icmp.c
+++ b/slirp/ip_icmp.c
@@ -30,6 +30,7 @@
* ip_icmp.c,v 1.7 1995/05/30 08:09:42 rgrimes Exp
*/
+#include "qemu/osdep.h"
#include "slirp.h"
#include "ip_icmp.h"
@@ -157,12 +158,12 @@ icmp_input(struct mbuf *m, int hlen)
goto freeit;
} else {
struct socket *so;
- struct sockaddr_in addr;
+ struct sockaddr_storage addr;
if ((so = socreate(slirp)) == NULL) goto freeit;
if (icmp_send(so, m, hlen) == 0) {
return;
}
- if(udp_attach(so) == -1) {
+ if (udp_attach(so, AF_INET) == -1) {
DEBUG_MISC((dfd,"icmp_input udp_attach errno = %d-%s\n",
errno,strerror(errno)));
sofree(so);
@@ -170,8 +171,10 @@ icmp_input(struct mbuf *m, int hlen)
goto end_error;
}
so->so_m = m;
+ so->so_ffamily = AF_INET;
so->so_faddr = ip->ip_dst;
so->so_fport = htons(7);
+ so->so_lfamily = AF_INET;
so->so_laddr = ip->ip_src;
so->so_lport = htons(9);
so->so_iptos = ip->ip_tos;
@@ -179,20 +182,9 @@ icmp_input(struct mbuf *m, int hlen)
so->so_state = SS_ISFCONNECTED;
/* Send the packet */
- addr.sin_family = AF_INET;
- if ((so->so_faddr.s_addr & slirp->vnetwork_mask.s_addr) ==
- slirp->vnetwork_addr.s_addr) {
- /* It's an alias */
- if (so->so_faddr.s_addr == slirp->vnameserver_addr.s_addr) {
- if (get_dns_addr(&addr.sin_addr) < 0)
- addr.sin_addr = loopback_addr;
- } else {
- addr.sin_addr = loopback_addr;
- }
- } else {
- addr.sin_addr = so->so_faddr;
- }
- addr.sin_port = so->so_fport;
+ addr = so->fhost.ss;
+ sotranslate_out(so, &addr);
+
if(sendto(so->s, icmp_ping_msg, strlen(icmp_ping_msg), 0,
(struct sockaddr *)&addr, sizeof(addr)) == -1) {
DEBUG_MISC((dfd,"icmp_input udp sendto tx errno = %d-%s\n",
diff --git a/slirp/ip_input.c b/slirp/ip_input.c
index 7d436e6ecc..e4855ae0f0 100644
--- a/slirp/ip_input.c
+++ b/slirp/ip_input.c
@@ -38,6 +38,7 @@
* terms and conditions of the copyright.
*/
+#include "qemu/osdep.h"
#include <slirp.h>
#include <qemu/osdep.h>
#include "ip_icmp.h"
diff --git a/slirp/ip_output.c b/slirp/ip_output.c
index 1254d0d585..0d6b3b8312 100644
--- a/slirp/ip_output.c
+++ b/slirp/ip_output.c
@@ -38,6 +38,7 @@
* terms and conditions of the copyright.
*/
+#include "qemu/osdep.h"
#include <slirp.h>
/* Number of packets queued before we start sending
diff --git a/slirp/mbuf.c b/slirp/mbuf.c
index 795fc29f98..c959758465 100644
--- a/slirp/mbuf.c
+++ b/slirp/mbuf.c
@@ -15,6 +15,7 @@
* the flags
*/
+#include "qemu/osdep.h"
#include <slirp.h>
#define MBUF_THRESH 30
@@ -91,7 +92,7 @@ m_get(Slirp *slirp)
m->m_len = 0;
m->m_nextpkt = NULL;
m->m_prevpkt = NULL;
- m->arp_requested = false;
+ m->resolution_requested = false;
m->expiration_date = (uint64_t)-1;
end_error:
DEBUG_ARG("m = %p", m);
diff --git a/slirp/mbuf.h b/slirp/mbuf.h
index b144f1ce3a..38fedf46de 100644
--- a/slirp/mbuf.h
+++ b/slirp/mbuf.h
@@ -79,7 +79,7 @@ struct mbuf {
int m_len; /* Amount of data in this mbuf */
Slirp *slirp;
- bool arp_requested;
+ bool resolution_requested;
uint64_t expiration_date;
/* start of dynamic buffer area, must be last element */
union {
diff --git a/slirp/misc.c b/slirp/misc.c
index 5497161f13..e2eea2e4b3 100644
--- a/slirp/misc.c
+++ b/slirp/misc.c
@@ -5,6 +5,7 @@
* terms and conditions of the copyright.
*/
+#include "qemu/osdep.h"
#include <slirp.h>
#include <libslirp.h>
diff --git a/slirp/sbuf.c b/slirp/sbuf.c
index b8c3db744f..dd4cb8c139 100644
--- a/slirp/sbuf.c
+++ b/slirp/sbuf.c
@@ -5,6 +5,7 @@
* terms and conditions of the copyright.
*/
+#include "qemu/osdep.h"
#include <slirp.h>
#include <qemu/main-loop.h>
diff --git a/slirp/slirp.c b/slirp/slirp.c
index 35f819afb7..0466d330da 100644
--- a/slirp/slirp.c
+++ b/slirp/slirp.c
@@ -21,8 +21,10 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
+#include "qemu/osdep.h"
#include "qemu-common.h"
#include "qemu/timer.h"
+#include "qemu/error-report.h"
#include "sysemu/char.h"
#include "slirp.h"
#include "hw/hw.h"
@@ -234,7 +236,7 @@ Slirp *slirp_init(int restricted, struct in_addr vnetwork,
slirp->opaque = opaque;
- register_savevm(NULL, "slirp", 0, 3,
+ register_savevm(NULL, "slirp", 0, 4,
slirp_state_save, slirp_state_load, slirp);
QTAILQ_INSERT_TAIL(&slirp_instances, slirp, entry);
@@ -762,20 +764,15 @@ void slirp_input(Slirp *slirp, const uint8_t *pkt, int pkt_len)
}
}
-/* Output the IP packet to the ethernet device. Returns 0 if the packet must be
- * re-queued.
+/* Prepare the IPv4 packet to be sent to the ethernet device. Returns 1 if no
+ * packet should be sent, 0 if the packet must be re-queued, 2 if the packet
+ * is ready to go.
*/
-int if_encap(Slirp *slirp, struct mbuf *ifm)
+static int if_encap4(Slirp *slirp, struct mbuf *ifm, struct ethhdr *eh,
+ uint8_t ethaddr[ETH_ALEN])
{
- uint8_t buf[1600];
- struct ethhdr *eh = (struct ethhdr *)buf;
- uint8_t ethaddr[ETH_ALEN];
const struct ip *iph = (const struct ip *)ifm->m_data;
- if (ifm->m_len + ETH_HLEN > sizeof(buf)) {
- return 1;
- }
-
if (iph->ip_dst.s_addr == 0) {
/* 0.0.0.0 can not be a destination address, something went wrong,
* avoid making it worse */
@@ -786,7 +783,7 @@ int if_encap(Slirp *slirp, struct mbuf *ifm)
struct ethhdr *reh = (struct ethhdr *)arp_req;
struct arphdr *rah = (struct arphdr *)(arp_req + ETH_HLEN);
- if (!ifm->arp_requested) {
+ if (!ifm->resolution_requested) {
/* If the client addr is not known, send an ARP request */
memset(reh->h_dest, 0xff, ETH_ALEN);
memcpy(reh->h_source, special_ethaddr, ETH_ALEN - 4);
@@ -812,22 +809,62 @@ int if_encap(Slirp *slirp, struct mbuf *ifm)
rah->ar_tip = iph->ip_dst.s_addr;
slirp->client_ipaddr = iph->ip_dst;
slirp_output(slirp->opaque, arp_req, sizeof(arp_req));
- ifm->arp_requested = true;
+ ifm->resolution_requested = true;
/* Expire request and drop outgoing packet after 1 second */
ifm->expiration_date = qemu_clock_get_ns(QEMU_CLOCK_REALTIME) + 1000000000ULL;
}
return 0;
} else {
- memcpy(eh->h_dest, ethaddr, ETH_ALEN);
memcpy(eh->h_source, special_ethaddr, ETH_ALEN - 4);
/* XXX: not correct */
memcpy(&eh->h_source[2], &slirp->vhost_addr, 4);
eh->h_proto = htons(ETH_P_IP);
- memcpy(buf + sizeof(struct ethhdr), ifm->m_data, ifm->m_len);
- slirp_output(slirp->opaque, buf, ifm->m_len + ETH_HLEN);
+
+ /* Send this */
+ return 2;
+ }
+}
+
+/* Output the IP packet to the ethernet device. Returns 0 if the packet must be
+ * re-queued.
+ */
+int if_encap(Slirp *slirp, struct mbuf *ifm)
+{
+ uint8_t buf[1600];
+ struct ethhdr *eh = (struct ethhdr *)buf;
+ uint8_t ethaddr[ETH_ALEN];
+ const struct ip *iph = (const struct ip *)ifm->m_data;
+ int ret;
+
+ if (ifm->m_len + ETH_HLEN > sizeof(buf)) {
return 1;
}
+
+ switch (iph->ip_v) {
+ case IPVERSION:
+ ret = if_encap4(slirp, ifm, eh, ethaddr);
+ if (ret < 2) {
+ return ret;
+ }
+ break;
+
+ default:
+ /* Do not assert while we don't manage IP6VERSION */
+ /* assert(0); */
+ break;
+ }
+
+ memcpy(eh->h_dest, ethaddr, ETH_ALEN);
+ DEBUG_ARGS((dfd, " src = %02x:%02x:%02x:%02x:%02x:%02x\n",
+ eh->h_source[0], eh->h_source[1], eh->h_source[2],
+ eh->h_source[3], eh->h_source[4], eh->h_source[5]));
+ DEBUG_ARGS((dfd, " dst = %02x:%02x:%02x:%02x:%02x:%02x\n",
+ eh->h_dest[0], eh->h_dest[1], eh->h_dest[2],
+ eh->h_dest[3], eh->h_dest[4], eh->h_dest[5]));
+ memcpy(buf + sizeof(struct ethhdr), ifm->m_data, ifm->m_len);
+ slirp_output(slirp->opaque, buf, ifm->m_len + ETH_HLEN);
+ return 1;
}
/* Drop host forwarding rule, return 0 if found. */
@@ -1011,10 +1048,26 @@ static void slirp_sbuf_save(QEMUFile *f, struct sbuf *sbuf)
static void slirp_socket_save(QEMUFile *f, struct socket *so)
{
qemu_put_be32(f, so->so_urgc);
- qemu_put_be32(f, so->so_faddr.s_addr);
- qemu_put_be32(f, so->so_laddr.s_addr);
- qemu_put_be16(f, so->so_fport);
- qemu_put_be16(f, so->so_lport);
+ qemu_put_be16(f, so->so_ffamily);
+ switch (so->so_ffamily) {
+ case AF_INET:
+ qemu_put_be32(f, so->so_faddr.s_addr);
+ qemu_put_be16(f, so->so_fport);
+ break;
+ default:
+ error_report(
+ "so_ffamily unknown, unable to save so_faddr and so_fport\n");
+ }
+ qemu_put_be16(f, so->so_lfamily);
+ switch (so->so_lfamily) {
+ case AF_INET:
+ qemu_put_be32(f, so->so_laddr.s_addr);
+ qemu_put_be16(f, so->so_lport);
+ break;
+ default:
+ error_report(
+ "so_ffamily unknown, unable to save so_laddr and so_lport\n");
+ }
qemu_put_byte(f, so->so_iptos);
qemu_put_byte(f, so->so_emu);
qemu_put_byte(f, so->so_type);
@@ -1134,10 +1187,26 @@ static int slirp_socket_load(QEMUFile *f, struct socket *so)
return -ENOMEM;
so->so_urgc = qemu_get_be32(f);
- so->so_faddr.s_addr = qemu_get_be32(f);
- so->so_laddr.s_addr = qemu_get_be32(f);
- so->so_fport = qemu_get_be16(f);
- so->so_lport = qemu_get_be16(f);
+ so->so_ffamily = qemu_get_be16(f);
+ switch (so->so_ffamily) {
+ case AF_INET:
+ so->so_faddr.s_addr = qemu_get_be32(f);
+ so->so_fport = qemu_get_be16(f);
+ break;
+ default:
+ error_report(
+ "so_ffamily unknown, unable to restore so_faddr and so_lport\n");
+ }
+ so->so_lfamily = qemu_get_be16(f);
+ switch (so->so_lfamily) {
+ case AF_INET:
+ so->so_laddr.s_addr = qemu_get_be32(f);
+ so->so_lport = qemu_get_be16(f);
+ break;
+ default:
+ error_report(
+ "so_ffamily unknown, unable to restore so_laddr and so_lport\n");
+ }
so->so_iptos = qemu_get_byte(f);
so->so_emu = qemu_get_byte(f);
so->so_type = qemu_get_byte(f);
diff --git a/slirp/slirp.h b/slirp/slirp.h
index ec0a4c2415..239fe2917a 100644
--- a/slirp/slirp.h
+++ b/slirp/slirp.h
@@ -327,7 +327,7 @@ void tcp_respond(struct tcpcb *, register struct tcpiphdr *, register struct mbu
struct tcpcb * tcp_newtcpcb(struct socket *);
struct tcpcb * tcp_close(register struct tcpcb *);
void tcp_sockclosed(struct tcpcb *);
-int tcp_fconnect(struct socket *);
+int tcp_fconnect(struct socket *, unsigned short af);
void tcp_connect(struct socket *);
int tcp_attach(struct socket *);
uint8_t tcp_tos(struct socket *);
diff --git a/slirp/socket.c b/slirp/socket.c
index 1673e3afce..2b5453e020 100644
--- a/slirp/socket.c
+++ b/slirp/socket.c
@@ -5,6 +5,7 @@
* terms and conditions of the copyright.
*/
+#include "qemu/osdep.h"
#include "qemu-common.h"
#include <slirp.h>
#include "ip_icmp.h"
@@ -15,24 +16,26 @@
static void sofcantrcvmore(struct socket *so);
static void sofcantsendmore(struct socket *so);
-struct socket *
-solookup(struct socket *head, struct in_addr laddr, u_int lport,
- struct in_addr faddr, u_int fport)
+struct socket *solookup(struct socket **last, struct socket *head,
+ struct sockaddr_storage *lhost, struct sockaddr_storage *fhost)
{
- struct socket *so;
-
- for (so = head->so_next; so != head; so = so->so_next) {
- if (so->so_lport == lport &&
- so->so_laddr.s_addr == laddr.s_addr &&
- so->so_faddr.s_addr == faddr.s_addr &&
- so->so_fport == fport)
- break;
- }
-
- if (so == head)
- return (struct socket *)NULL;
- return so;
+ struct socket *so = *last;
+
+ /* Optimisation */
+ if (so != head && sockaddr_equal(&(so->lhost.ss), lhost)
+ && (!fhost || sockaddr_equal(&so->fhost.ss, fhost))) {
+ return so;
+ }
+
+ for (so = head->so_next; so != head; so = so->so_next) {
+ if (sockaddr_equal(&(so->lhost.ss), lhost)
+ && (!fhost || sockaddr_equal(&so->fhost.ss, fhost))) {
+ *last = so;
+ return so;
+ }
+ }
+ return (struct socket *)NULL;
}
/*
@@ -437,8 +440,9 @@ sowrite(struct socket *so)
void
sorecvfrom(struct socket *so)
{
- struct sockaddr_in addr;
- socklen_t addrlen = sizeof(struct sockaddr_in);
+ struct sockaddr_storage addr;
+ struct sockaddr_storage saddr, daddr;
+ socklen_t addrlen = sizeof(struct sockaddr_storage);
DEBUG_CALL("sorecvfrom");
DEBUG_ARG("so = %p", so);
@@ -525,9 +529,21 @@ sorecvfrom(struct socket *so)
/*
* If this packet was destined for CTL_ADDR,
- * make it look like that's where it came from, done by udp_output
+ * make it look like that's where it came from
*/
- udp_output(so, m, &addr);
+ saddr = addr;
+ sotranslate_in(so, &saddr);
+ daddr = so->lhost.ss;
+
+ switch (so->so_ffamily) {
+ case AF_INET:
+ udp_output(so, m, (struct sockaddr_in *) &saddr,
+ (struct sockaddr_in *) &daddr,
+ so->so_iptos);
+ break;
+ default:
+ break;
+ }
} /* rx error */
} /* if ping packet */
}
@@ -538,33 +554,20 @@ sorecvfrom(struct socket *so)
int
sosendto(struct socket *so, struct mbuf *m)
{
- Slirp *slirp = so->slirp;
int ret;
- struct sockaddr_in addr;
+ struct sockaddr_storage addr;
DEBUG_CALL("sosendto");
DEBUG_ARG("so = %p", so);
DEBUG_ARG("m = %p", m);
- addr.sin_family = AF_INET;
- if ((so->so_faddr.s_addr & slirp->vnetwork_mask.s_addr) ==
- slirp->vnetwork_addr.s_addr) {
- /* It's an alias */
- if (so->so_faddr.s_addr == slirp->vnameserver_addr.s_addr) {
- if (get_dns_addr(&addr.sin_addr) < 0)
- addr.sin_addr = loopback_addr;
- } else {
- addr.sin_addr = loopback_addr;
- }
- } else
- addr.sin_addr = so->so_faddr;
- addr.sin_port = so->so_fport;
-
- DEBUG_MISC((dfd, " sendto()ing, addr.sin_port=%d, addr.sin_addr.s_addr=%.16s\n", ntohs(addr.sin_port), inet_ntoa(addr.sin_addr)));
+ addr = so->fhost.ss;
+ DEBUG_CALL(" sendto()ing)");
+ sotranslate_out(so, &addr);
/* Don't care what port we get */
ret = sendto(so->s, m->m_data, m->m_len, 0,
- (struct sockaddr *)&addr, sizeof (struct sockaddr));
+ (struct sockaddr *)&addr, sizeof(addr));
if (ret < 0)
return -1;
@@ -619,6 +622,7 @@ tcp_listen(Slirp *slirp, uint32_t haddr, u_int hport, uint32_t laddr,
so->so_state &= SS_PERSISTENT_MASK;
so->so_state |= (SS_FACCEPTCONN | flags);
+ so->so_lfamily = AF_INET;
so->so_lport = lport; /* Kept in network format */
so->so_laddr.s_addr = laddr; /* Ditto */
@@ -645,6 +649,7 @@ tcp_listen(Slirp *slirp, uint32_t haddr, u_int hport, uint32_t laddr,
qemu_setsockopt(s, SOL_SOCKET, SO_OOBINLINE, &opt, sizeof(int));
getsockname(s,(struct sockaddr *)&addr,&addrlen);
+ so->so_ffamily = AF_INET;
so->so_fport = addr.sin_port;
if (addr.sin_addr.s_addr == 0 || addr.sin_addr.s_addr == loopback_addr.s_addr)
so->so_faddr = slirp->vhost_addr;
@@ -718,3 +723,81 @@ sofwdrain(struct socket *so)
else
sofcantsendmore(so);
}
+
+/*
+ * Translate addr in host addr when it is a virtual address
+ */
+void sotranslate_out(struct socket *so, struct sockaddr_storage *addr)
+{
+ Slirp *slirp = so->slirp;
+ struct sockaddr_in *sin = (struct sockaddr_in *)addr;
+
+ switch (addr->ss_family) {
+ case AF_INET:
+ if ((so->so_faddr.s_addr & slirp->vnetwork_mask.s_addr) ==
+ slirp->vnetwork_addr.s_addr) {
+ /* It's an alias */
+ if (so->so_faddr.s_addr == slirp->vnameserver_addr.s_addr) {
+ if (get_dns_addr(&sin->sin_addr) < 0) {
+ sin->sin_addr = loopback_addr;
+ }
+ } else {
+ sin->sin_addr = loopback_addr;
+ }
+ }
+
+ DEBUG_MISC((dfd, " addr.sin_port=%d, "
+ "addr.sin_addr.s_addr=%.16s\n",
+ ntohs(sin->sin_port), inet_ntoa(sin->sin_addr)));
+ break;
+
+ default:
+ break;
+ }
+}
+
+void sotranslate_in(struct socket *so, struct sockaddr_storage *addr)
+{
+ Slirp *slirp = so->slirp;
+ struct sockaddr_in *sin = (struct sockaddr_in *)addr;
+
+ switch (addr->ss_family) {
+ case AF_INET:
+ if ((so->so_faddr.s_addr & slirp->vnetwork_mask.s_addr) ==
+ slirp->vnetwork_addr.s_addr) {
+ uint32_t inv_mask = ~slirp->vnetwork_mask.s_addr;
+
+ if ((so->so_faddr.s_addr & inv_mask) == inv_mask) {
+ sin->sin_addr = slirp->vhost_addr;
+ } else if (sin->sin_addr.s_addr == loopback_addr.s_addr ||
+ so->so_faddr.s_addr != slirp->vhost_addr.s_addr) {
+ sin->sin_addr = so->so_faddr;
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+
+/*
+ * Translate connections from localhost to the real hostname
+ */
+void sotranslate_accept(struct socket *so)
+{
+ Slirp *slirp = so->slirp;
+
+ switch (so->so_ffamily) {
+ case AF_INET:
+ if (so->so_faddr.s_addr == INADDR_ANY ||
+ (so->so_faddr.s_addr & loopback_mask) ==
+ (loopback_addr.s_addr & loopback_mask)) {
+ so->so_faddr = slirp->vhost_addr;
+ }
+ break;
+
+ default:
+ break;
+ }
+}
diff --git a/slirp/socket.h b/slirp/socket.h
index 57e0407ebc..c4afc9494f 100644
--- a/slirp/socket.h
+++ b/slirp/socket.h
@@ -31,10 +31,21 @@ struct socket {
struct tcpiphdr *so_ti; /* Pointer to the original ti within
* so_mconn, for non-blocking connections */
int so_urgc;
- struct in_addr so_faddr; /* foreign host table entry */
- struct in_addr so_laddr; /* local host table entry */
- uint16_t so_fport; /* foreign port */
- uint16_t so_lport; /* local port */
+ union { /* foreign host */
+ struct sockaddr_storage ss;
+ struct sockaddr_in sin;
+ } fhost;
+#define so_faddr fhost.sin.sin_addr
+#define so_fport fhost.sin.sin_port
+#define so_ffamily fhost.ss.ss_family
+
+ union { /* local host */
+ struct sockaddr_storage ss;
+ struct sockaddr_in sin;
+ } lhost;
+#define so_laddr lhost.sin.sin_addr
+#define so_lport lhost.sin.sin_port
+#define so_lfamily lhost.ss.ss_family
uint8_t so_iptos; /* Type of service */
uint8_t so_emu; /* Is the socket emulated? */
@@ -76,8 +87,31 @@ struct socket {
#define SS_HOSTFWD 0x1000 /* Socket describes host->guest forwarding */
#define SS_INCOMING 0x2000 /* Connection was initiated by a host on the internet */
-struct socket * solookup(struct socket *, struct in_addr, u_int, struct in_addr, u_int);
-struct socket * socreate(Slirp *);
+static inline int sockaddr_equal(struct sockaddr_storage *a,
+ struct sockaddr_storage *b)
+{
+ if (a->ss_family != b->ss_family) {
+ return 0;
+ }
+
+ switch (a->ss_family) {
+ case AF_INET:
+ {
+ struct sockaddr_in *a4 = (struct sockaddr_in *) a;
+ struct sockaddr_in *b4 = (struct sockaddr_in *) b;
+ return a4->sin_addr.s_addr == b4->sin_addr.s_addr
+ && a4->sin_port == b4->sin_port;
+ }
+ default:
+ g_assert_not_reached();
+ }
+
+ return 0;
+}
+
+struct socket *solookup(struct socket **, struct socket *,
+ struct sockaddr_storage *, struct sockaddr_storage *);
+struct socket *socreate(Slirp *);
void sofree(struct socket *);
int soread(struct socket *);
void sorecvoob(struct socket *);
@@ -94,4 +128,9 @@ struct iovec; /* For win32 */
size_t sopreprbuf(struct socket *so, struct iovec *iov, int *np);
int soreadbuf(struct socket *so, const char *buf, int size);
+void sotranslate_out(struct socket *, struct sockaddr_storage *);
+void sotranslate_in(struct socket *, struct sockaddr_storage *);
+void sotranslate_accept(struct socket *);
+
+
#endif /* _SOCKET_H_ */
diff --git a/slirp/tcp_input.c b/slirp/tcp_input.c
index 6b096ecb3c..2027a7511d 100644
--- a/slirp/tcp_input.c
+++ b/slirp/tcp_input.c
@@ -38,6 +38,7 @@
* terms and conditions of the copyright.
*/
+#include "qemu/osdep.h"
#include <slirp.h>
#include "ip_icmp.h"
@@ -227,6 +228,8 @@ tcp_input(struct mbuf *m, int iphlen, struct socket *inso)
int iss = 0;
u_long tiwin;
int ret;
+ struct sockaddr_storage lhost, fhost;
+ struct sockaddr_in *lhost4, *fhost4;
struct ex_list *ex_ptr;
Slirp *slirp;
@@ -320,16 +323,16 @@ tcp_input(struct mbuf *m, int iphlen, struct socket *inso)
* Locate pcb for segment.
*/
findso:
- so = slirp->tcp_last_so;
- if (so->so_fport != ti->ti_dport ||
- so->so_lport != ti->ti_sport ||
- so->so_laddr.s_addr != ti->ti_src.s_addr ||
- so->so_faddr.s_addr != ti->ti_dst.s_addr) {
- so = solookup(&slirp->tcb, ti->ti_src, ti->ti_sport,
- ti->ti_dst, ti->ti_dport);
- if (so)
- slirp->tcp_last_so = so;
- }
+ lhost.ss_family = AF_INET;
+ lhost4 = (struct sockaddr_in *) &lhost;
+ lhost4->sin_addr = ti->ti_src;
+ lhost4->sin_port = ti->ti_sport;
+ fhost.ss_family = AF_INET;
+ fhost4 = (struct sockaddr_in *) &fhost;
+ fhost4->sin_addr = ti->ti_dst;
+ fhost4->sin_port = ti->ti_dport;
+
+ so = solookup(&slirp->tcp_last_so, &slirp->tcb, &lhost, &fhost);
/*
* If the state is CLOSED (i.e., TCB does not exist) then
@@ -374,10 +377,8 @@ findso:
sbreserve(&so->so_snd, TCP_SNDSPACE);
sbreserve(&so->so_rcv, TCP_RCVSPACE);
- so->so_laddr = ti->ti_src;
- so->so_lport = ti->ti_sport;
- so->so_faddr = ti->ti_dst;
- so->so_fport = ti->ti_dport;
+ so->lhost.ss = lhost;
+ so->fhost.ss = fhost;
if ((so->so_iptos = tcp_tos(so)) == 0)
so->so_iptos = ((struct ip *)ti)->ip_tos;
@@ -584,7 +585,7 @@ findso:
goto cont_input;
}
- if ((tcp_fconnect(so) == -1) &&
+ if ((tcp_fconnect(so, so->so_ffamily) == -1) &&
#if defined(_WIN32)
socket_error() != WSAEWOULDBLOCK
#else
diff --git a/slirp/tcp_output.c b/slirp/tcp_output.c
index fafca58a0a..34e4d2e5d4 100644
--- a/slirp/tcp_output.c
+++ b/slirp/tcp_output.c
@@ -38,6 +38,7 @@
* terms and conditions of the copyright.
*/
+#include "qemu/osdep.h"
#include <slirp.h>
static const u_char tcp_outflags[TCP_NSTATES] = {
diff --git a/slirp/tcp_subr.c b/slirp/tcp_subr.c
index e161ed2a96..b1aa1f23f4 100644
--- a/slirp/tcp_subr.c
+++ b/slirp/tcp_subr.c
@@ -38,6 +38,7 @@
* terms and conditions of the copyright.
*/
+#include "qemu/osdep.h"
#include <slirp.h>
/* patchable/settable parameters for tcp */
@@ -324,40 +325,27 @@ tcp_sockclosed(struct tcpcb *tp)
* nonblocking. Connect returns after the SYN is sent, and does
* not wait for ACK+SYN.
*/
-int tcp_fconnect(struct socket *so)
+int tcp_fconnect(struct socket *so, unsigned short af)
{
- Slirp *slirp = so->slirp;
int ret=0;
DEBUG_CALL("tcp_fconnect");
DEBUG_ARG("so = %p", so);
- if( (ret = so->s = qemu_socket(AF_INET,SOCK_STREAM,0)) >= 0) {
+ ret = so->s = qemu_socket(af, SOCK_STREAM, 0);
+ if (ret >= 0) {
int opt, s=so->s;
- struct sockaddr_in addr;
+ struct sockaddr_storage addr;
qemu_set_nonblock(s);
socket_set_fast_reuse(s);
opt = 1;
qemu_setsockopt(s, SOL_SOCKET, SO_OOBINLINE, &opt, sizeof(opt));
- addr.sin_family = AF_INET;
- if ((so->so_faddr.s_addr & slirp->vnetwork_mask.s_addr) ==
- slirp->vnetwork_addr.s_addr) {
- /* It's an alias */
- if (so->so_faddr.s_addr == slirp->vnameserver_addr.s_addr) {
- if (get_dns_addr(&addr.sin_addr) < 0)
- addr.sin_addr = loopback_addr;
- } else {
- addr.sin_addr = loopback_addr;
- }
- } else
- addr.sin_addr = so->so_faddr;
- addr.sin_port = so->so_fport;
-
- DEBUG_MISC((dfd, " connect()ing, addr.sin_port=%d, "
- "addr.sin_addr.s_addr=%.16s\n",
- ntohs(addr.sin_port), inet_ntoa(addr.sin_addr)));
+ addr = so->fhost.ss;
+ DEBUG_CALL(" connect()ing")
+ sotranslate_out(so, &addr);
+
/* We don't care what port we get */
ret = connect(s,(struct sockaddr *)&addr,sizeof (addr));
@@ -413,6 +401,7 @@ void tcp_connect(struct socket *inso)
free(so); /* NOT sofree */
return;
}
+ so->so_lfamily = AF_INET;
so->so_laddr = inso->so_laddr;
so->so_lport = inso->so_lport;
}
@@ -430,14 +419,8 @@ void tcp_connect(struct socket *inso)
qemu_setsockopt(s, SOL_SOCKET, SO_OOBINLINE, &opt, sizeof(int));
socket_set_nodelay(s);
- so->so_fport = addr.sin_port;
- so->so_faddr = addr.sin_addr;
- /* Translate connections from localhost to the real hostname */
- if (so->so_faddr.s_addr == 0 ||
- (so->so_faddr.s_addr & loopback_mask) ==
- (loopback_addr.s_addr & loopback_mask)) {
- so->so_faddr = slirp->vhost_addr;
- }
+ so->fhost.sin = addr;
+ sotranslate_accept(so);
/* Close the accept() socket, set right state */
if (inso->so_state & SS_FACCEPTONCE) {
diff --git a/slirp/tcp_timer.c b/slirp/tcp_timer.c
index 6c5bb11cc3..1214c2e6fa 100644
--- a/slirp/tcp_timer.c
+++ b/slirp/tcp_timer.c
@@ -30,6 +30,7 @@
* tcp_timer.c,v 1.2 1994/08/02 07:49:10 davidg Exp
*/
+#include "qemu/osdep.h"
#include <slirp.h>
static struct tcpcb *tcp_timers(register struct tcpcb *tp, int timer);
diff --git a/slirp/tftp.c b/slirp/tftp.c
index a329fb281b..abb010621c 100644
--- a/slirp/tftp.c
+++ b/slirp/tftp.c
@@ -22,6 +22,7 @@
* THE SOFTWARE.
*/
+#include "qemu/osdep.h"
#include <slirp.h>
#include "qemu-common.h"
@@ -155,7 +156,7 @@ static int tftp_send_oack(struct tftp_session *spt,
m->m_len = sizeof(struct tftp_t) - 514 + n -
sizeof(struct ip) - sizeof(struct udphdr);
- udp_output2(NULL, m, &saddr, &daddr, IPTOS_LOWDELAY);
+ udp_output(NULL, m, &saddr, &daddr, IPTOS_LOWDELAY);
return 0;
}
@@ -193,7 +194,7 @@ static void tftp_send_error(struct tftp_session *spt,
m->m_len = sizeof(struct tftp_t) - 514 + 3 + strlen(msg) -
sizeof(struct ip) - sizeof(struct udphdr);
- udp_output2(NULL, m, &saddr, &daddr, IPTOS_LOWDELAY);
+ udp_output(NULL, m, &saddr, &daddr, IPTOS_LOWDELAY);
out:
tftp_session_terminate(spt);
@@ -243,7 +244,7 @@ static void tftp_send_next_block(struct tftp_session *spt,
m->m_len = sizeof(struct tftp_t) - (512 - nobytes) -
sizeof(struct ip) - sizeof(struct udphdr);
- udp_output2(NULL, m, &saddr, &daddr, IPTOS_LOWDELAY);
+ udp_output(NULL, m, &saddr, &daddr, IPTOS_LOWDELAY);
if (nobytes == 512) {
tftp_session_update(spt);
diff --git a/slirp/udp.c b/slirp/udp.c
index fee13b4dbd..6b39cab0c6 100644
--- a/slirp/udp.c
+++ b/slirp/udp.c
@@ -38,6 +38,7 @@
* terms and conditions of the copyright.
*/
+#include "qemu/osdep.h"
#include <slirp.h>
#include "ip_icmp.h"
@@ -70,6 +71,8 @@ udp_input(register struct mbuf *m, int iphlen)
int len;
struct ip save_ip;
struct socket *so;
+ struct sockaddr_storage lhost;
+ struct sockaddr_in *lhost4;
DEBUG_CALL("udp_input");
DEBUG_ARG("m = %p", m);
@@ -151,25 +154,12 @@ udp_input(register struct mbuf *m, int iphlen)
/*
* Locate pcb for datagram.
*/
- so = slirp->udp_last_so;
- if (so == &slirp->udb || so->so_lport != uh->uh_sport ||
- so->so_laddr.s_addr != ip->ip_src.s_addr) {
- struct socket *tmp;
-
- for (tmp = slirp->udb.so_next; tmp != &slirp->udb;
- tmp = tmp->so_next) {
- if (tmp->so_lport == uh->uh_sport &&
- tmp->so_laddr.s_addr == ip->ip_src.s_addr) {
- so = tmp;
- break;
- }
- }
- if (tmp == &slirp->udb) {
- so = NULL;
- } else {
- slirp->udp_last_so = so;
- }
- }
+ lhost.ss_family = AF_INET;
+ lhost4 = (struct sockaddr_in *) &lhost;
+ lhost4->sin_addr = ip->ip_src;
+ lhost4->sin_port = uh->uh_sport;
+
+ so = solookup(&slirp->udp_last_so, &slirp->udb, &lhost, NULL);
if (so == NULL) {
/*
@@ -180,7 +170,7 @@ udp_input(register struct mbuf *m, int iphlen)
if (!so) {
goto bad;
}
- if(udp_attach(so) == -1) {
+ if (udp_attach(so, AF_INET) == -1) {
DEBUG_MISC((dfd," udp_attach errno = %d-%s\n",
errno,strerror(errno)));
sofree(so);
@@ -190,6 +180,7 @@ udp_input(register struct mbuf *m, int iphlen)
/*
* Setup fields
*/
+ so->so_lfamily = AF_INET;
so->so_laddr = ip->ip_src;
so->so_lport = uh->uh_sport;
@@ -202,6 +193,7 @@ udp_input(register struct mbuf *m, int iphlen)
*/
}
+ so->so_ffamily = AF_INET;
so->so_faddr = ip->ip_dst; /* XXX */
so->so_fport = uh->uh_dport; /* XXX */
@@ -218,6 +210,7 @@ udp_input(register struct mbuf *m, int iphlen)
*ip=save_ip;
DEBUG_MISC((dfd,"udp tx errno = %d-%s\n",errno,strerror(errno)));
icmp_error(m, ICMP_UNREACH,ICMP_UNREACH_NET, 0,strerror(errno));
+ goto bad;
}
m_free(so->so_m); /* used for ICMP if error on sorecvfrom */
@@ -233,7 +226,7 @@ bad:
m_free(m);
}
-int udp_output2(struct socket *so, struct mbuf *m,
+int udp_output(struct socket *so, struct mbuf *m,
struct sockaddr_in *saddr, struct sockaddr_in *daddr,
int iptos)
{
@@ -284,35 +277,11 @@ int udp_output2(struct socket *so, struct mbuf *m,
return (error);
}
-int udp_output(struct socket *so, struct mbuf *m,
- struct sockaddr_in *addr)
-
-{
- Slirp *slirp = so->slirp;
- struct sockaddr_in saddr, daddr;
-
- saddr = *addr;
- if ((so->so_faddr.s_addr & slirp->vnetwork_mask.s_addr) ==
- slirp->vnetwork_addr.s_addr) {
- uint32_t inv_mask = ~slirp->vnetwork_mask.s_addr;
-
- if ((so->so_faddr.s_addr & inv_mask) == inv_mask) {
- saddr.sin_addr = slirp->vhost_addr;
- } else if (addr->sin_addr.s_addr == loopback_addr.s_addr ||
- so->so_faddr.s_addr != slirp->vhost_addr.s_addr) {
- saddr.sin_addr = so->so_faddr;
- }
- }
- daddr.sin_addr = so->so_laddr;
- daddr.sin_port = so->so_lport;
-
- return udp_output2(so, m, &saddr, &daddr, so->so_iptos);
-}
-
int
-udp_attach(struct socket *so)
+udp_attach(struct socket *so, unsigned short af)
{
- if((so->s = qemu_socket(AF_INET,SOCK_DGRAM,0)) != -1) {
+ so->s = qemu_socket(af, SOCK_DGRAM, 0);
+ if (so->s != -1) {
so->so_expire = curtime + SO_EXPIRE;
insque(so, &so->slirp->udb);
}
@@ -375,13 +344,9 @@ udp_listen(Slirp *slirp, uint32_t haddr, u_int hport, uint32_t laddr,
socket_set_fast_reuse(so->s);
getsockname(so->s,(struct sockaddr *)&addr,&addrlen);
- so->so_fport = addr.sin_port;
- if (addr.sin_addr.s_addr == 0 ||
- addr.sin_addr.s_addr == loopback_addr.s_addr) {
- so->so_faddr = slirp->vhost_addr;
- } else {
- so->so_faddr = addr.sin_addr;
- }
+ so->fhost.sin = addr;
+ sotranslate_accept(so);
+ so->so_lfamily = AF_INET;
so->so_lport = lport;
so->so_laddr.s_addr = laddr;
if (flags != SS_FACCEPTONCE)
diff --git a/slirp/udp.h b/slirp/udp.h
index 9bf31fe7be..2f9de3886c 100644
--- a/slirp/udp.h
+++ b/slirp/udp.h
@@ -76,12 +76,11 @@ struct mbuf;
void udp_init(Slirp *);
void udp_cleanup(Slirp *);
void udp_input(register struct mbuf *, int);
-int udp_output(struct socket *, struct mbuf *, struct sockaddr_in *);
-int udp_attach(struct socket *);
+int udp_attach(struct socket *, unsigned short af);
void udp_detach(struct socket *);
struct socket * udp_listen(Slirp *, uint32_t, u_int, uint32_t, u_int,
int);
-int udp_output2(struct socket *so, struct mbuf *m,
+int udp_output(struct socket *so, struct mbuf *m,
struct sockaddr_in *saddr, struct sockaddr_in *daddr,
int iptos);
#endif
diff --git a/spice-qemu-char.c b/spice-qemu-char.c
index 8951d7ca37..7c1f4385bf 100644
--- a/spice-qemu-char.c
+++ b/spice-qemu-char.c
@@ -1,11 +1,10 @@
-#include "config-host.h"
+#include "qemu/osdep.h"
#include "trace.h"
#include "ui/qemu-spice.h"
#include "sysemu/char.h"
#include <spice.h>
#include <spice/protocol.h>
-#include "qemu/osdep.h"
typedef struct SpiceCharDriver {
CharDriverState* chr;
diff --git a/stubs/arch-query-cpu-def.c b/stubs/arch-query-cpu-def.c
index a975ab453a..cefe4beb82 100644
--- a/stubs/arch-query-cpu-def.c
+++ b/stubs/arch-query-cpu-def.c
@@ -1,3 +1,4 @@
+#include "qemu/osdep.h"
#include "qemu-common.h"
#include "sysemu/arch_init.h"
#include "qapi/qmp/qerror.h"
diff --git a/stubs/bdrv-commit-all.c b/stubs/bdrv-commit-all.c
index a8e0a95417..bf84a1d85a 100644
--- a/stubs/bdrv-commit-all.c
+++ b/stubs/bdrv-commit-all.c
@@ -1,3 +1,4 @@
+#include "qemu/osdep.h"
#include "qemu-common.h"
#include "block/block.h"
diff --git a/stubs/clock-warp.c b/stubs/clock-warp.c
index 5565118d11..5ae32b9e6a 100644
--- a/stubs/clock-warp.c
+++ b/stubs/clock-warp.c
@@ -1,3 +1,4 @@
+#include "qemu/osdep.h"
#include "qemu-common.h"
#include "qemu/timer.h"
diff --git a/stubs/cpu-get-clock.c b/stubs/cpu-get-clock.c
index 5b34c976d9..1d07523b86 100644
--- a/stubs/cpu-get-clock.c
+++ b/stubs/cpu-get-clock.c
@@ -1,3 +1,4 @@
+#include "qemu/osdep.h"
#include "qemu-common.h"
#include "qemu/timer.h"
diff --git a/stubs/cpu-get-icount.c b/stubs/cpu-get-icount.c
index d68585965f..3a6f2ab00f 100644
--- a/stubs/cpu-get-icount.c
+++ b/stubs/cpu-get-icount.c
@@ -1,3 +1,4 @@
+#include "qemu/osdep.h"
#include "qemu-common.h"
#include "qemu/timer.h"
diff --git a/stubs/cpus.c b/stubs/cpus.c
index 8e6f06b116..e19272297a 100644
--- a/stubs/cpus.c
+++ b/stubs/cpus.c
@@ -1,3 +1,4 @@
+#include "qemu/osdep.h"
#include "qemu-common.h"
#include "qom/cpu.h"
diff --git a/stubs/dump.c b/stubs/dump.c
index 8c24eda847..d9ee23f1eb 100644
--- a/stubs/dump.c
+++ b/stubs/dump.c
@@ -11,6 +11,7 @@
*
*/
+#include "qemu/osdep.h"
#include "qemu-common.h"
#include "sysemu/dump-arch.h"
#include "qmp-commands.h"
diff --git a/stubs/fd-register.c b/stubs/fd-register.c
index d0c34fd2a3..f91aa34185 100644
--- a/stubs/fd-register.c
+++ b/stubs/fd-register.c
@@ -1,3 +1,4 @@
+#include "qemu/osdep.h"
#include "qemu-common.h"
#include "qemu/main-loop.h"
diff --git a/stubs/fdset-add-fd.c b/stubs/fdset-add-fd.c
index ee1643708c..bf9e60aed5 100644
--- a/stubs/fdset-add-fd.c
+++ b/stubs/fdset-add-fd.c
@@ -1,3 +1,4 @@
+#include "qemu/osdep.h"
#include "qemu-common.h"
#include "monitor/monitor.h"
diff --git a/stubs/fdset-find-fd.c b/stubs/fdset-find-fd.c
index 4f18344bad..1d9caf37ec 100644
--- a/stubs/fdset-find-fd.c
+++ b/stubs/fdset-find-fd.c
@@ -1,3 +1,4 @@
+#include "qemu/osdep.h"
#include "qemu-common.h"
#include "monitor/monitor.h"
diff --git a/stubs/fdset-get-fd.c b/stubs/fdset-get-fd.c
index 7112c155e3..5325044b5a 100644
--- a/stubs/fdset-get-fd.c
+++ b/stubs/fdset-get-fd.c
@@ -1,3 +1,4 @@
+#include "qemu/osdep.h"
#include "qemu-common.h"
#include "monitor/monitor.h"
diff --git a/stubs/fdset-remove-fd.c b/stubs/fdset-remove-fd.c
index 7f6d61e619..47ea297210 100644
--- a/stubs/fdset-remove-fd.c
+++ b/stubs/fdset-remove-fd.c
@@ -1,3 +1,4 @@
+#include "qemu/osdep.h"
#include "qemu-common.h"
#include "monitor/monitor.h"
diff --git a/stubs/gdbstub.c b/stubs/gdbstub.c
index f6a4553a31..359c28990a 100644
--- a/stubs/gdbstub.c
+++ b/stubs/gdbstub.c
@@ -1,3 +1,4 @@
+#include "qemu/osdep.h"
#include "stdbool.h" /* bool (in exec/gdbstub.h) */
#include "stddef.h" /* NULL */
#include "exec/gdbstub.h" /* xml_builtin */
diff --git a/stubs/get-fd.c b/stubs/get-fd.c
index 9f2c65cf0a..85881fb678 100644
--- a/stubs/get-fd.c
+++ b/stubs/get-fd.c
@@ -1,3 +1,4 @@
+#include "qemu/osdep.h"
#include "qemu-common.h"
#include "monitor/monitor.h"
diff --git a/stubs/get-next-serial.c b/stubs/get-next-serial.c
index 40c56d13d7..6ff6a6d3b2 100644
--- a/stubs/get-next-serial.c
+++ b/stubs/get-next-serial.c
@@ -1,3 +1,4 @@
+#include "qemu/osdep.h"
#include "qemu-common.h"
CharDriverState *serial_hds[0];
diff --git a/stubs/get-vm-name.c b/stubs/get-vm-name.c
index e5f619ffab..fa990136b0 100644
--- a/stubs/get-vm-name.c
+++ b/stubs/get-vm-name.c
@@ -1,3 +1,4 @@
+#include "qemu/osdep.h"
#include "qemu-common.h"
const char *qemu_get_vm_name(void)
diff --git a/stubs/iothread-lock.c b/stubs/iothread-lock.c
index dda6f6b58d..9b6db2e740 100644
--- a/stubs/iothread-lock.c
+++ b/stubs/iothread-lock.c
@@ -1,3 +1,4 @@
+#include "qemu/osdep.h"
#include "qemu-common.h"
#include "qemu/main-loop.h"
diff --git a/stubs/is-daemonized.c b/stubs/is-daemonized.c
index c0ee9171a7..d5cd1dc371 100644
--- a/stubs/is-daemonized.c
+++ b/stubs/is-daemonized.c
@@ -1,3 +1,4 @@
+#include "qemu/osdep.h"
#include "qemu-common.h"
/* Win32 has its own inline stub */
diff --git a/stubs/kvm.c b/stubs/kvm.c
index 828b824f2c..ddd620499d 100644
--- a/stubs/kvm.c
+++ b/stubs/kvm.c
@@ -1,3 +1,4 @@
+#include "qemu/osdep.h"
#include "qemu-common.h"
#include "sysemu/kvm.h"
diff --git a/stubs/machine-init-done.c b/stubs/machine-init-done.c
index 28a92555b6..9a0d62514f 100644
--- a/stubs/machine-init-done.c
+++ b/stubs/machine-init-done.c
@@ -1,3 +1,4 @@
+#include "qemu/osdep.h"
#include "qemu-common.h"
#include "sysemu/sysemu.h"
diff --git a/stubs/migr-blocker.c b/stubs/migr-blocker.c
index 300df6e205..8ab3604dfa 100644
--- a/stubs/migr-blocker.c
+++ b/stubs/migr-blocker.c
@@ -1,3 +1,4 @@
+#include "qemu/osdep.h"
#include "qemu-common.h"
#include "migration/migration.h"
diff --git a/stubs/mon-is-qmp.c b/stubs/mon-is-qmp.c
index dd26f19c87..a8344ced80 100644
--- a/stubs/mon-is-qmp.c
+++ b/stubs/mon-is-qmp.c
@@ -1,3 +1,4 @@
+#include "qemu/osdep.h"
#include "qemu-common.h"
#include "monitor/monitor.h"
diff --git a/stubs/mon-printf.c b/stubs/mon-printf.c
index 0ce2ca6925..e7c1e0cf74 100644
--- a/stubs/mon-printf.c
+++ b/stubs/mon-printf.c
@@ -1,3 +1,4 @@
+#include "qemu/osdep.h"
#include "qemu-common.h"
#include "monitor/monitor.h"
diff --git a/stubs/monitor-init.c b/stubs/monitor-init.c
index 563902b412..de1bc7cd54 100644
--- a/stubs/monitor-init.c
+++ b/stubs/monitor-init.c
@@ -1,3 +1,4 @@
+#include "qemu/osdep.h"
#include "qemu-common.h"
#include "monitor/monitor.h"
diff --git a/stubs/notify-event.c b/stubs/notify-event.c
index 32f7289d3a..14e52268a8 100644
--- a/stubs/notify-event.c
+++ b/stubs/notify-event.c
@@ -1,3 +1,4 @@
+#include "qemu/osdep.h"
#include "qemu-common.h"
#include "qemu/main-loop.h"
diff --git a/stubs/qmp_pc_dimm_device_list.c b/stubs/qmp_pc_dimm_device_list.c
index b584bd8b24..a4af7fe473 100644
--- a/stubs/qmp_pc_dimm_device_list.c
+++ b/stubs/qmp_pc_dimm_device_list.c
@@ -1,3 +1,4 @@
+#include "qemu/osdep.h"
#include "qom/object.h"
#include "hw/mem/pc-dimm.h"
diff --git a/stubs/qtest.c b/stubs/qtest.c
index 4dfde6104d..891eb954fb 100644
--- a/stubs/qtest.c
+++ b/stubs/qtest.c
@@ -8,6 +8,7 @@
* See the COPYING file in the top-level directory.
*/
+#include "qemu/osdep.h"
#include "sysemu/qtest.h"
/* Needed for qtest_allowed() */
diff --git a/stubs/replay-user.c b/stubs/replay-user.c
index cf330721c8..b29e7ebba1 100644
--- a/stubs/replay-user.c
+++ b/stubs/replay-user.c
@@ -9,6 +9,7 @@
*
*/
+#include "qemu/osdep.h"
#include "sysemu/replay.h"
bool replay_exception(void)
diff --git a/stubs/replay.c b/stubs/replay.c
index 8f98790257..00ca01f55a 100644
--- a/stubs/replay.c
+++ b/stubs/replay.c
@@ -1,5 +1,5 @@
+#include "qemu/osdep.h"
#include "sysemu/replay.h"
-#include <stdlib.h>
#include "sysemu/sysemu.h"
ReplayMode replay_mode;
diff --git a/stubs/reset.c b/stubs/reset.c
index ad287251ed..5d47711f9a 100644
--- a/stubs/reset.c
+++ b/stubs/reset.c
@@ -1,3 +1,4 @@
+#include "qemu/osdep.h"
#include "hw/hw.h"
/* Stub functions for binaries that never call qemu_devices_reset(),
diff --git a/stubs/runstate-check.c b/stubs/runstate-check.c
index bd2e3757ae..7c5227e848 100644
--- a/stubs/runstate-check.c
+++ b/stubs/runstate-check.c
@@ -1,3 +1,4 @@
+#include "qemu/osdep.h"
#include "sysemu/sysemu.h"
bool runstate_check(RunState state)
diff --git a/stubs/set-fd-handler.c b/stubs/set-fd-handler.c
index a8481bc3c1..26965de4c3 100644
--- a/stubs/set-fd-handler.c
+++ b/stubs/set-fd-handler.c
@@ -1,3 +1,4 @@
+#include "qemu/osdep.h"
#include "qemu-common.h"
#include "qemu/main-loop.h"
diff --git a/stubs/slirp.c b/stubs/slirp.c
index bd0ac7f27d..dcae51f0e5 100644
--- a/stubs/slirp.c
+++ b/stubs/slirp.c
@@ -1,3 +1,4 @@
+#include "qemu/osdep.h"
#include "qemu-common.h"
#include "slirp/slirp.h"
diff --git a/stubs/sysbus.c b/stubs/sysbus.c
index e13496582b..d8da90caae 100644
--- a/stubs/sysbus.c
+++ b/stubs/sysbus.c
@@ -1,3 +1,4 @@
+#include "qemu/osdep.h"
#include "hw/qdev-core.h"
BusState *sysbus_get_default(void)
diff --git a/stubs/target-get-monitor-def.c b/stubs/target-get-monitor-def.c
index 711a9ae46b..013e6571e5 100644
--- a/stubs/target-get-monitor-def.c
+++ b/stubs/target-get-monitor-def.c
@@ -19,6 +19,7 @@
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
+#include "qemu/osdep.h"
#include "stdint.h"
typedef struct CPUState CPUState;
diff --git a/stubs/target-monitor-defs.c b/stubs/target-monitor-defs.c
index 7d8d182b23..203ebb0f27 100644
--- a/stubs/target-monitor-defs.c
+++ b/stubs/target-monitor-defs.c
@@ -1,3 +1,4 @@
+#include "qemu/osdep.h"
#include "stddef.h"
#include "qemu/typedefs.h"
diff --git a/stubs/uuid.c b/stubs/uuid.c
index ffc0ed40ae..92ad717831 100644
--- a/stubs/uuid.c
+++ b/stubs/uuid.c
@@ -1,3 +1,4 @@
+#include "qemu/osdep.h"
#include "qemu-common.h"
#include "sysemu/sysemu.h"
#include "qmp-commands.h"
diff --git a/stubs/vhost.c b/stubs/vhost.c
index d346b856f5..2d76cdebdc 100644
--- a/stubs/vhost.c
+++ b/stubs/vhost.c
@@ -1,3 +1,4 @@
+#include "qemu/osdep.h"
#include "hw/virtio/vhost.h"
bool vhost_has_free_slot(void)
diff --git a/stubs/vm-stop.c b/stubs/vm-stop.c
index 69fd86b2e8..8271cad65d 100644
--- a/stubs/vm-stop.c
+++ b/stubs/vm-stop.c
@@ -1,3 +1,4 @@
+#include "qemu/osdep.h"
#include "qemu-common.h"
#include "sysemu/sysemu.h"
diff --git a/stubs/vmstate.c b/stubs/vmstate.c
index 778bc3fc69..65906271d2 100644
--- a/stubs/vmstate.c
+++ b/stubs/vmstate.c
@@ -1,3 +1,4 @@
+#include "qemu/osdep.h"
#include "qemu-common.h"
#include "migration/vmstate.h"
diff --git a/target-arm/cpu.c b/target-arm/cpu.c
index 0e582c4410..7ddbf3d19b 100644
--- a/target-arm/cpu.c
+++ b/target-arm/cpu.c
@@ -650,6 +650,15 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
cpu->id_aa64pfr0 &= ~0xf000;
}
+ if (!arm_feature(env, ARM_FEATURE_EL2)) {
+ /* Disable the hypervisor feature bits in the processor feature
+ * registers if we don't have EL2. These are id_pfr1[15:12] and
+ * id_aa64pfr0_el1[11:8].
+ */
+ cpu->id_aa64pfr0 &= ~0xf00;
+ cpu->id_pfr1 &= ~0xf000;
+ }
+
if (!cpu->has_mpu) {
unset_feature(env, ARM_FEATURE_MPU);
}
diff --git a/target-arm/helper.c b/target-arm/helper.c
index ae024869d0..5ea507f5bc 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -3167,6 +3167,35 @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
.type = ARM_CP_ALIAS,
.fieldoffset = offsetof(CPUARMState, vfp.xregs[ARM_VFP_FPEXC]),
.access = PL2_RW, .accessfn = fpexc32_access },
+ { .name = "DACR32_EL2", .state = ARM_CP_STATE_AA64,
+ .opc0 = 3, .opc1 = 4, .crn = 3, .crm = 0, .opc2 = 0,
+ .access = PL2_RW, .resetvalue = 0,
+ .writefn = dacr_write, .raw_writefn = raw_write,
+ .fieldoffset = offsetof(CPUARMState, cp15.dacr32_el2) },
+ { .name = "IFSR32_EL2", .state = ARM_CP_STATE_AA64,
+ .opc0 = 3, .opc1 = 4, .crn = 5, .crm = 0, .opc2 = 1,
+ .access = PL2_RW, .resetvalue = 0,
+ .fieldoffset = offsetof(CPUARMState, cp15.ifsr32_el2) },
+ { .name = "SPSR_IRQ", .state = ARM_CP_STATE_AA64,
+ .type = ARM_CP_ALIAS,
+ .opc0 = 3, .opc1 = 4, .crn = 4, .crm = 3, .opc2 = 0,
+ .access = PL2_RW,
+ .fieldoffset = offsetof(CPUARMState, banked_spsr[BANK_IRQ]) },
+ { .name = "SPSR_ABT", .state = ARM_CP_STATE_AA64,
+ .type = ARM_CP_ALIAS,
+ .opc0 = 3, .opc1 = 4, .crn = 4, .crm = 3, .opc2 = 1,
+ .access = PL2_RW,
+ .fieldoffset = offsetof(CPUARMState, banked_spsr[BANK_ABT]) },
+ { .name = "SPSR_UND", .state = ARM_CP_STATE_AA64,
+ .type = ARM_CP_ALIAS,
+ .opc0 = 3, .opc1 = 4, .crn = 4, .crm = 3, .opc2 = 2,
+ .access = PL2_RW,
+ .fieldoffset = offsetof(CPUARMState, banked_spsr[BANK_UND]) },
+ { .name = "SPSR_FIQ", .state = ARM_CP_STATE_AA64,
+ .type = ARM_CP_ALIAS,
+ .opc0 = 3, .opc1 = 4, .crn = 4, .crm = 3, .opc2 = 3,
+ .access = PL2_RW,
+ .fieldoffset = offsetof(CPUARMState, banked_spsr[BANK_FIQ]) },
REGINFO_SENTINEL
};
@@ -3294,11 +3323,6 @@ static const ARMCPRegInfo el2_cp_reginfo[] = {
.opc0 = 3, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 0,
.access = PL2_RW, .fieldoffset = offsetof(CPUARMState, cp15.hcr_el2),
.writefn = hcr_write },
- { .name = "DACR32_EL2", .state = ARM_CP_STATE_AA64,
- .opc0 = 3, .opc1 = 4, .crn = 3, .crm = 0, .opc2 = 0,
- .access = PL2_RW, .resetvalue = 0,
- .writefn = dacr_write, .raw_writefn = raw_write,
- .fieldoffset = offsetof(CPUARMState, cp15.dacr32_el2) },
{ .name = "ELR_EL2", .state = ARM_CP_STATE_AA64,
.type = ARM_CP_ALIAS,
.opc0 = 3, .opc1 = 4, .crn = 4, .crm = 0, .opc2 = 1,
@@ -3308,10 +3332,6 @@ static const ARMCPRegInfo el2_cp_reginfo[] = {
.type = ARM_CP_ALIAS,
.opc0 = 3, .opc1 = 4, .crn = 5, .crm = 2, .opc2 = 0,
.access = PL2_RW, .fieldoffset = offsetof(CPUARMState, cp15.esr_el[2]) },
- { .name = "IFSR32_EL2", .state = ARM_CP_STATE_AA64,
- .opc0 = 3, .opc1 = 4, .crn = 5, .crm = 0, .opc2 = 1,
- .access = PL2_RW, .resetvalue = 0,
- .fieldoffset = offsetof(CPUARMState, cp15.ifsr32_el2) },
{ .name = "FAR_EL2", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 4, .crn = 6, .crm = 0, .opc2 = 0,
.access = PL2_RW, .fieldoffset = offsetof(CPUARMState, cp15.far_el[2]) },
@@ -3320,26 +3340,6 @@ static const ARMCPRegInfo el2_cp_reginfo[] = {
.opc0 = 3, .opc1 = 4, .crn = 4, .crm = 0, .opc2 = 0,
.access = PL2_RW,
.fieldoffset = offsetof(CPUARMState, banked_spsr[BANK_HYP]) },
- { .name = "SPSR_IRQ", .state = ARM_CP_STATE_AA64,
- .type = ARM_CP_ALIAS,
- .opc0 = 3, .opc1 = 4, .crn = 4, .crm = 3, .opc2 = 0,
- .access = PL2_RW,
- .fieldoffset = offsetof(CPUARMState, banked_spsr[BANK_IRQ]) },
- { .name = "SPSR_ABT", .state = ARM_CP_STATE_AA64,
- .type = ARM_CP_ALIAS,
- .opc0 = 3, .opc1 = 4, .crn = 4, .crm = 3, .opc2 = 1,
- .access = PL2_RW,
- .fieldoffset = offsetof(CPUARMState, banked_spsr[BANK_ABT]) },
- { .name = "SPSR_UND", .state = ARM_CP_STATE_AA64,
- .type = ARM_CP_ALIAS,
- .opc0 = 3, .opc1 = 4, .crn = 4, .crm = 3, .opc2 = 2,
- .access = PL2_RW,
- .fieldoffset = offsetof(CPUARMState, banked_spsr[BANK_UND]) },
- { .name = "SPSR_FIQ", .state = ARM_CP_STATE_AA64,
- .type = ARM_CP_ALIAS,
- .opc0 = 3, .opc1 = 4, .crn = 4, .crm = 3, .opc2 = 3,
- .access = PL2_RW,
- .fieldoffset = offsetof(CPUARMState, banked_spsr[BANK_FIQ]) },
{ .name = "VBAR_EL2", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 4, .crn = 12, .crm = 0, .opc2 = 0,
.access = PL2_RW, .writefn = vbar_write,
@@ -6763,24 +6763,34 @@ typedef enum {
} MMUFaultType;
/*
- * check_s2_startlevel
+ * check_s2_mmu_setup
* @cpu: ARMCPU
* @is_aa64: True if the translation regime is in AArch64 state
* @startlevel: Suggested starting level
* @inputsize: Bitsize of IPAs
* @stride: Page-table stride (See the ARM ARM)
*
- * Returns true if the suggested starting level is OK and false otherwise.
+ * Returns true if the suggested S2 translation parameters are OK and
+ * false otherwise.
*/
-static bool check_s2_startlevel(ARMCPU *cpu, bool is_aa64, int level,
- int inputsize, int stride)
+static bool check_s2_mmu_setup(ARMCPU *cpu, bool is_aa64, int level,
+ int inputsize, int stride)
{
+ const int grainsize = stride + 3;
+ int startsizecheck;
+
/* Negative levels are never allowed. */
if (level < 0) {
return false;
}
+ startsizecheck = inputsize - ((3 - level) * stride + grainsize);
+ if (startsizecheck < 1 || startsizecheck > stride + 4) {
+ return false;
+ }
+
if (is_aa64) {
+ CPUARMState *env = &cpu->env;
unsigned int pamax = arm_pamax(cpu);
switch (stride) {
@@ -6802,21 +6812,20 @@ static bool check_s2_startlevel(ARMCPU *cpu, bool is_aa64, int level,
default:
g_assert_not_reached();
}
- } else {
- const int grainsize = stride + 3;
- int startsizecheck;
+ /* Inputsize checks. */
+ if (inputsize > pamax &&
+ (arm_el_is_aa64(env, 1) || inputsize > 40)) {
+ /* This is CONSTRAINED UNPREDICTABLE and we choose to fault. */
+ return false;
+ }
+ } else {
/* AArch32 only supports 4KB pages. Assert on that. */
assert(stride == 9);
if (level == 0) {
return false;
}
-
- startsizecheck = inputsize - ((3 - level) * stride + grainsize);
- if (startsizecheck < 1 || startsizecheck > stride + 4) {
- return false;
- }
}
return true;
}
@@ -7013,8 +7022,7 @@ static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
}
/* Check that the starting level is valid. */
- ok = check_s2_startlevel(cpu, va_size == 64, level,
- inputsize, stride);
+ ok = check_s2_mmu_setup(cpu, va_size == 64, level, inputsize, stride);
if (!ok) {
/* AArch64 reports these as level 0 faults.
* AArch32 reports these as level 1 faults.
diff --git a/tcg-runtime.c b/tcg-runtime.c
index 9daba6945e..ea2ad649cb 100644
--- a/tcg-runtime.c
+++ b/tcg-runtime.c
@@ -21,7 +21,7 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
-#include <stdint.h>
+#include "qemu/osdep.h"
#include "qemu/host-utils.h"
/* This file is compiled once, and thus we can't include the standard
diff --git a/tci.c b/tci.c
index b5ed7b1f7a..7cbb39ed4b 100644
--- a/tci.c
+++ b/tci.c
@@ -17,7 +17,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "config.h"
+#include "qemu/osdep.h"
/* Defining NDEBUG disables assertions (which makes the code faster). */
#if !defined(CONFIG_DEBUG_TCG) && !defined(NDEBUG)
diff --git a/thread-pool.c b/thread-pool.c
index 402c778b47..03ba0b02a4 100644
--- a/thread-pool.c
+++ b/thread-pool.c
@@ -14,10 +14,10 @@
* Contributions after 2012-01-13 are licensed under the terms of the
* GNU GPL, version 2 or (at your option) any later version.
*/
+#include "qemu/osdep.h"
#include "qemu-common.h"
#include "qemu/queue.h"
#include "qemu/thread.h"
-#include "qemu/osdep.h"
#include "qemu/coroutine.h"
#include "trace.h"
#include "block/thread-pool.h"
diff --git a/thunk.c b/thunk.c
index f501fd72fc..f057d86d94 100644
--- a/thunk.c
+++ b/thunk.c
@@ -16,9 +16,7 @@
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdarg.h>
+#include "qemu/osdep.h"
#include "qemu.h"
#include "exec/user/thunk.h"
diff --git a/tpm.c b/tpm.c
index 0a3e3d5032..9ed708e22b 100644
--- a/tpm.c
+++ b/tpm.c
@@ -11,7 +11,7 @@
*
* Based on net.c
*/
-#include "config-host.h"
+#include "qemu/osdep.h"
#include "qapi/qmp/qerror.h"
#include "sysemu/tpm_backend.h"
diff --git a/trace/control.c b/trace/control.c
index 84ea840892..20d3370bf8 100644
--- a/trace/control.c
+++ b/trace/control.c
@@ -7,6 +7,7 @@
* See the COPYING file in the top-level directory.
*/
+#include "qemu/osdep.h"
#include "trace/control.h"
#ifdef CONFIG_TRACE_SIMPLE
#include "trace/simple.h"
diff --git a/trace/ftrace.c b/trace/ftrace.c
index a7ae371e6f..e953922f5b 100644
--- a/trace/ftrace.c
+++ b/trace/ftrace.c
@@ -9,10 +9,7 @@
*
*/
-#include <stdio.h>
-#include <string.h>
-#include <fcntl.h>
-#include <limits.h>
+#include "qemu/osdep.h"
#include "trace.h"
#include "trace/control.h"
diff --git a/trace/qmp.c b/trace/qmp.c
index 0b19489528..6320b4b3b1 100644
--- a/trace/qmp.c
+++ b/trace/qmp.c
@@ -7,6 +7,7 @@
* See the COPYING file in the top-level directory.
*/
+#include "qemu/osdep.h"
#include "qemu/typedefs.h"
#include "qmp-commands.h"
#include "trace/control.h"
diff --git a/trace/simple.c b/trace/simple.c
index e8594cd00d..3fdcc82263 100644
--- a/trace/simple.c
+++ b/trace/simple.c
@@ -8,12 +8,8 @@
*
*/
-#include <stdlib.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <time.h>
+#include "qemu/osdep.h"
#ifndef _WIN32
-#include <signal.h>
#include <pthread.h>
#endif
#include "qemu/timer.h"
diff --git a/ui/console-gl.c b/ui/console-gl.c
index baf397b300..74b1bed6ee 100644
--- a/ui/console-gl.c
+++ b/ui/console-gl.c
@@ -24,6 +24,7 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
+#include "qemu/osdep.h"
#include "qemu-common.h"
#include "ui/console.h"
#include "ui/shader.h"
diff --git a/ui/console.c b/ui/console.c
index 791b4fcea2..b739ae9a05 100644
--- a/ui/console.c
+++ b/ui/console.c
@@ -21,6 +21,7 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
+#include "qemu/osdep.h"
#include "qemu-common.h"
#include "ui/console.h"
#include "hw/qdev-core.h"
diff --git a/ui/curses.c b/ui/curses.c
index 274e09b0be..b47558956c 100644
--- a/ui/curses.c
+++ b/ui/curses.c
@@ -21,6 +21,7 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
+#include "qemu/osdep.h"
#include <curses.h>
#ifndef _WIN32
diff --git a/ui/cursor.c b/ui/cursor.c
index 2b8dd3fa50..a276e01f1c 100644
--- a/ui/cursor.c
+++ b/ui/cursor.c
@@ -1,3 +1,4 @@
+#include "qemu/osdep.h"
#include "qemu-common.h"
#include "ui/console.h"
diff --git a/ui/egl-context.c b/ui/egl-context.c
index 40102e392e..3a02b68d1a 100644
--- a/ui/egl-context.c
+++ b/ui/egl-context.c
@@ -1,3 +1,4 @@
+#include "qemu/osdep.h"
#include "qemu-common.h"
#include "ui/egl-context.h"
diff --git a/ui/egl-helpers.c b/ui/egl-helpers.c
index 87d77afaa8..4c83834615 100644
--- a/ui/egl-helpers.c
+++ b/ui/egl-helpers.c
@@ -1,11 +1,4 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdint.h>
-#include <stdbool.h>
-#include <unistd.h>
-#include <string.h>
-#include <errno.h>
-#include <fcntl.h>
+#include "qemu/osdep.h"
#include <glob.h>
#include "ui/egl-helpers.h"
diff --git a/ui/gtk-egl.c b/ui/gtk-egl.c
index 500c42c9fa..431457c746 100644
--- a/ui/gtk-egl.c
+++ b/ui/gtk-egl.c
@@ -11,6 +11,7 @@
* See the COPYING file in the top-level directory.
*/
+#include "qemu/osdep.h"
#include "qemu-common.h"
#include "trace.h"
diff --git a/ui/gtk-gl-area.c b/ui/gtk-gl-area.c
index dec3edb296..b86ff3cbec 100644
--- a/ui/gtk-gl-area.c
+++ b/ui/gtk-gl-area.c
@@ -7,6 +7,7 @@
* See the COPYING file in the top-level directory.
*/
+#include "qemu/osdep.h"
#include "qemu-common.h"
#include "trace.h"
diff --git a/ui/gtk.c b/ui/gtk.c
index c8dbd5c7f0..2b46965f80 100644
--- a/ui/gtk.c
+++ b/ui/gtk.c
@@ -34,6 +34,7 @@
#define GETTEXT_PACKAGE "qemu"
#define LOCALEDIR "po"
+#include "qemu/osdep.h"
#include "qemu-common.h"
#include "ui/console.h"
diff --git a/ui/input-keymap.c b/ui/input-keymap.c
index 63d71d2632..fd2c09ddc2 100644
--- a/ui/input-keymap.c
+++ b/ui/input-keymap.c
@@ -1,3 +1,4 @@
+#include "qemu/osdep.h"
#include "sysemu/sysemu.h"
#include "ui/keymaps.h"
#include "ui/input.h"
diff --git a/ui/input-legacy.c b/ui/input-legacy.c
index 3454055084..c97eac1778 100644
--- a/ui/input-legacy.c
+++ b/ui/input-legacy.c
@@ -22,9 +22,9 @@
* THE SOFTWARE.
*/
+#include "qemu/osdep.h"
#include "sysemu/sysemu.h"
#include "ui/console.h"
-#include "qapi/error.h"
#include "qmp-commands.h"
#include "qapi-types.h"
#include "ui/keymaps.h"
diff --git a/ui/input.c b/ui/input.c
index 006667b3d5..bdcb974a89 100644
--- a/ui/input.c
+++ b/ui/input.c
@@ -1,3 +1,4 @@
+#include "qemu/osdep.h"
#include "hw/qdev.h"
#include "sysemu/sysemu.h"
#include "qapi-types.h"
diff --git a/ui/keymaps.c b/ui/keymaps.c
index 1b9ba3fa24..8899a0b31e 100644
--- a/ui/keymaps.c
+++ b/ui/keymaps.c
@@ -22,6 +22,7 @@
* THE SOFTWARE.
*/
+#include "qemu/osdep.h"
#include "keymaps.h"
#include "sysemu/sysemu.h"
diff --git a/ui/qemu-pixman.c b/ui/qemu-pixman.c
index 4116e1507b..c9f8dce7f4 100644
--- a/ui/qemu-pixman.c
+++ b/ui/qemu-pixman.c
@@ -3,6 +3,7 @@
* See the COPYING file in the top-level directory.
*/
+#include "qemu/osdep.h"
#include "qemu-common.h"
#include "ui/console.h"
diff --git a/ui/sdl.c b/ui/sdl.c
index f215fe140d..9804ee8dfb 100644
--- a/ui/sdl.c
+++ b/ui/sdl.c
@@ -25,6 +25,7 @@
/* Avoid compiler warning because macro is redefined in SDL_syswm.h. */
#undef WIN32_LEAN_AND_MEAN
+#include "qemu/osdep.h"
#include <SDL.h>
#include <SDL_syswm.h>
diff --git a/ui/sdl2-2d.c b/ui/sdl2-2d.c
index 191ee3b52d..95930061ea 100644
--- a/ui/sdl2-2d.c
+++ b/ui/sdl2-2d.c
@@ -23,6 +23,7 @@
*/
/* Ported SDL 1.2 code to 2.0 by Dave Airlie. */
+#include "qemu/osdep.h"
#include "qemu-common.h"
#include "ui/console.h"
#include "ui/input.h"
diff --git a/ui/sdl2-gl.c b/ui/sdl2-gl.c
index 2bb3d06bab..a324ecacac 100644
--- a/ui/sdl2-gl.c
+++ b/ui/sdl2-gl.c
@@ -25,6 +25,7 @@
* THE SOFTWARE.
*/
+#include "qemu/osdep.h"
#include "qemu-common.h"
#include "ui/console.h"
#include "ui/input.h"
diff --git a/ui/sdl2-input.c b/ui/sdl2-input.c
index ac5dc9476b..6e315ae800 100644
--- a/ui/sdl2-input.c
+++ b/ui/sdl2-input.c
@@ -23,6 +23,7 @@
*/
/* Ported SDL 1.2 code to 2.0 by Dave Airlie. */
+#include "qemu/osdep.h"
#include "qemu-common.h"
#include "ui/console.h"
#include "ui/input.h"
diff --git a/ui/sdl2.c b/ui/sdl2.c
index c0a76d7744..e0128ad755 100644
--- a/ui/sdl2.c
+++ b/ui/sdl2.c
@@ -23,6 +23,7 @@
*/
/* Ported SDL 1.2 code to 2.0 by Dave Airlie. */
+#include "qemu/osdep.h"
#include "qemu-common.h"
#include "ui/console.h"
#include "ui/input.h"
diff --git a/ui/sdl_zoom.c b/ui/sdl_zoom.c
index 2625c4557e..72622c2647 100644
--- a/ui/sdl_zoom.c
+++ b/ui/sdl_zoom.c
@@ -11,11 +11,9 @@
*
*/
-#include "sdl_zoom.h"
#include "qemu/osdep.h"
+#include "sdl_zoom.h"
#include <glib.h>
-#include <stdint.h>
-#include <stdio.h>
static void sdl_zoom_rgb16(SDL_Surface *src, SDL_Surface *dst, int smooth,
SDL_Rect *dst_rect);
diff --git a/ui/shader.c b/ui/shader.c
index 0588655cfe..9264009b80 100644
--- a/ui/shader.c
+++ b/ui/shader.c
@@ -24,6 +24,7 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
+#include "qemu/osdep.h"
#include "qemu-common.h"
#include "ui/shader.h"
diff --git a/ui/spice-core.c b/ui/spice-core.c
index 8f27768819..4dbd99ab19 100644
--- a/ui/spice-core.c
+++ b/ui/spice-core.c
@@ -15,6 +15,7 @@
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
+#include "qemu/osdep.h"
#include <spice.h>
#include <netdb.h>
diff --git a/ui/spice-display.c b/ui/spice-display.c
index 0489131968..8a5b3258bd 100644
--- a/ui/spice-display.c
+++ b/ui/spice-display.c
@@ -15,6 +15,7 @@
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
+#include "qemu/osdep.h"
#include "qemu-common.h"
#include "ui/qemu-spice.h"
#include "qemu/timer.h"
diff --git a/ui/spice-input.c b/ui/spice-input.c
index 2b3b9ed714..72e406382f 100644
--- a/ui/spice-input.c
+++ b/ui/spice-input.c
@@ -15,10 +15,7 @@
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdbool.h>
-#include <string.h>
+#include "qemu/osdep.h"
#include <spice.h>
#include <spice/enums.h>
diff --git a/ui/vnc-auth-sasl.c b/ui/vnc-auth-sasl.c
index de8abc96d4..13a59f500e 100644
--- a/ui/vnc-auth-sasl.c
+++ b/ui/vnc-auth-sasl.c
@@ -22,6 +22,7 @@
* THE SOFTWARE.
*/
+#include "qemu/osdep.h"
#include "vnc.h"
/* Max amount of data we send/recv for SASL steps to prevent DOS */
diff --git a/ui/vnc-auth-vencrypt.c b/ui/vnc-auth-vencrypt.c
index 093dd2f4c2..8f3bb11cea 100644
--- a/ui/vnc-auth-vencrypt.c
+++ b/ui/vnc-auth-vencrypt.c
@@ -24,6 +24,7 @@
* THE SOFTWARE.
*/
+#include "qemu/osdep.h"
#include "vnc.h"
#include "qemu/main-loop.h"
diff --git a/ui/vnc-enc-hextile.c b/ui/vnc-enc-hextile.c
index 2e768fd899..4215bd7daf 100644
--- a/ui/vnc-enc-hextile.c
+++ b/ui/vnc-enc-hextile.c
@@ -24,6 +24,7 @@
* THE SOFTWARE.
*/
+#include "qemu/osdep.h"
#include "vnc.h"
static void hextile_enc_cord(uint8_t *ptr, int x, int y, int w, int h)
diff --git a/ui/vnc-enc-tight.c b/ui/vnc-enc-tight.c
index 9a9ddf2e3c..e5cba0e5a7 100644
--- a/ui/vnc-enc-tight.c
+++ b/ui/vnc-enc-tight.c
@@ -26,7 +26,7 @@
* THE SOFTWARE.
*/
-#include "config-host.h"
+#include "qemu/osdep.h"
/* This needs to be before jpeglib.h line because of conflict with
INT32 definitions between jmorecfg.h (included by jpeglib.h) and
@@ -40,7 +40,6 @@
#include <png.h>
#endif
#ifdef CONFIG_VNC_JPEG
-#include <stdio.h>
#include <jpeglib.h>
#endif
diff --git a/ui/vnc-enc-zlib.c b/ui/vnc-enc-zlib.c
index d1b97f2516..33e9df2f6a 100644
--- a/ui/vnc-enc-zlib.c
+++ b/ui/vnc-enc-zlib.c
@@ -24,6 +24,7 @@
* THE SOFTWARE.
*/
+#include "qemu/osdep.h"
#include "vnc.h"
#define ZALLOC_ALIGNMENT 16
diff --git a/ui/vnc-enc-zrle-template.c b/ui/vnc-enc-zrle-template.c
index 70ae624ee9..abf6b86e4e 100644
--- a/ui/vnc-enc-zrle-template.c
+++ b/ui/vnc-enc-zrle-template.c
@@ -22,7 +22,7 @@
*/
-#include <assert.h>
+#include "qemu/osdep.h"
#undef ZRLE_ENDIAN_SUFFIX
diff --git a/ui/vnc-enc-zrle.c b/ui/vnc-enc-zrle.c
index ed3b48465d..5489870e70 100644
--- a/ui/vnc-enc-zrle.c
+++ b/ui/vnc-enc-zrle.c
@@ -26,6 +26,7 @@
* THE SOFTWARE.
*/
+#include "qemu/osdep.h"
#include "vnc.h"
#include "vnc-enc-zrle.h"
diff --git a/ui/vnc-enc-zywrle-template.c b/ui/vnc-enc-zywrle-template.c
index 561f7bfabb..b446380a7a 100644
--- a/ui/vnc-enc-zywrle-template.c
+++ b/ui/vnc-enc-zywrle-template.c
@@ -100,6 +100,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endif
#define ZYWRLE_QUANTIZE
+#include "qemu/osdep.h"
#include "vnc-enc-zywrle.h"
#ifndef ZRLE_COMPACT_PIXEL
diff --git a/ui/vnc-jobs.c b/ui/vnc-jobs.c
index 546635aabe..98ca978b06 100644
--- a/ui/vnc-jobs.c
+++ b/ui/vnc-jobs.c
@@ -26,6 +26,7 @@
*/
+#include "qemu/osdep.h"
#include "vnc.h"
#include "vnc-jobs.h"
#include "qemu/sockets.h"
diff --git a/ui/vnc-palette.c b/ui/vnc-palette.c
index c130deee9d..3b89d1af25 100644
--- a/ui/vnc-palette.c
+++ b/ui/vnc-palette.c
@@ -26,9 +26,9 @@
* THE SOFTWARE.
*/
+#include "qemu/osdep.h"
#include "vnc-palette.h"
#include <glib.h>
-#include <string.h>
static VncPaletteEntry *palette_find(const VncPalette *palette,
uint32_t color, unsigned int hash)
diff --git a/ui/vnc-ws.c b/ui/vnc-ws.c
index 80182334ef..1d3ecc2330 100644
--- a/ui/vnc-ws.c
+++ b/ui/vnc-ws.c
@@ -18,6 +18,7 @@
* along with this software; if not, see <http://www.gnu.org/licenses/>.
*/
+#include "qemu/osdep.h"
#include "vnc.h"
#include "io/channel-websock.h"
diff --git a/ui/vnc.c b/ui/vnc.c
index 339f8c35b2..b6bbea5f44 100644
--- a/ui/vnc.c
+++ b/ui/vnc.c
@@ -24,6 +24,7 @@
* THE SOFTWARE.
*/
+#include "qemu/osdep.h"
#include "vnc.h"
#include "vnc-jobs.h"
#include "trace.h"
@@ -37,7 +38,6 @@
#include "qapi/qmp/qerror.h"
#include "qapi/qmp/types.h"
#include "qmp-commands.h"
-#include "qemu/osdep.h"
#include "ui/input.h"
#include "qapi-event.h"
#include "crypto/hash.h"
diff --git a/ui/x_keymap.c b/ui/x_keymap.c
index 1a773174f6..27884851de 100644
--- a/ui/x_keymap.c
+++ b/ui/x_keymap.c
@@ -21,6 +21,7 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
+#include "qemu/osdep.h"
#include "qemu-common.h"
#include "x_keymap.h"
diff --git a/user-exec.c b/user-exec.c
index 8ad89a466b..d8d597bafe 100644
--- a/user-exec.c
+++ b/user-exec.c
@@ -16,7 +16,7 @@
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
-#include "config.h"
+#include "qemu/osdep.h"
#include "cpu.h"
#include "disas/disas.h"
#include "tcg.h"
@@ -33,7 +33,6 @@
#undef ESI
#undef EDI
#undef EIP
-#include <signal.h>
#ifdef __linux__
#include <sys/ucontext.h>
#endif
diff --git a/util/acl.c b/util/acl.c
index 571d686156..723b6a89b4 100644
--- a/util/acl.c
+++ b/util/acl.c
@@ -23,6 +23,7 @@
*/
+#include "qemu/osdep.h"
#include "qemu-common.h"
#include "qemu/acl.h"
diff --git a/util/base64.c b/util/base64.c
index f82caa7c8b..8aa2a5b3ac 100644
--- a/util/base64.c
+++ b/util/base64.c
@@ -18,6 +18,7 @@
*
*/
+#include "qemu/osdep.h"
#include <config-host.h>
#include "qemu/base64.h"
diff --git a/util/bitmap.c b/util/bitmap.c
index 44f0f481be..40aadfb4f3 100644
--- a/util/bitmap.c
+++ b/util/bitmap.c
@@ -9,6 +9,7 @@
* Version 2.
*/
+#include "qemu/osdep.h"
#include "qemu/bitops.h"
#include "qemu/bitmap.h"
#include "qemu/atomic.h"
diff --git a/util/bitops.c b/util/bitops.c
index 227c38b883..b0c35dd5f1 100644
--- a/util/bitops.c
+++ b/util/bitops.c
@@ -11,6 +11,7 @@
* 2 of the License, or (at your option) any later version.
*/
+#include "qemu/osdep.h"
#include "qemu/bitops.h"
#define BITOP_WORD(nr) ((nr) / BITS_PER_LONG)
diff --git a/util/buffer.c b/util/buffer.c
index 8b27c08aac..a6118bf5b2 100644
--- a/util/buffer.c
+++ b/util/buffer.c
@@ -18,6 +18,7 @@
*
*/
+#include "qemu/osdep.h"
#include "qemu/buffer.h"
#include "trace.h"
diff --git a/util/compatfd.c b/util/compatfd.c
index e8571502be..9a43042ae6 100644
--- a/util/compatfd.c
+++ b/util/compatfd.c
@@ -13,6 +13,7 @@
* GNU GPL, version 2 or (at your option) any later version.
*/
+#include "qemu/osdep.h"
#include "qemu-common.h"
#include "qemu/compatfd.h"
#include "qemu/thread.h"
diff --git a/util/coroutine-gthread.c b/util/coroutine-gthread.c
index 0bcd77867d..fb697eb0b7 100644
--- a/util/coroutine-gthread.c
+++ b/util/coroutine-gthread.c
@@ -18,6 +18,7 @@
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
+#include "qemu/osdep.h"
#include <glib.h>
#include "qemu-common.h"
#include "qemu/coroutine_int.h"
diff --git a/util/coroutine-sigaltstack.c b/util/coroutine-sigaltstack.c
index 39842a4a90..6b8aee7a2b 100644
--- a/util/coroutine-sigaltstack.c
+++ b/util/coroutine-sigaltstack.c
@@ -25,11 +25,9 @@
#ifdef _FORTIFY_SOURCE
#undef _FORTIFY_SOURCE
#endif
-#include <stdlib.h>
+#include "qemu/osdep.h"
#include <setjmp.h>
-#include <stdint.h>
#include <pthread.h>
-#include <signal.h>
#include "qemu-common.h"
#include "qemu/coroutine_int.h"
diff --git a/util/coroutine-ucontext.c b/util/coroutine-ucontext.c
index 26cbebb7a7..4914f60199 100644
--- a/util/coroutine-ucontext.c
+++ b/util/coroutine-ucontext.c
@@ -22,9 +22,8 @@
#ifdef _FORTIFY_SOURCE
#undef _FORTIFY_SOURCE
#endif
-#include <stdlib.h>
+#include "qemu/osdep.h"
#include <setjmp.h>
-#include <stdint.h>
#include <ucontext.h>
#include "qemu-common.h"
#include "qemu/coroutine_int.h"
diff --git a/util/coroutine-win32.c b/util/coroutine-win32.c
index 4f922c53af..02e28e825f 100644
--- a/util/coroutine-win32.c
+++ b/util/coroutine-win32.c
@@ -22,6 +22,7 @@
* THE SOFTWARE.
*/
+#include "qemu/osdep.h"
#include "qemu-common.h"
#include "qemu/coroutine_int.h"
diff --git a/util/crc32c.c b/util/crc32c.c
index 8866327801..7e99555c16 100644
--- a/util/crc32c.c
+++ b/util/crc32c.c
@@ -25,6 +25,7 @@
*
*/
+#include "qemu/osdep.h"
#include "qemu-common.h"
#include "qemu/crc32c.h"
diff --git a/util/cutils.c b/util/cutils.c
index cfeb848d19..59e1f70d5f 100644
--- a/util/cutils.c
+++ b/util/cutils.c
@@ -21,11 +21,10 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
+#include "qemu/osdep.h"
#include "qemu-common.h"
#include "qemu/host-utils.h"
#include <math.h>
-#include <limits.h>
-#include <errno.h>
#include "qemu/sockets.h"
#include "qemu/iov.h"
diff --git a/util/envlist.c b/util/envlist.c
index 099a544a41..e86857e70a 100644
--- a/util/envlist.c
+++ b/util/envlist.c
@@ -1,3 +1,4 @@
+#include "qemu/osdep.h"
#include "qemu-common.h"
#include "qemu/queue.h"
#include "qemu/envlist.h"
diff --git a/util/error.c b/util/error.c
index 57303fd05c..471b8b3c1e 100644
--- a/util/error.c
+++ b/util/error.c
@@ -12,8 +12,8 @@
* the COPYING.LIB file in the top-level directory.
*/
+#include "qemu/osdep.h"
#include "qemu-common.h"
-#include "qapi/error.h"
#include "qemu/error-report.h"
struct Error
diff --git a/util/event_notifier-posix.c b/util/event_notifier-posix.c
index d4a0c63e12..2e30e74bd6 100644
--- a/util/event_notifier-posix.c
+++ b/util/event_notifier-posix.c
@@ -10,6 +10,7 @@
* See the COPYING file in the top-level directory.
*/
+#include "qemu/osdep.h"
#include "qemu-common.h"
#include "qemu/event_notifier.h"
#include "sysemu/char.h"
diff --git a/util/event_notifier-win32.c b/util/event_notifier-win32.c
index 6dbb530cfa..14b4f7d2c0 100644
--- a/util/event_notifier-win32.c
+++ b/util/event_notifier-win32.c
@@ -10,6 +10,7 @@
* See the COPYING file in the top-level directory.
*/
+#include "qemu/osdep.h"
#include "qemu-common.h"
#include "qemu/event_notifier.h"
#include "qemu/main-loop.h"
diff --git a/util/fifo8.c b/util/fifo8.c
index 0ea5ad98e3..5c64101b33 100644
--- a/util/fifo8.c
+++ b/util/fifo8.c
@@ -12,6 +12,7 @@
* with this program; if not, see <http://www.gnu.org/licenses/>.
*/
+#include "qemu/osdep.h"
#include "qemu-common.h"
#include "qemu/fifo8.h"
diff --git a/util/getauxval.c b/util/getauxval.c
index 1732ace2b1..0b3bae2dcb 100644
--- a/util/getauxval.c
+++ b/util/getauxval.c
@@ -22,8 +22,8 @@
* THE SOFTWARE.
*/
-#include "qemu-common.h"
#include "qemu/osdep.h"
+#include "qemu-common.h"
#ifdef CONFIG_GETAUXVAL
/* Don't inline this in qemu/osdep.h, because pulling in <sys/auxv.h> for
diff --git a/util/hbitmap.c b/util/hbitmap.c
index 50b888fd60..b22b87d0a6 100644
--- a/util/hbitmap.c
+++ b/util/hbitmap.c
@@ -9,10 +9,8 @@
* later. See the COPYING file in the top-level directory.
*/
-#include <string.h>
-#include <glib.h>
-#include <assert.h>
#include "qemu/osdep.h"
+#include <glib.h>
#include "qemu/hbitmap.h"
#include "qemu/host-utils.h"
#include "trace.h"
diff --git a/util/hexdump.c b/util/hexdump.c
index 969b3406c0..1d9c12967b 100644
--- a/util/hexdump.c
+++ b/util/hexdump.c
@@ -13,6 +13,7 @@
* GNU GPL, version 2 or (at your option) any later version.
*/
+#include "qemu/osdep.h"
#include "qemu-common.h"
void qemu_hexdump(const char *buf, FILE *fp, const char *prefix, size_t size)
diff --git a/util/host-utils.c b/util/host-utils.c
index 102e5bf302..b166e57586 100644
--- a/util/host-utils.c
+++ b/util/host-utils.c
@@ -23,8 +23,7 @@
* THE SOFTWARE.
*/
-#include <stdlib.h>
-#include <stdint.h>
+#include "qemu/osdep.h"
#include "qemu/host-utils.h"
/* Long integer helpers */
diff --git a/util/id.c b/util/id.c
index 7883fbec79..bbbadcc784 100644
--- a/util/id.c
+++ b/util/id.c
@@ -10,6 +10,7 @@
* or later. See the COPYING.LIB file in the top-level directory.
*/
+#include "qemu/osdep.h"
#include "qemu-common.h"
bool id_wellformed(const char *id)
diff --git a/util/iov.c b/util/iov.c
index a0d5934e8e..e802ee15bc 100644
--- a/util/iov.c
+++ b/util/iov.c
@@ -16,6 +16,7 @@
* GNU GPL, version 2 or (at your option) any later version.
*/
+#include "qemu/osdep.h"
#include "qemu/iov.h"
#include "qemu/sockets.h"
diff --git a/util/log.c b/util/log.c
index 46c88c93e2..2709e98f98 100644
--- a/util/log.c
+++ b/util/log.c
@@ -17,6 +17,7 @@
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
+#include "qemu/osdep.h"
#include "qemu-common.h"
#include "qemu/log.h"
#include "trace/control.h"
diff --git a/util/mmap-alloc.c b/util/mmap-alloc.c
index 5cd7f71ac3..0b4cc7f7f1 100644
--- a/util/mmap-alloc.c
+++ b/util/mmap-alloc.c
@@ -9,10 +9,9 @@
* This work is licensed under the terms of the GNU GPL, version 2 or
* later. See the COPYING file in the top-level directory.
*/
+#include "qemu/osdep.h"
#include <qemu/mmap-alloc.h>
-#include <sys/types.h>
#include <sys/mman.h>
-#include <assert.h>
#define HUGETLBFS_MAGIC 0x958458f6
diff --git a/util/module.c b/util/module.c
index 4bd4a94d87..ce058aef6f 100644
--- a/util/module.c
+++ b/util/module.c
@@ -13,7 +13,7 @@
* GNU GPL, version 2 or (at your option) any later version.
*/
-#include <stdlib.h>
+#include "qemu/osdep.h"
#include "qemu-common.h"
#ifdef CONFIG_MODULES
#include <gmodule.h>
diff --git a/util/notify.c b/util/notify.c
index f215dfc214..06de63a839 100644
--- a/util/notify.c
+++ b/util/notify.c
@@ -13,6 +13,7 @@
* GNU GPL, version 2 or (at your option) any later version.
*/
+#include "qemu/osdep.h"
#include "qemu-common.h"
#include "qemu/notify.h"
diff --git a/util/osdep.c b/util/osdep.c
index 534b51147c..8356bdd3d8 100644
--- a/util/osdep.c
+++ b/util/osdep.c
@@ -21,24 +21,15 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdarg.h>
-#include <stdbool.h>
-#include <string.h>
-#include <errno.h>
-#include <unistd.h>
-#include <fcntl.h>
+#include "qemu/osdep.h"
/* Needed early for CONFIG_BSD etc. */
-#include "config-host.h"
#if defined(CONFIG_MADVISE) || defined(CONFIG_POSIX_MADVISE)
#include <sys/mman.h>
#endif
#ifdef CONFIG_SOLARIS
-#include <sys/types.h>
#include <sys/statvfs.h>
/* See MySQL bug #7156 (http://bugs.mysql.com/bug.php?id=7156) for
discussion about Solaris header problems */
diff --git a/util/oslib-posix.c b/util/oslib-posix.c
index d25f6715c7..d844387b79 100644
--- a/util/oslib-posix.c
+++ b/util/oslib-posix.c
@@ -47,13 +47,12 @@ extern int daemon(int, int);
# define QEMU_VMALLOC_ALIGN getpagesize()
#endif
+#include "qemu/osdep.h"
#include <termios.h>
-#include <unistd.h>
#include <termios.h>
#include <glib/gprintf.h>
-#include "config-host.h"
#include "sysemu/sysemu.h"
#include "trace.h"
#include "qemu/sockets.h"
diff --git a/util/oslib-win32.c b/util/oslib-win32.c
index 6a47019dfb..438cfa4f6a 100644
--- a/util/oslib-win32.c
+++ b/util/oslib-win32.c
@@ -29,10 +29,9 @@
* this file are based on code from GNOME glib-2 and use a different license,
* see the license comment there.
*/
+#include "qemu/osdep.h"
#include <windows.h>
#include <glib.h>
-#include <stdlib.h>
-#include "config-host.h"
#include "sysemu/sysemu.h"
#include "qemu/main-loop.h"
#include "trace.h"
diff --git a/util/path.c b/util/path.c
index 4e4877e821..d09e8c5e14 100644
--- a/util/path.c
+++ b/util/path.c
@@ -3,14 +3,9 @@
The assumption is that this area does not change.
*/
-#include <sys/types.h>
+#include "qemu/osdep.h"
#include <sys/param.h>
#include <dirent.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <stdio.h>
#include "qemu-common.h"
struct pathelem
diff --git a/util/qemu-config.c b/util/qemu-config.c
index 687fd34cc6..fb973074d3 100644
--- a/util/qemu-config.c
+++ b/util/qemu-config.c
@@ -1,8 +1,8 @@
+#include "qemu/osdep.h"
#include "qemu-common.h"
#include "qemu/error-report.h"
#include "qemu/option.h"
#include "qemu/config-file.h"
-#include "qapi/error.h"
#include "qmp-commands.h"
static QemuOptsList *vm_config_groups[48];
diff --git a/util/qemu-coroutine-io.c b/util/qemu-coroutine-io.c
index e1eae7331e..0d5041c1c3 100644
--- a/util/qemu-coroutine-io.c
+++ b/util/qemu-coroutine-io.c
@@ -22,6 +22,7 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
+#include "qemu/osdep.h"
#include "qemu-common.h"
#include "qemu/sockets.h"
#include "qemu/coroutine.h"
diff --git a/util/qemu-coroutine-lock.c b/util/qemu-coroutine-lock.c
index 130ee19d17..da37ca7f95 100644
--- a/util/qemu-coroutine-lock.c
+++ b/util/qemu-coroutine-lock.c
@@ -22,6 +22,7 @@
* THE SOFTWARE.
*/
+#include "qemu/osdep.h"
#include "qemu-common.h"
#include "qemu/coroutine.h"
#include "qemu/coroutine_int.h"
diff --git a/util/qemu-coroutine-sleep.c b/util/qemu-coroutine-sleep.c
index b35db56356..6966831d37 100644
--- a/util/qemu-coroutine-sleep.c
+++ b/util/qemu-coroutine-sleep.c
@@ -11,6 +11,7 @@
*
*/
+#include "qemu/osdep.h"
#include "qemu/coroutine.h"
#include "qemu/timer.h"
#include "block/aio.h"
diff --git a/util/qemu-coroutine.c b/util/qemu-coroutine.c
index 8953560223..5816702cc5 100644
--- a/util/qemu-coroutine.c
+++ b/util/qemu-coroutine.c
@@ -12,6 +12,7 @@
*
*/
+#include "qemu/osdep.h"
#include "trace.h"
#include "qemu-common.h"
#include "qemu/thread.h"
diff --git a/util/qemu-error.c b/util/qemu-error.c
index ecf5708478..1ef35664af 100644
--- a/util/qemu-error.c
+++ b/util/qemu-error.c
@@ -10,7 +10,7 @@
* See the COPYING file in the top-level directory.
*/
-#include <stdio.h>
+#include "qemu/osdep.h"
#include "monitor/monitor.h"
#include "qemu/error-report.h"
diff --git a/util/qemu-openpty.c b/util/qemu-openpty.c
index 4c5321116b..2e8b43bdf5 100644
--- a/util/qemu-openpty.c
+++ b/util/qemu-openpty.c
@@ -32,7 +32,7 @@
* linked with -lutil.
*/
-#include "config-host.h"
+#include "qemu/osdep.h"
#include "qemu-common.h"
#if defined(__GLIBC__)
diff --git a/util/qemu-option.c b/util/qemu-option.c
index a2d593ad2b..e7aa43f857 100644
--- a/util/qemu-option.c
+++ b/util/qemu-option.c
@@ -23,13 +23,11 @@
* THE SOFTWARE.
*/
-#include <stdio.h>
-#include <string.h>
+#include "qemu/osdep.h"
#include "qemu-common.h"
#include "qemu/error-report.h"
#include "qapi/qmp/types.h"
-#include "qapi/error.h"
#include "qapi/qmp/qerror.h"
#include "qemu/option_int.h"
diff --git a/util/qemu-progress.c b/util/qemu-progress.c
index 532333e757..f745233763 100644
--- a/util/qemu-progress.c
+++ b/util/qemu-progress.c
@@ -22,9 +22,8 @@
* THE SOFTWARE.
*/
-#include "qemu-common.h"
#include "qemu/osdep.h"
-#include <stdio.h>
+#include "qemu-common.h"
struct progress_state {
float current;
diff --git a/util/qemu-sockets.c b/util/qemu-sockets.c
index f455a1748f..51354dfb6d 100644
--- a/util/qemu-sockets.c
+++ b/util/qemu-sockets.c
@@ -15,12 +15,7 @@
* Contributions after 2012-01-13 are licensed under the terms of the
* GNU GPL, version 2 or (at your option) any later version.
*/
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include <errno.h>
-#include <unistd.h>
+#include "qemu/osdep.h"
#include "monitor/monitor.h"
#include "qemu/sockets.h"
diff --git a/util/qemu-thread-posix.c b/util/qemu-thread-posix.c
index dbd8094fce..74a3023f3e 100644
--- a/util/qemu-thread-posix.c
+++ b/util/qemu-thread-posix.c
@@ -10,16 +10,7 @@
* See the COPYING file in the top-level directory.
*
*/
-#include <stdlib.h>
-#include <stdio.h>
-#include <errno.h>
-#include <time.h>
-#include <signal.h>
-#include <stdint.h>
-#include <string.h>
-#include <limits.h>
-#include <unistd.h>
-#include <sys/time.h>
+#include "qemu/osdep.h"
#ifdef __linux__
#include <sys/syscall.h>
#include <linux/futex.h>
diff --git a/util/qemu-thread-win32.c b/util/qemu-thread-win32.c
index 6cdd553e9a..98a5ddff82 100644
--- a/util/qemu-thread-win32.c
+++ b/util/qemu-thread-win32.c
@@ -10,12 +10,11 @@
* See the COPYING file in the top-level directory.
*
*/
+#include "qemu/osdep.h"
#include "qemu-common.h"
#include "qemu/thread.h"
#include "qemu/notify.h"
#include <process.h>
-#include <assert.h>
-#include <limits.h>
static bool name_threads;
diff --git a/util/qemu-timer-common.c b/util/qemu-timer-common.c
index 95e0847c76..06d084d364 100644
--- a/util/qemu-timer-common.c
+++ b/util/qemu-timer-common.c
@@ -21,6 +21,7 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
+#include "qemu/osdep.h"
#include "qemu/timer.h"
/***********************************************************/
diff --git a/util/rcu.c b/util/rcu.c
index 8ba304dc44..bceb3e4720 100644
--- a/util/rcu.c
+++ b/util/rcu.c
@@ -26,12 +26,8 @@
* IBM's contributions to this file may be relicensed under LGPLv2 or later.
*/
+#include "qemu/osdep.h"
#include "qemu-common.h"
-#include <stdio.h>
-#include <assert.h>
-#include <stdlib.h>
-#include <stdint.h>
-#include <errno.h>
#include "qemu/rcu.h"
#include "qemu/atomic.h"
#include "qemu/thread.h"
diff --git a/util/readline.c b/util/readline.c
index cc1302ac0a..e94c97521b 100644
--- a/util/readline.c
+++ b/util/readline.c
@@ -22,6 +22,7 @@
* THE SOFTWARE.
*/
+#include "qemu/osdep.h"
#include "qemu-common.h"
#include "qemu/readline.h"
diff --git a/util/rfifolock.c b/util/rfifolock.c
index afbf7488df..c22f5feeee 100644
--- a/util/rfifolock.c
+++ b/util/rfifolock.c
@@ -11,7 +11,7 @@
*
*/
-#include <assert.h>
+#include "qemu/osdep.h"
#include "qemu/rfifolock.h"
void rfifolock_init(RFifoLock *r, void (*cb)(void *), void *opaque)
diff --git a/util/throttle.c b/util/throttle.c
index af4bc95ba3..2f9b23d925 100644
--- a/util/throttle.c
+++ b/util/throttle.c
@@ -22,6 +22,7 @@
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
+#include "qemu/osdep.h"
#include "qemu/throttle.h"
#include "qemu/timer.h"
#include "block/aio.h"
diff --git a/util/timed-average.c b/util/timed-average.c
index a2dfb4834d..2eef9cbb19 100644
--- a/util/timed-average.c
+++ b/util/timed-average.c
@@ -22,7 +22,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include <string.h>
+#include "qemu/osdep.h"
#include "qemu/timed-average.h"
diff --git a/util/unicode.c b/util/unicode.c
index d1c8658850..524dca8c7c 100644
--- a/util/unicode.c
+++ b/util/unicode.c
@@ -10,6 +10,7 @@
* later. See the COPYING file in the top-level directory.
*/
+#include "qemu/osdep.h"
#include "qemu-common.h"
/**
diff --git a/util/uri.c b/util/uri.c
index 550b984587..d109d6c01d 100644
--- a/util/uri.c
+++ b/util/uri.c
@@ -51,9 +51,8 @@
*
*/
+#include "qemu/osdep.h"
#include <glib.h>
-#include <string.h>
-#include <stdio.h>
#include "qemu/uri.h"
diff --git a/vl.c b/vl.c
index a7d7c39c34..c581e3978b 100644
--- a/vl.c
+++ b/vl.c
@@ -21,14 +21,8 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
-#include <unistd.h>
-#include <fcntl.h>
-#include <signal.h>
-#include <time.h>
-#include <errno.h>
-#include <sys/time.h>
+#include "qemu/osdep.h"
-#include "config-host.h"
#ifdef CONFIG_SECCOMP
#include "sysemu/seccomp.h"
@@ -113,7 +107,6 @@ int main(int argc, char **argv)
#include "qemu/queue.h"
#include "sysemu/cpus.h"
#include "sysemu/arch_init.h"
-#include "qemu/osdep.h"
#include "ui/qemu-spice.h"
#include "qapi/string-input-visitor.h"
@@ -3311,12 +3304,18 @@ int main(int argc, char **argv, char **envp)
#endif
#ifdef CONFIG_SLIRP
case QEMU_OPTION_tftp:
+ error_report("The -tftp option is deprecated. "
+ "Please use '-netdev user,tftp=...' instead.");
legacy_tftp_prefix = optarg;
break;
case QEMU_OPTION_bootp:
+ error_report("The -bootp option is deprecated. "
+ "Please use '-netdev user,bootfile=...' instead.");
legacy_bootp_filename = optarg;
break;
case QEMU_OPTION_redir:
+ error_report("The -redir option is deprecated. "
+ "Please use '-netdev user,hostfwd=...' instead.");
if (net_slirp_redir(optarg) < 0)
exit(1);
break;