diff options
-rw-r--r-- | .gitignore | 4 | ||||
-rw-r--r-- | MAINTAINERS | 48 | ||||
-rw-r--r-- | Makefile | 9 | ||||
-rw-r--r-- | Makefile.objs | 11 | ||||
-rw-r--r-- | Makefile.target | 5 | ||||
-rw-r--r-- | VERSION | 2 | ||||
-rwxr-xr-x | configure | 19 | ||||
-rw-r--r-- | crypto/Makefile.objs | 4 | ||||
-rw-r--r-- | crypto/cipher-gcrypt.c | 6 | ||||
-rw-r--r-- | crypto/cipher-nettle.c | 42 | ||||
-rw-r--r-- | crypto/cipher.c | 7 | ||||
-rw-r--r-- | crypto/hmac-gcrypt.c | 152 | ||||
-rw-r--r-- | crypto/hmac-glib.c | 166 | ||||
-rw-r--r-- | crypto/hmac-nettle.c | 175 | ||||
-rw-r--r-- | crypto/hmac.c | 72 | ||||
-rw-r--r-- | crypto/hmac.h | 166 | ||||
-rw-r--r-- | disas/cris.c | 4 | ||||
-rw-r--r-- | disas/m68k.c | 8 | ||||
-rw-r--r-- | exec.c | 687 | ||||
-rw-r--r-- | hw/alpha/alpha_sys.h | 2 | ||||
-rw-r--r-- | hw/arm/aspeed.c | 70 | ||||
-rw-r--r-- | hw/arm/aspeed_soc.c | 95 | ||||
-rw-r--r-- | hw/arm/pxa2xx.c | 9 | ||||
-rw-r--r-- | hw/arm/strongarm.h | 2 | ||||
-rw-r--r-- | hw/arm/tosa.c | 7 | ||||
-rw-r--r-- | hw/arm/virt-acpi-build.c | 2 | ||||
-rw-r--r-- | hw/arm/virt.c | 19 | ||||
-rw-r--r-- | hw/arm/z2.c | 7 | ||||
-rw-r--r-- | hw/block/m25p80.c | 1 | ||||
-rw-r--r-- | hw/block/pflash_cfi01.c | 13 | ||||
-rw-r--r-- | hw/block/pflash_cfi02.c | 13 | ||||
-rw-r--r-- | hw/char/cadence_uart.c | 14 | ||||
-rw-r--r-- | hw/i2c/core.c | 6 | ||||
-rw-r--r-- | hw/i386/acpi-build.c | 2 | ||||
-rw-r--r-- | hw/i386/kvm/apic.c | 2 | ||||
-rw-r--r-- | hw/i386/kvm/clock.c | 142 | ||||
-rw-r--r-- | hw/i386/multiboot.c | 20 | ||||
-rw-r--r-- | hw/i386/pc.c | 68 | ||||
-rw-r--r-- | hw/i386/pc_piix.c | 2 | ||||
-rw-r--r-- | hw/i386/pc_q35.c | 39 | ||||
-rw-r--r-- | hw/intc/arm_gicv3.c | 5 | ||||
-rw-r--r-- | hw/intc/arm_gicv3_common.c | 3 | ||||
-rw-r--r-- | hw/intc/arm_gicv3_cpuif.c | 13 | ||||
-rw-r--r-- | hw/intc/ioapic.c | 2 | ||||
-rw-r--r-- | hw/misc/aspeed_scu.c | 4 | ||||
-rw-r--r-- | hw/misc/aspeed_sdmc.c | 3 | ||||
-rw-r--r-- | hw/misc/hyperv_testdev.c | 2 | ||||
-rw-r--r-- | hw/ppc/fdt.c | 2 | ||||
-rw-r--r-- | hw/ppc/pnv.c | 2 | ||||
-rw-r--r-- | hw/ppc/pnv_core.c | 2 | ||||
-rw-r--r-- | hw/ppc/pnv_lpc.c | 2 | ||||
-rw-r--r-- | hw/ppc/pnv_xscom.c | 2 | ||||
-rw-r--r-- | hw/ppc/spapr_cpu_core.c | 6 | ||||
-rw-r--r-- | hw/scsi/scsi-disk.c | 9 | ||||
-rw-r--r-- | hw/scsi/virtio-scsi.c | 27 | ||||
-rw-r--r-- | hw/sh4/shix.c | 2 | ||||
-rw-r--r-- | hw/ssi/aspeed_smc.c | 17 | ||||
-rw-r--r-- | hw/timer/ds1338.c | 6 | ||||
-rw-r--r-- | hw/watchdog/wdt_i6300esb.c | 9 | ||||
-rw-r--r-- | include/block/aio.h | 4 | ||||
-rw-r--r-- | include/exec/cpu-all.h | 23 | ||||
-rw-r--r-- | include/exec/cpu-common.h | 15 | ||||
-rw-r--r-- | include/exec/memory.h | 166 | ||||
-rw-r--r-- | include/hw/arm/arm.h | 2 | ||||
-rw-r--r-- | include/hw/arm/aspeed_soc.h | 4 | ||||
-rw-r--r-- | include/hw/arm/exynos4210.h | 2 | ||||
-rw-r--r-- | include/hw/arm/omap.h | 2 | ||||
-rw-r--r-- | include/hw/arm/pxa.h | 2 | ||||
-rw-r--r-- | include/hw/compat.h | 3 | ||||
-rw-r--r-- | include/hw/i386/pc.h | 12 | ||||
-rw-r--r-- | include/hw/m68k/mcf.h | 2 | ||||
-rw-r--r-- | include/hw/mips/cpudevs.h | 2 | ||||
-rw-r--r-- | include/hw/misc/aspeed_scu.h | 1 | ||||
-rw-r--r-- | include/hw/ppc/fdt.h | 2 | ||||
-rw-r--r-- | include/hw/ppc/ppc.h | 2 | ||||
-rw-r--r-- | include/hw/ppc/spapr_cpu_core.h | 2 | ||||
-rw-r--r-- | include/hw/sh4/sh.h | 2 | ||||
-rw-r--r-- | include/qemu/main-loop.h | 4 | ||||
-rw-r--r-- | include/qemu/timer.h | 2 | ||||
-rw-r--r-- | include/qemu/typedefs.h | 1 | ||||
-rw-r--r-- | include/standard-headers/linux/input.h | 1 | ||||
-rw-r--r-- | include/standard-headers/linux/pci_regs.h | 15 | ||||
-rw-r--r-- | linux-headers/asm-arm/kvm.h | 7 | ||||
-rw-r--r-- | linux-headers/asm-x86/unistd_32.h | 3 | ||||
-rw-r--r-- | linux-headers/asm-x86/unistd_64.h | 3 | ||||
-rw-r--r-- | linux-headers/asm-x86/unistd_x32.h | 3 | ||||
-rw-r--r-- | linux-headers/linux/kvm.h | 7 | ||||
-rw-r--r-- | linux-user/main.c | 7 | ||||
-rw-r--r-- | memory_ldst.inc.c | 709 | ||||
-rw-r--r-- | qapi/crypto.json | 3 | ||||
-rw-r--r-- | qemu-timer.c | 20 | ||||
-rw-r--r-- | rules.mak | 26 | ||||
-rw-r--r-- | scripts/analyze-inclusions | 8 | ||||
-rw-r--r-- | slirp/dhcpv6.c | 2 | ||||
-rw-r--r-- | slirp/ip6_icmp.c | 2 | ||||
-rw-r--r-- | slirp/slirp.c | 2 | ||||
-rw-r--r-- | slirp/slirp.h | 5 | ||||
-rw-r--r-- | slirp/tcp_input.c | 16 | ||||
-rw-r--r-- | slirp/tcp_output.c | 6 | ||||
-rw-r--r-- | slirp/tcp_timer.c | 2 | ||||
-rw-r--r-- | slirp/tcpip.h | 2 | ||||
-rw-r--r-- | slirp/tftp.c | 26 | ||||
-rw-r--r-- | slirp/tftp.h | 8 | ||||
-rw-r--r-- | target-m68k/op_helper.c | 229 | ||||
-rw-r--r-- | target/alpha/Makefile.objs (renamed from target-alpha/Makefile.objs) | 0 | ||||
-rw-r--r-- | target/alpha/STATUS (renamed from target-alpha/STATUS) | 0 | ||||
-rw-r--r-- | target/alpha/cpu-qom.h (renamed from target-alpha/cpu-qom.h) | 0 | ||||
-rw-r--r-- | target/alpha/cpu.c (renamed from target-alpha/cpu.c) | 0 | ||||
-rw-r--r-- | target/alpha/cpu.h (renamed from target-alpha/cpu.h) | 0 | ||||
-rw-r--r-- | target/alpha/fpu_helper.c (renamed from target-alpha/fpu_helper.c) | 0 | ||||
-rw-r--r-- | target/alpha/gdbstub.c (renamed from target-alpha/gdbstub.c) | 0 | ||||
-rw-r--r-- | target/alpha/helper.c (renamed from target-alpha/helper.c) | 0 | ||||
-rw-r--r-- | target/alpha/helper.h (renamed from target-alpha/helper.h) | 0 | ||||
-rw-r--r-- | target/alpha/int_helper.c (renamed from target-alpha/int_helper.c) | 0 | ||||
-rw-r--r-- | target/alpha/machine.c (renamed from target-alpha/machine.c) | 0 | ||||
-rw-r--r-- | target/alpha/mem_helper.c (renamed from target-alpha/mem_helper.c) | 0 | ||||
-rw-r--r-- | target/alpha/sys_helper.c (renamed from target-alpha/sys_helper.c) | 0 | ||||
-rw-r--r-- | target/alpha/translate.c (renamed from target-alpha/translate.c) | 0 | ||||
-rw-r--r-- | target/alpha/vax_helper.c (renamed from target-alpha/vax_helper.c) | 0 | ||||
-rw-r--r-- | target/arm/Makefile.objs (renamed from target-arm/Makefile.objs) | 0 | ||||
-rw-r--r-- | target/arm/arch_dump.c (renamed from target-arm/arch_dump.c) | 0 | ||||
-rw-r--r-- | target/arm/arm-powerctl.c (renamed from target-arm/arm-powerctl.c) | 0 | ||||
-rw-r--r-- | target/arm/arm-powerctl.h (renamed from target-arm/arm-powerctl.h) | 0 | ||||
-rw-r--r-- | target/arm/arm-semi.c (renamed from target-arm/arm-semi.c) | 0 | ||||
-rw-r--r-- | target/arm/arm_ldst.h (renamed from target-arm/arm_ldst.h) | 0 | ||||
-rw-r--r-- | target/arm/cpu-qom.h (renamed from target-arm/cpu-qom.h) | 0 | ||||
-rw-r--r-- | target/arm/cpu.c (renamed from target-arm/cpu.c) | 11 | ||||
-rw-r--r-- | target/arm/cpu.h (renamed from target-arm/cpu.h) | 1 | ||||
-rw-r--r-- | target/arm/cpu64.c (renamed from target-arm/cpu64.c) | 0 | ||||
-rw-r--r-- | target/arm/crypto_helper.c (renamed from target-arm/crypto_helper.c) | 0 | ||||
-rw-r--r-- | target/arm/gdbstub.c (renamed from target-arm/gdbstub.c) | 0 | ||||
-rw-r--r-- | target/arm/gdbstub64.c (renamed from target-arm/gdbstub64.c) | 0 | ||||
-rw-r--r-- | target/arm/helper-a64.c (renamed from target-arm/helper-a64.c) | 0 | ||||
-rw-r--r-- | target/arm/helper-a64.h (renamed from target-arm/helper-a64.h) | 0 | ||||
-rw-r--r-- | target/arm/helper.c (renamed from target-arm/helper.c) | 19 | ||||
-rw-r--r-- | target/arm/helper.h (renamed from target-arm/helper.h) | 0 | ||||
-rw-r--r-- | target/arm/internals.h (renamed from target-arm/internals.h) | 2 | ||||
-rw-r--r-- | target/arm/iwmmxt_helper.c (renamed from target-arm/iwmmxt_helper.c) | 0 | ||||
-rw-r--r-- | target/arm/kvm-consts.h (renamed from target-arm/kvm-consts.h) | 0 | ||||
-rw-r--r-- | target/arm/kvm-stub.c (renamed from target-arm/kvm-stub.c) | 0 | ||||
-rw-r--r-- | target/arm/kvm.c (renamed from target-arm/kvm.c) | 0 | ||||
-rw-r--r-- | target/arm/kvm32.c (renamed from target-arm/kvm32.c) | 0 | ||||
-rw-r--r-- | target/arm/kvm64.c (renamed from target-arm/kvm64.c) | 0 | ||||
-rw-r--r-- | target/arm/kvm_arm.h (renamed from target-arm/kvm_arm.h) | 0 | ||||
-rw-r--r-- | target/arm/machine.c (renamed from target-arm/machine.c) | 0 | ||||
-rw-r--r-- | target/arm/monitor.c (renamed from target-arm/monitor.c) | 0 | ||||
-rw-r--r-- | target/arm/neon_helper.c (renamed from target-arm/neon_helper.c) | 0 | ||||
-rw-r--r-- | target/arm/op_addsub.h (renamed from target-arm/op_addsub.h) | 0 | ||||
-rw-r--r-- | target/arm/op_helper.c (renamed from target-arm/op_helper.c) | 9 | ||||
-rw-r--r-- | target/arm/psci.c (renamed from target-arm/psci.c) | 0 | ||||
-rw-r--r-- | target/arm/trace-events (renamed from target-arm/trace-events) | 2 | ||||
-rw-r--r-- | target/arm/translate-a64.c (renamed from target-arm/translate-a64.c) | 7 | ||||
-rw-r--r-- | target/arm/translate.c (renamed from target-arm/translate.c) | 0 | ||||
-rw-r--r-- | target/arm/translate.h (renamed from target-arm/translate.h) | 0 | ||||
-rw-r--r-- | target/cris/Makefile.objs (renamed from target-cris/Makefile.objs) | 0 | ||||
-rw-r--r-- | target/cris/cpu-qom.h (renamed from target-cris/cpu-qom.h) | 0 | ||||
-rw-r--r-- | target/cris/cpu.c (renamed from target-cris/cpu.c) | 0 | ||||
-rw-r--r-- | target/cris/cpu.h (renamed from target-cris/cpu.h) | 0 | ||||
-rw-r--r-- | target/cris/crisv10-decode.h (renamed from target-cris/crisv10-decode.h) | 0 | ||||
-rw-r--r-- | target/cris/crisv32-decode.h (renamed from target-cris/crisv32-decode.h) | 0 | ||||
-rw-r--r-- | target/cris/gdbstub.c (renamed from target-cris/gdbstub.c) | 0 | ||||
-rw-r--r-- | target/cris/helper.c (renamed from target-cris/helper.c) | 0 | ||||
-rw-r--r-- | target/cris/helper.h (renamed from target-cris/helper.h) | 0 | ||||
-rw-r--r-- | target/cris/machine.c (renamed from target-cris/machine.c) | 0 | ||||
-rw-r--r-- | target/cris/mmu.c (renamed from target-cris/mmu.c) | 0 | ||||
-rw-r--r-- | target/cris/mmu.h (renamed from target-cris/mmu.h) | 0 | ||||
-rw-r--r-- | target/cris/op_helper.c (renamed from target-cris/op_helper.c) | 0 | ||||
-rw-r--r-- | target/cris/opcode-cris.h (renamed from target-cris/opcode-cris.h) | 0 | ||||
-rw-r--r-- | target/cris/translate.c (renamed from target-cris/translate.c) | 0 | ||||
-rw-r--r-- | target/cris/translate_v10.c (renamed from target-cris/translate_v10.c) | 0 | ||||
-rw-r--r-- | target/i386/Makefile.objs (renamed from target-i386/Makefile.objs) | 0 | ||||
-rw-r--r-- | target/i386/TODO (renamed from target-i386/TODO) | 0 | ||||
-rw-r--r-- | target/i386/arch_dump.c (renamed from target-i386/arch_dump.c) | 0 | ||||
-rw-r--r-- | target/i386/arch_memory_mapping.c (renamed from target-i386/arch_memory_mapping.c) | 42 | ||||
-rw-r--r-- | target/i386/bpt_helper.c (renamed from target-i386/bpt_helper.c) | 7 | ||||
-rw-r--r-- | target/i386/cc_helper.c (renamed from target-i386/cc_helper.c) | 0 | ||||
-rw-r--r-- | target/i386/cc_helper_template.h (renamed from target-i386/cc_helper_template.h) | 0 | ||||
-rw-r--r-- | target/i386/cpu-qom.h (renamed from target-i386/cpu-qom.h) | 0 | ||||
-rw-r--r-- | target/i386/cpu.c (renamed from target-i386/cpu.c) | 18 | ||||
-rw-r--r-- | target/i386/cpu.h (renamed from target-i386/cpu.h) | 3 | ||||
-rw-r--r-- | target/i386/excp_helper.c (renamed from target-i386/excp_helper.c) | 0 | ||||
-rw-r--r-- | target/i386/fpu_helper.c (renamed from target-i386/fpu_helper.c) | 0 | ||||
-rw-r--r-- | target/i386/gdbstub.c (renamed from target-i386/gdbstub.c) | 52 | ||||
-rw-r--r-- | target/i386/helper.c (renamed from target-i386/helper.c) | 54 | ||||
-rw-r--r-- | target/i386/helper.h (renamed from target-i386/helper.h) | 1 | ||||
-rw-r--r-- | target/i386/hyperv.c (renamed from target-i386/hyperv.c) | 0 | ||||
-rw-r--r-- | target/i386/hyperv.h (renamed from target-i386/hyperv.h) | 0 | ||||
-rw-r--r-- | target/i386/int_helper.c (renamed from target-i386/int_helper.c) | 0 | ||||
-rw-r--r-- | target/i386/kvm-stub.c (renamed from target-i386/kvm-stub.c) | 0 | ||||
-rw-r--r-- | target/i386/kvm.c (renamed from target-i386/kvm.c) | 7 | ||||
-rw-r--r-- | target/i386/kvm_i386.h (renamed from target-i386/kvm_i386.h) | 1 | ||||
-rw-r--r-- | target/i386/machine.c (renamed from target-i386/machine.c) | 0 | ||||
-rw-r--r-- | target/i386/mem_helper.c (renamed from target-i386/mem_helper.c) | 0 | ||||
-rw-r--r-- | target/i386/misc_helper.c (renamed from target-i386/misc_helper.c) | 0 | ||||
-rw-r--r-- | target/i386/monitor.c (renamed from target-i386/monitor.c) | 234 | ||||
-rw-r--r-- | target/i386/mpx_helper.c (renamed from target-i386/mpx_helper.c) | 0 | ||||
-rw-r--r-- | target/i386/ops_sse.h (renamed from target-i386/ops_sse.h) | 0 | ||||
-rw-r--r-- | target/i386/ops_sse_header.h (renamed from target-i386/ops_sse_header.h) | 0 | ||||
-rw-r--r-- | target/i386/seg_helper.c (renamed from target-i386/seg_helper.c) | 0 | ||||
-rw-r--r-- | target/i386/shift_helper_template.h (renamed from target-i386/shift_helper_template.h) | 0 | ||||
-rw-r--r-- | target/i386/smm_helper.c (renamed from target-i386/smm_helper.c) | 0 | ||||
-rw-r--r-- | target/i386/svm.h (renamed from target-i386/svm.h) | 0 | ||||
-rw-r--r-- | target/i386/svm_helper.c (renamed from target-i386/svm_helper.c) | 0 | ||||
-rw-r--r-- | target/i386/trace-events (renamed from target-i386/trace-events) | 2 | ||||
-rw-r--r-- | target/i386/translate.c (renamed from target-i386/translate.c) | 29 | ||||
-rw-r--r-- | target/lm32/Makefile.objs (renamed from target-lm32/Makefile.objs) | 0 | ||||
-rw-r--r-- | target/lm32/README (renamed from target-lm32/README) | 0 | ||||
-rw-r--r-- | target/lm32/TODO (renamed from target-lm32/TODO) | 0 | ||||
-rw-r--r-- | target/lm32/cpu-qom.h (renamed from target-lm32/cpu-qom.h) | 0 | ||||
-rw-r--r-- | target/lm32/cpu.c (renamed from target-lm32/cpu.c) | 0 | ||||
-rw-r--r-- | target/lm32/cpu.h (renamed from target-lm32/cpu.h) | 0 | ||||
-rw-r--r-- | target/lm32/gdbstub.c (renamed from target-lm32/gdbstub.c) | 0 | ||||
-rw-r--r-- | target/lm32/helper.c (renamed from target-lm32/helper.c) | 0 | ||||
-rw-r--r-- | target/lm32/helper.h (renamed from target-lm32/helper.h) | 0 | ||||
-rw-r--r-- | target/lm32/lm32-semi.c (renamed from target-lm32/lm32-semi.c) | 2 | ||||
-rw-r--r-- | target/lm32/machine.c (renamed from target-lm32/machine.c) | 0 | ||||
-rw-r--r-- | target/lm32/op_helper.c (renamed from target-lm32/op_helper.c) | 0 | ||||
-rw-r--r-- | target/lm32/translate.c (renamed from target-lm32/translate.c) | 0 | ||||
-rw-r--r-- | target/m68k/Makefile.objs (renamed from target-m68k/Makefile.objs) | 0 | ||||
-rw-r--r-- | target/m68k/cpu-qom.h (renamed from target-m68k/cpu-qom.h) | 0 | ||||
-rw-r--r-- | target/m68k/cpu.c (renamed from target-m68k/cpu.c) | 0 | ||||
-rw-r--r-- | target/m68k/cpu.h (renamed from target-m68k/cpu.h) | 4 | ||||
-rw-r--r-- | target/m68k/gdbstub.c (renamed from target-m68k/gdbstub.c) | 0 | ||||
-rw-r--r-- | target/m68k/helper.c (renamed from target-m68k/helper.c) | 52 | ||||
-rw-r--r-- | target/m68k/helper.h (renamed from target-m68k/helper.h) | 13 | ||||
-rw-r--r-- | target/m68k/m68k-semi.c (renamed from target-m68k/m68k-semi.c) | 0 | ||||
-rw-r--r-- | target/m68k/op_helper.c | 471 | ||||
-rw-r--r-- | target/m68k/qregs.def (renamed from target-m68k/qregs.def) | 2 | ||||
-rw-r--r-- | target/m68k/translate.c (renamed from target-m68k/translate.c) | 1518 | ||||
-rw-r--r-- | target/microblaze/Makefile.objs (renamed from target-microblaze/Makefile.objs) | 0 | ||||
-rw-r--r-- | target/microblaze/cpu-qom.h (renamed from target-microblaze/cpu-qom.h) | 0 | ||||
-rw-r--r-- | target/microblaze/cpu.c (renamed from target-microblaze/cpu.c) | 0 | ||||
-rw-r--r-- | target/microblaze/cpu.h (renamed from target-microblaze/cpu.h) | 0 | ||||
-rw-r--r-- | target/microblaze/gdbstub.c (renamed from target-microblaze/gdbstub.c) | 0 | ||||
-rw-r--r-- | target/microblaze/helper.c (renamed from target-microblaze/helper.c) | 0 | ||||
-rw-r--r-- | target/microblaze/helper.h (renamed from target-microblaze/helper.h) | 0 | ||||
-rw-r--r-- | target/microblaze/microblaze-decode.h (renamed from target-microblaze/microblaze-decode.h) | 0 | ||||
-rw-r--r-- | target/microblaze/mmu.c (renamed from target-microblaze/mmu.c) | 0 | ||||
-rw-r--r-- | target/microblaze/mmu.h (renamed from target-microblaze/mmu.h) | 0 | ||||
-rw-r--r-- | target/microblaze/op_helper.c (renamed from target-microblaze/op_helper.c) | 0 | ||||
-rw-r--r-- | target/microblaze/translate.c (renamed from target-microblaze/translate.c) | 0 | ||||
-rw-r--r-- | target/mips/Makefile.objs (renamed from target-mips/Makefile.objs) | 0 | ||||
-rw-r--r-- | target/mips/TODO (renamed from target-mips/TODO) | 0 | ||||
-rw-r--r-- | target/mips/cpu-qom.h (renamed from target-mips/cpu-qom.h) | 0 | ||||
-rw-r--r-- | target/mips/cpu.c (renamed from target-mips/cpu.c) | 0 | ||||
-rw-r--r-- | target/mips/cpu.h (renamed from target-mips/cpu.h) | 0 | ||||
-rw-r--r-- | target/mips/dsp_helper.c (renamed from target-mips/dsp_helper.c) | 0 | ||||
-rw-r--r-- | target/mips/gdbstub.c (renamed from target-mips/gdbstub.c) | 0 | ||||
-rw-r--r-- | target/mips/helper.c (renamed from target-mips/helper.c) | 0 | ||||
-rw-r--r-- | target/mips/helper.h (renamed from target-mips/helper.h) | 0 | ||||
-rw-r--r-- | target/mips/kvm.c (renamed from target-mips/kvm.c) | 0 | ||||
-rw-r--r-- | target/mips/kvm_mips.h (renamed from target-mips/kvm_mips.h) | 0 | ||||
-rw-r--r-- | target/mips/lmi_helper.c (renamed from target-mips/lmi_helper.c) | 0 | ||||
-rw-r--r-- | target/mips/machine.c (renamed from target-mips/machine.c) | 0 | ||||
-rw-r--r-- | target/mips/mips-defs.h (renamed from target-mips/mips-defs.h) | 0 | ||||
-rw-r--r-- | target/mips/mips-semi.c (renamed from target-mips/mips-semi.c) | 0 | ||||
-rw-r--r-- | target/mips/msa_helper.c (renamed from target-mips/msa_helper.c) | 0 | ||||
-rw-r--r-- | target/mips/op_helper.c (renamed from target-mips/op_helper.c) | 0 | ||||
-rw-r--r-- | target/mips/translate.c (renamed from target-mips/translate.c) | 0 | ||||
-rw-r--r-- | target/mips/translate_init.c (renamed from target-mips/translate_init.c) | 0 | ||||
-rw-r--r-- | target/moxie/Makefile.objs (renamed from target-moxie/Makefile.objs) | 0 | ||||
-rw-r--r-- | target/moxie/cpu.c (renamed from target-moxie/cpu.c) | 0 | ||||
-rw-r--r-- | target/moxie/cpu.h (renamed from target-moxie/cpu.h) | 0 | ||||
-rw-r--r-- | target/moxie/helper.c (renamed from target-moxie/helper.c) | 0 | ||||
-rw-r--r-- | target/moxie/helper.h (renamed from target-moxie/helper.h) | 0 | ||||
-rw-r--r-- | target/moxie/machine.c (renamed from target-moxie/machine.c) | 0 | ||||
-rw-r--r-- | target/moxie/machine.h (renamed from target-moxie/machine.h) | 0 | ||||
-rw-r--r-- | target/moxie/mmu.c (renamed from target-moxie/mmu.c) | 0 | ||||
-rw-r--r-- | target/moxie/mmu.h (renamed from target-moxie/mmu.h) | 0 | ||||
-rw-r--r-- | target/moxie/translate.c (renamed from target-moxie/translate.c) | 0 | ||||
-rw-r--r-- | target/openrisc/Makefile.objs (renamed from target-openrisc/Makefile.objs) | 0 | ||||
-rw-r--r-- | target/openrisc/cpu.c (renamed from target-openrisc/cpu.c) | 0 | ||||
-rw-r--r-- | target/openrisc/cpu.h (renamed from target-openrisc/cpu.h) | 0 | ||||
-rw-r--r-- | target/openrisc/exception.c (renamed from target-openrisc/exception.c) | 0 | ||||
-rw-r--r-- | target/openrisc/exception.h (renamed from target-openrisc/exception.h) | 0 | ||||
-rw-r--r-- | target/openrisc/exception_helper.c (renamed from target-openrisc/exception_helper.c) | 0 | ||||
-rw-r--r-- | target/openrisc/fpu_helper.c (renamed from target-openrisc/fpu_helper.c) | 0 | ||||
-rw-r--r-- | target/openrisc/gdbstub.c (renamed from target-openrisc/gdbstub.c) | 0 | ||||
-rw-r--r-- | target/openrisc/helper.h (renamed from target-openrisc/helper.h) | 0 | ||||
-rw-r--r-- | target/openrisc/int_helper.c (renamed from target-openrisc/int_helper.c) | 0 | ||||
-rw-r--r-- | target/openrisc/interrupt.c (renamed from target-openrisc/interrupt.c) | 0 | ||||
-rw-r--r-- | target/openrisc/interrupt_helper.c (renamed from target-openrisc/interrupt_helper.c) | 0 | ||||
-rw-r--r-- | target/openrisc/machine.c (renamed from target-openrisc/machine.c) | 0 | ||||
-rw-r--r-- | target/openrisc/mmu.c (renamed from target-openrisc/mmu.c) | 0 | ||||
-rw-r--r-- | target/openrisc/mmu_helper.c (renamed from target-openrisc/mmu_helper.c) | 0 | ||||
-rw-r--r-- | target/openrisc/sys_helper.c (renamed from target-openrisc/sys_helper.c) | 0 | ||||
-rw-r--r-- | target/openrisc/translate.c (renamed from target-openrisc/translate.c) | 0 | ||||
-rw-r--r-- | target/ppc/Makefile.objs (renamed from target-ppc/Makefile.objs) | 0 | ||||
-rw-r--r-- | target/ppc/STATUS (renamed from target-ppc/STATUS) | 0 | ||||
-rw-r--r-- | target/ppc/arch_dump.c (renamed from target-ppc/arch_dump.c) | 0 | ||||
-rw-r--r-- | target/ppc/cpu-models.c (renamed from target-ppc/cpu-models.c) | 0 | ||||
-rw-r--r-- | target/ppc/cpu-models.h (renamed from target-ppc/cpu-models.h) | 0 | ||||
-rw-r--r-- | target/ppc/cpu-qom.h (renamed from target-ppc/cpu-qom.h) | 0 | ||||
-rw-r--r-- | target/ppc/cpu.h (renamed from target-ppc/cpu.h) | 0 | ||||
-rw-r--r-- | target/ppc/dfp_helper.c (renamed from target-ppc/dfp_helper.c) | 0 | ||||
-rw-r--r-- | target/ppc/excp_helper.c (renamed from target-ppc/excp_helper.c) | 0 | ||||
-rw-r--r-- | target/ppc/fpu_helper.c (renamed from target-ppc/fpu_helper.c) | 0 | ||||
-rw-r--r-- | target/ppc/gdbstub.c (renamed from target-ppc/gdbstub.c) | 0 | ||||
-rw-r--r-- | target/ppc/helper.h (renamed from target-ppc/helper.h) | 0 | ||||
-rw-r--r-- | target/ppc/helper_regs.h (renamed from target-ppc/helper_regs.h) | 0 | ||||
-rw-r--r-- | target/ppc/int_helper.c (renamed from target-ppc/int_helper.c) | 0 | ||||
-rw-r--r-- | target/ppc/internal.h (renamed from target-ppc/internal.h) | 0 | ||||
-rw-r--r-- | target/ppc/kvm-stub.c (renamed from target-ppc/kvm-stub.c) | 0 | ||||
-rw-r--r-- | target/ppc/kvm.c (renamed from target-ppc/kvm.c) | 0 | ||||
-rw-r--r-- | target/ppc/kvm_ppc.h (renamed from target-ppc/kvm_ppc.h) | 0 | ||||
-rw-r--r-- | target/ppc/machine.c (renamed from target-ppc/machine.c) | 0 | ||||
-rw-r--r-- | target/ppc/mem_helper.c (renamed from target-ppc/mem_helper.c) | 0 | ||||
-rw-r--r-- | target/ppc/mfrom_table.c (renamed from target-ppc/mfrom_table.c) | 0 | ||||
-rw-r--r-- | target/ppc/mfrom_table_gen.c (renamed from target-ppc/mfrom_table_gen.c) | 0 | ||||
-rw-r--r-- | target/ppc/misc_helper.c (renamed from target-ppc/misc_helper.c) | 0 | ||||
-rw-r--r-- | target/ppc/mmu-hash32.c (renamed from target-ppc/mmu-hash32.c) | 0 | ||||
-rw-r--r-- | target/ppc/mmu-hash32.h (renamed from target-ppc/mmu-hash32.h) | 0 | ||||
-rw-r--r-- | target/ppc/mmu-hash64.c (renamed from target-ppc/mmu-hash64.c) | 0 | ||||
-rw-r--r-- | target/ppc/mmu-hash64.h (renamed from target-ppc/mmu-hash64.h) | 0 | ||||
-rw-r--r-- | target/ppc/mmu_helper.c (renamed from target-ppc/mmu_helper.c) | 0 | ||||
-rw-r--r-- | target/ppc/monitor.c (renamed from target-ppc/monitor.c) | 0 | ||||
-rw-r--r-- | target/ppc/timebase_helper.c (renamed from target-ppc/timebase_helper.c) | 0 | ||||
-rw-r--r-- | target/ppc/trace-events (renamed from target-ppc/trace-events) | 2 | ||||
-rw-r--r-- | target/ppc/translate.c (renamed from target-ppc/translate.c) | 0 | ||||
-rw-r--r-- | target/ppc/translate/dfp-impl.inc.c (renamed from target-ppc/translate/dfp-impl.inc.c) | 0 | ||||
-rw-r--r-- | target/ppc/translate/dfp-ops.inc.c (renamed from target-ppc/translate/dfp-ops.inc.c) | 0 | ||||
-rw-r--r-- | target/ppc/translate/fp-impl.inc.c (renamed from target-ppc/translate/fp-impl.inc.c) | 0 | ||||
-rw-r--r-- | target/ppc/translate/fp-ops.inc.c (renamed from target-ppc/translate/fp-ops.inc.c) | 0 | ||||
-rw-r--r-- | target/ppc/translate/spe-impl.inc.c (renamed from target-ppc/translate/spe-impl.inc.c) | 0 | ||||
-rw-r--r-- | target/ppc/translate/spe-ops.inc.c (renamed from target-ppc/translate/spe-ops.inc.c) | 0 | ||||
-rw-r--r-- | target/ppc/translate/vmx-impl.inc.c (renamed from target-ppc/translate/vmx-impl.inc.c) | 0 | ||||
-rw-r--r-- | target/ppc/translate/vmx-ops.inc.c (renamed from target-ppc/translate/vmx-ops.inc.c) | 0 | ||||
-rw-r--r-- | target/ppc/translate/vsx-impl.inc.c (renamed from target-ppc/translate/vsx-impl.inc.c) | 0 | ||||
-rw-r--r-- | target/ppc/translate/vsx-ops.inc.c (renamed from target-ppc/translate/vsx-ops.inc.c) | 0 | ||||
-rw-r--r-- | target/ppc/translate_init.c (renamed from target-ppc/translate_init.c) | 0 | ||||
-rw-r--r-- | target/ppc/user_only_helper.c (renamed from target-ppc/user_only_helper.c) | 0 | ||||
-rw-r--r-- | target/s390x/Makefile.objs (renamed from target-s390x/Makefile.objs) | 2 | ||||
-rw-r--r-- | target/s390x/arch_dump.c (renamed from target-s390x/arch_dump.c) | 0 | ||||
-rw-r--r-- | target/s390x/cc_helper.c (renamed from target-s390x/cc_helper.c) | 0 | ||||
-rw-r--r-- | target/s390x/cpu-qom.h (renamed from target-s390x/cpu-qom.h) | 0 | ||||
-rw-r--r-- | target/s390x/cpu.c (renamed from target-s390x/cpu.c) | 0 | ||||
-rw-r--r-- | target/s390x/cpu.h (renamed from target-s390x/cpu.h) | 0 | ||||
-rw-r--r-- | target/s390x/cpu_features.c (renamed from target-s390x/cpu_features.c) | 0 | ||||
-rw-r--r-- | target/s390x/cpu_features.h (renamed from target-s390x/cpu_features.h) | 0 | ||||
-rw-r--r-- | target/s390x/cpu_features_def.h (renamed from target-s390x/cpu_features_def.h) | 0 | ||||
-rw-r--r-- | target/s390x/cpu_models.c (renamed from target-s390x/cpu_models.c) | 0 | ||||
-rw-r--r-- | target/s390x/cpu_models.h (renamed from target-s390x/cpu_models.h) | 0 | ||||
-rw-r--r-- | target/s390x/fpu_helper.c (renamed from target-s390x/fpu_helper.c) | 0 | ||||
-rw-r--r-- | target/s390x/gdbstub.c (renamed from target-s390x/gdbstub.c) | 0 | ||||
-rw-r--r-- | target/s390x/gen-features.c (renamed from target-s390x/gen-features.c) | 0 | ||||
-rw-r--r-- | target/s390x/helper.c (renamed from target-s390x/helper.c) | 0 | ||||
-rw-r--r-- | target/s390x/helper.h (renamed from target-s390x/helper.h) | 0 | ||||
-rw-r--r-- | target/s390x/insn-data.def (renamed from target-s390x/insn-data.def) | 0 | ||||
-rw-r--r-- | target/s390x/insn-format.def (renamed from target-s390x/insn-format.def) | 0 | ||||
-rw-r--r-- | target/s390x/int_helper.c (renamed from target-s390x/int_helper.c) | 0 | ||||
-rw-r--r-- | target/s390x/interrupt.c (renamed from target-s390x/interrupt.c) | 0 | ||||
-rw-r--r-- | target/s390x/ioinst.c (renamed from target-s390x/ioinst.c) | 0 | ||||
-rw-r--r-- | target/s390x/kvm.c (renamed from target-s390x/kvm.c) | 0 | ||||
-rw-r--r-- | target/s390x/machine.c (renamed from target-s390x/machine.c) | 0 | ||||
-rw-r--r-- | target/s390x/mem_helper.c (renamed from target-s390x/mem_helper.c) | 0 | ||||
-rw-r--r-- | target/s390x/misc_helper.c (renamed from target-s390x/misc_helper.c) | 0 | ||||
-rw-r--r-- | target/s390x/mmu_helper.c (renamed from target-s390x/mmu_helper.c) | 0 | ||||
-rw-r--r-- | target/s390x/trace-events (renamed from target-s390x/trace-events) | 8 | ||||
-rw-r--r-- | target/s390x/translate.c (renamed from target-s390x/translate.c) | 0 | ||||
-rw-r--r-- | target/sh4/Makefile.objs (renamed from target-sh4/Makefile.objs) | 0 | ||||
-rw-r--r-- | target/sh4/README.sh4 (renamed from target-sh4/README.sh4) | 2 | ||||
-rw-r--r-- | target/sh4/cpu-qom.h (renamed from target-sh4/cpu-qom.h) | 0 | ||||
-rw-r--r-- | target/sh4/cpu.c (renamed from target-sh4/cpu.c) | 0 | ||||
-rw-r--r-- | target/sh4/cpu.h (renamed from target-sh4/cpu.h) | 0 | ||||
-rw-r--r-- | target/sh4/gdbstub.c (renamed from target-sh4/gdbstub.c) | 0 | ||||
-rw-r--r-- | target/sh4/helper.c (renamed from target-sh4/helper.c) | 0 | ||||
-rw-r--r-- | target/sh4/helper.h (renamed from target-sh4/helper.h) | 0 | ||||
-rw-r--r-- | target/sh4/monitor.c (renamed from target-sh4/monitor.c) | 0 | ||||
-rw-r--r-- | target/sh4/op_helper.c (renamed from target-sh4/op_helper.c) | 0 | ||||
-rw-r--r-- | target/sh4/translate.c (renamed from target-sh4/translate.c) | 0 | ||||
-rw-r--r-- | target/sparc/Makefile.objs (renamed from target-sparc/Makefile.objs) | 0 | ||||
-rw-r--r-- | target/sparc/TODO (renamed from target-sparc/TODO) | 0 | ||||
-rw-r--r-- | target/sparc/asi.h (renamed from target-sparc/asi.h) | 0 | ||||
-rw-r--r-- | target/sparc/cc_helper.c (renamed from target-sparc/cc_helper.c) | 0 | ||||
-rw-r--r-- | target/sparc/cpu-qom.h (renamed from target-sparc/cpu-qom.h) | 0 | ||||
-rw-r--r-- | target/sparc/cpu.c (renamed from target-sparc/cpu.c) | 0 | ||||
-rw-r--r-- | target/sparc/cpu.h (renamed from target-sparc/cpu.h) | 0 | ||||
-rw-r--r-- | target/sparc/fop_helper.c (renamed from target-sparc/fop_helper.c) | 0 | ||||
-rw-r--r-- | target/sparc/gdbstub.c (renamed from target-sparc/gdbstub.c) | 0 | ||||
-rw-r--r-- | target/sparc/helper.c (renamed from target-sparc/helper.c) | 0 | ||||
-rw-r--r-- | target/sparc/helper.h (renamed from target-sparc/helper.h) | 0 | ||||
-rw-r--r-- | target/sparc/int32_helper.c (renamed from target-sparc/int32_helper.c) | 0 | ||||
-rw-r--r-- | target/sparc/int64_helper.c (renamed from target-sparc/int64_helper.c) | 0 | ||||
-rw-r--r-- | target/sparc/ldst_helper.c (renamed from target-sparc/ldst_helper.c) | 0 | ||||
-rw-r--r-- | target/sparc/machine.c (renamed from target-sparc/machine.c) | 0 | ||||
-rw-r--r-- | target/sparc/mmu_helper.c (renamed from target-sparc/mmu_helper.c) | 0 | ||||
-rw-r--r-- | target/sparc/monitor.c (renamed from target-sparc/monitor.c) | 0 | ||||
-rw-r--r-- | target/sparc/trace-events (renamed from target-sparc/trace-events) | 8 | ||||
-rw-r--r-- | target/sparc/translate.c (renamed from target-sparc/translate.c) | 0 | ||||
-rw-r--r-- | target/sparc/vis_helper.c (renamed from target-sparc/vis_helper.c) | 0 | ||||
-rw-r--r-- | target/sparc/win_helper.c (renamed from target-sparc/win_helper.c) | 0 | ||||
-rw-r--r-- | target/tilegx/Makefile.objs (renamed from target-tilegx/Makefile.objs) | 0 | ||||
-rw-r--r-- | target/tilegx/cpu.c (renamed from target-tilegx/cpu.c) | 0 | ||||
-rw-r--r-- | target/tilegx/cpu.h (renamed from target-tilegx/cpu.h) | 0 | ||||
-rw-r--r-- | target/tilegx/helper.c (renamed from target-tilegx/helper.c) | 0 | ||||
-rw-r--r-- | target/tilegx/helper.h (renamed from target-tilegx/helper.h) | 0 | ||||
-rw-r--r-- | target/tilegx/opcode_tilegx.h (renamed from target-tilegx/opcode_tilegx.h) | 0 | ||||
-rw-r--r-- | target/tilegx/simd_helper.c (renamed from target-tilegx/simd_helper.c) | 0 | ||||
-rw-r--r-- | target/tilegx/spr_def_64.h (renamed from target-tilegx/spr_def_64.h) | 0 | ||||
-rw-r--r-- | target/tilegx/translate.c (renamed from target-tilegx/translate.c) | 0 | ||||
-rw-r--r-- | target/tricore/Makefile.objs (renamed from target-tricore/Makefile.objs) | 0 | ||||
-rw-r--r-- | target/tricore/cpu-qom.h (renamed from target-tricore/cpu-qom.h) | 0 | ||||
-rw-r--r-- | target/tricore/cpu.c (renamed from target-tricore/cpu.c) | 0 | ||||
-rw-r--r-- | target/tricore/cpu.h (renamed from target-tricore/cpu.h) | 0 | ||||
-rw-r--r-- | target/tricore/csfr.def (renamed from target-tricore/csfr.def) | 0 | ||||
-rw-r--r-- | target/tricore/fpu_helper.c (renamed from target-tricore/fpu_helper.c) | 0 | ||||
-rw-r--r-- | target/tricore/helper.c (renamed from target-tricore/helper.c) | 0 | ||||
-rw-r--r-- | target/tricore/helper.h (renamed from target-tricore/helper.h) | 0 | ||||
-rw-r--r-- | target/tricore/op_helper.c (renamed from target-tricore/op_helper.c) | 0 | ||||
-rw-r--r-- | target/tricore/translate.c (renamed from target-tricore/translate.c) | 0 | ||||
-rw-r--r-- | target/tricore/tricore-defs.h (renamed from target-tricore/tricore-defs.h) | 0 | ||||
-rw-r--r-- | target/tricore/tricore-opcodes.h (renamed from target-tricore/tricore-opcodes.h) | 0 | ||||
-rw-r--r-- | target/unicore32/Makefile.objs (renamed from target-unicore32/Makefile.objs) | 0 | ||||
-rw-r--r-- | target/unicore32/cpu-qom.h (renamed from target-unicore32/cpu-qom.h) | 0 | ||||
-rw-r--r-- | target/unicore32/cpu.c (renamed from target-unicore32/cpu.c) | 0 | ||||
-rw-r--r-- | target/unicore32/cpu.h (renamed from target-unicore32/cpu.h) | 0 | ||||
-rw-r--r-- | target/unicore32/helper.c (renamed from target-unicore32/helper.c) | 0 | ||||
-rw-r--r-- | target/unicore32/helper.h (renamed from target-unicore32/helper.h) | 0 | ||||
-rw-r--r-- | target/unicore32/op_helper.c (renamed from target-unicore32/op_helper.c) | 0 | ||||
-rw-r--r-- | target/unicore32/softmmu.c (renamed from target-unicore32/softmmu.c) | 0 | ||||
-rw-r--r-- | target/unicore32/translate.c (renamed from target-unicore32/translate.c) | 0 | ||||
-rw-r--r-- | target/unicore32/ucf64_helper.c (renamed from target-unicore32/ucf64_helper.c) | 0 | ||||
-rw-r--r-- | target/xtensa/Makefile.objs (renamed from target-xtensa/Makefile.objs) | 0 | ||||
-rw-r--r-- | target/xtensa/core-dc232b.c (renamed from target-xtensa/core-dc232b.c) | 0 | ||||
-rw-r--r-- | target/xtensa/core-dc232b/core-isa.h (renamed from target-xtensa/core-dc232b/core-isa.h) | 0 | ||||
-rw-r--r-- | target/xtensa/core-dc232b/gdb-config.c (renamed from target-xtensa/core-dc232b/gdb-config.c) | 0 | ||||
-rw-r--r-- | target/xtensa/core-dc233c.c (renamed from target-xtensa/core-dc233c.c) | 0 | ||||
-rw-r--r-- | target/xtensa/core-dc233c/core-isa.h (renamed from target-xtensa/core-dc233c/core-isa.h) | 0 | ||||
-rw-r--r-- | target/xtensa/core-dc233c/gdb-config.c (renamed from target-xtensa/core-dc233c/gdb-config.c) | 0 | ||||
-rw-r--r-- | target/xtensa/core-fsf.c (renamed from target-xtensa/core-fsf.c) | 0 | ||||
-rw-r--r-- | target/xtensa/core-fsf/core-isa.h (renamed from target-xtensa/core-fsf/core-isa.h) | 0 | ||||
-rw-r--r-- | target/xtensa/cpu-qom.h (renamed from target-xtensa/cpu-qom.h) | 0 | ||||
-rw-r--r-- | target/xtensa/cpu.c (renamed from target-xtensa/cpu.c) | 0 | ||||
-rw-r--r-- | target/xtensa/cpu.h (renamed from target-xtensa/cpu.h) | 0 | ||||
-rw-r--r-- | target/xtensa/gdbstub.c (renamed from target-xtensa/gdbstub.c) | 0 | ||||
-rw-r--r-- | target/xtensa/helper.c (renamed from target-xtensa/helper.c) | 0 | ||||
-rw-r--r-- | target/xtensa/helper.h (renamed from target-xtensa/helper.h) | 0 | ||||
-rwxr-xr-x | target/xtensa/import_core.sh (renamed from target-xtensa/import_core.sh) | 0 | ||||
-rw-r--r-- | target/xtensa/monitor.c (renamed from target-xtensa/monitor.c) | 0 | ||||
-rw-r--r-- | target/xtensa/op_helper.c (renamed from target-xtensa/op_helper.c) | 0 | ||||
-rw-r--r-- | target/xtensa/overlay_tool.h (renamed from target-xtensa/overlay_tool.h) | 0 | ||||
-rw-r--r-- | target/xtensa/translate.c (renamed from target-xtensa/translate.c) | 0 | ||||
-rw-r--r-- | target/xtensa/xtensa-semi.c (renamed from target-xtensa/xtensa-semi.c) | 0 | ||||
-rw-r--r-- | tcg/s390/tcg-target.inc.c | 75 | ||||
-rw-r--r-- | tests/Makefile.include | 2 | ||||
-rw-r--r-- | tests/tcg/xtensa/Makefile | 2 | ||||
-rw-r--r-- | tests/test-crypto-cipher.c | 119 | ||||
-rw-r--r-- | tests/test-crypto-hmac.c | 266 |
448 files changed, 5141 insertions, 1515 deletions
diff --git a/.gitignore b/.gitignore index 3d7848cb7e..e43c3044dc 100644 --- a/.gitignore +++ b/.gitignore @@ -82,10 +82,6 @@ *.d !/scripts/qemu-guest-agent/fsfreeze-hook.d *.o -*.lo -*.la -*.pc -.libs .sdk *.gcda *.gcno diff --git a/MAINTAINERS b/MAINTAINERS index 4a605791fc..585cd5abd7 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -106,7 +106,7 @@ F: include/fpu/ Alpha M: Richard Henderson <rth@twiddle.net> S: Maintained -F: target-alpha/ +F: target/alpha/ F: hw/alpha/ F: tests/tcg/alpha/ F: disas/alpha.c @@ -115,7 +115,7 @@ ARM M: Peter Maydell <peter.maydell@linaro.org> L: qemu-arm@nongnu.org S: Maintained -F: target-arm/ +F: target/arm/ F: hw/arm/ F: hw/cpu/a*mpcore.c F: include/hw/cpu/a*mpcore.h @@ -126,7 +126,7 @@ F: disas/libvixl/ CRIS M: Edgar E. Iglesias <edgar.iglesias@gmail.com> S: Maintained -F: target-cris/ +F: target/cris/ F: hw/cris/ F: include/hw/cris/ F: tests/tcg/cris/ @@ -135,7 +135,7 @@ F: disas/cris.c LM32 M: Michael Walle <michael@walle.cc> S: Maintained -F: target-lm32/ +F: target/lm32/ F: disas/lm32.c F: hw/lm32/ F: hw/*/lm32_* @@ -147,13 +147,13 @@ F: tests/tcg/lm32/ M68K M: Laurent Vivier <laurent@vivier.eu> S: Maintained -F: target-m68k/ +F: target/m68k/ F: disas/m68k.c MicroBlaze M: Edgar E. Iglesias <edgar.iglesias@gmail.com> S: Maintained -F: target-microblaze/ +F: target/microblaze/ F: hw/microblaze/ F: disas/microblaze.c @@ -161,7 +161,7 @@ MIPS M: Aurelien Jarno <aurelien@aurel32.net> M: Yongbok Kim <yongbok.kim@imgtec.com> S: Maintained -F: target-mips/ +F: target/mips/ F: hw/mips/ F: hw/misc/mips_* F: hw/intc/mips_gic.c @@ -176,7 +176,7 @@ F: disas/mips.c Moxie M: Anthony Green <green@moxielogic.com> S: Maintained -F: target-moxie/ +F: target/moxie/ F: disas/moxie.c F: hw/moxie/ F: default-configs/moxie-softmmu.mak @@ -184,7 +184,7 @@ F: default-configs/moxie-softmmu.mak OpenRISC M: Jia Liu <proljc@gmail.com> S: Maintained -F: target-openrisc/ +F: target/openrisc/ F: hw/openrisc/ F: tests/tcg/openrisc/ @@ -193,7 +193,7 @@ M: David Gibson <david@gibson.dropbear.id.au> M: Alexander Graf <agraf@suse.de> L: qemu-ppc@nongnu.org S: Maintained -F: target-ppc/ +F: target/ppc/ F: hw/ppc/ F: include/hw/ppc/ F: disas/ppc.c @@ -202,14 +202,14 @@ S390 M: Richard Henderson <rth@twiddle.net> M: Alexander Graf <agraf@suse.de> S: Maintained -F: target-s390x/ +F: target/s390x/ F: hw/s390x/ F: disas/s390.c SH4 M: Aurelien Jarno <aurelien@aurel32.net> S: Odd Fixes -F: target-sh4/ +F: target/sh4/ F: hw/sh4/ F: disas/sh4.c F: include/hw/sh4/ @@ -218,7 +218,7 @@ SPARC M: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> M: Artyom Tarasenko <atar4qemu@gmail.com> S: Maintained -F: target-sparc/ +F: target/sparc/ F: hw/sparc/ F: hw/sparc64/ F: disas/sparc.c @@ -226,7 +226,7 @@ F: disas/sparc.c UniCore32 M: Guan Xuetao <gxt@mprc.pku.edu.cn> S: Maintained -F: target-unicore32/ +F: target/unicore32/ F: hw/unicore32/ F: include/hw/unicore32/ @@ -235,7 +235,7 @@ M: Paolo Bonzini <pbonzini@redhat.com> M: Richard Henderson <rth@twiddle.net> M: Eduardo Habkost <ehabkost@redhat.com> S: Maintained -F: target-i386/ +F: target/i386/ F: hw/i386/ F: disas/i386.c @@ -243,14 +243,14 @@ Xtensa M: Max Filippov <jcmvbkbc@gmail.com> W: http://wiki.osll.spb.ru/doku.php?id=etc:users:jcmvbkbc:qemu-target-xtensa S: Maintained -F: target-xtensa/ +F: target/xtensa/ F: hw/xtensa/ F: tests/tcg/xtensa/ TriCore M: Bastian Koppelmann <kbastian@mail.uni-paderborn.de> S: Maintained -F: target-tricore/ +F: target/tricore/ F: hw/tricore/ F: include/hw/tricore/ @@ -269,26 +269,26 @@ ARM M: Peter Maydell <peter.maydell@linaro.org> L: qemu-arm@nongnu.org S: Maintained -F: target-arm/kvm.c +F: target/arm/kvm.c MIPS M: James Hogan <james.hogan@imgtec.com> S: Maintained -F: target-mips/kvm.c +F: target/mips/kvm.c PPC M: Alexander Graf <agraf@suse.de> S: Maintained -F: target-ppc/kvm.c +F: target/ppc/kvm.c S390 M: Christian Borntraeger <borntraeger@de.ibm.com> M: Cornelia Huck <cornelia.huck@de.ibm.com> M: Alexander Graf <agraf@suse.de> S: Maintained -F: target-s390x/kvm.c -F: target-s390x/ioinst.[ch] -F: target-s390x/machine.c +F: target/s390x/kvm.c +F: target/s390x/ioinst.[ch] +F: target/s390x/machine.c F: hw/intc/s390_flic.c F: hw/intc/s390_flic_kvm.c F: include/hw/s390x/s390_flic.h @@ -301,7 +301,7 @@ M: Paolo Bonzini <pbonzini@redhat.com> M: Marcelo Tosatti <mtosatti@redhat.com> L: kvm@vger.kernel.org S: Supported -F: target-i386/kvm.c +F: target/i386/kvm.c Guest CPU Cores (Xen): ---------------------- @@ -231,12 +231,10 @@ ALL_SUBDIRS=$(TARGET_DIRS) $(patsubst %,pc-bios/%, $(ROMS)) recurse-all: $(SUBDIR_RULES) $(ROMSUBDIR_RULES) -$(BUILD_DIR)/version.o: $(SRC_PATH)/version.rc config-host.h | $(BUILD_DIR)/version.lo +$(BUILD_DIR)/version.o: $(SRC_PATH)/version.rc config-host.h $(call quiet-command,$(WINDRES) -I$(BUILD_DIR) -o $@ $<,"RC","version.o") -$(BUILD_DIR)/version.lo: $(SRC_PATH)/version.rc config-host.h - $(call quiet-command,$(WINDRES) -I$(BUILD_DIR) -o $@ $<,"RC","version.lo") -Makefile: $(version-obj-y) $(version-lobj-y) +Makefile: $(version-obj-y) ###################################################################### # Build libraries @@ -358,10 +356,9 @@ clean: rm -f config.mak op-i386.h opc-i386.h gen-op-i386.h op-arm.h opc-arm.h gen-op-arm.h rm -f qemu-options.def rm -f *.msi - find . \( -name '*.l[oa]' -o -name '*.so' -o -name '*.dll' -o -name '*.mo' -o -name '*.[oda]' \) -type f -exec rm {} + + find . \( -name '*.so' -o -name '*.dll' -o -name '*.mo' -o -name '*.[oda]' \) -type f -exec rm {} + rm -f $(filter-out %.tlb,$(TOOLS)) $(HELPERS-y) qemu-ga TAGS cscope.* *.pod *~ */*~ rm -f fsdev/*.pod - rm -rf .libs */.libs rm -f qemu-img-cmds.h rm -f ui/shader/*-vert.h ui/shader/*-frag.h @# May not be present in GENERATED_HEADERS diff --git a/Makefile.objs b/Makefile.objs index 06f74b8b99..51c36a4d54 100644 --- a/Makefile.objs +++ b/Makefile.objs @@ -97,7 +97,6 @@ common-obj-y += disas/ ###################################################################### # Resource file for Windows executables version-obj-$(CONFIG_WIN32) += $(BUILD_DIR)/version.o -version-lobj-$(CONFIG_WIN32) += $(BUILD_DIR)/version.lo ###################################################################### # tracing @@ -155,11 +154,11 @@ trace-events-y += hw/alpha/trace-events trace-events-y += ui/trace-events trace-events-y += audio/trace-events trace-events-y += net/trace-events -trace-events-y += target-arm/trace-events -trace-events-y += target-i386/trace-events -trace-events-y += target-sparc/trace-events -trace-events-y += target-s390x/trace-events -trace-events-y += target-ppc/trace-events +trace-events-y += target/arm/trace-events +trace-events-y += target/i386/trace-events +trace-events-y += target/sparc/trace-events +trace-events-y += target/s390x/trace-events +trace-events-y += target/ppc/trace-events trace-events-y += qom/trace-events trace-events-y += linux-user/trace-events trace-events-y += qapi/trace-events diff --git a/Makefile.target b/Makefile.target index 7a5080e94a..8ae82cb311 100644 --- a/Makefile.target +++ b/Makefile.target @@ -11,7 +11,7 @@ $(call set-vpath, $(SRC_PATH):$(BUILD_DIR)) ifdef CONFIG_LINUX QEMU_CFLAGS += -I../linux-headers endif -QEMU_CFLAGS += -I.. -I$(SRC_PATH)/target-$(TARGET_BASE_ARCH) -DNEED_CPU_H +QEMU_CFLAGS += -I.. -I$(SRC_PATH)/target/$(TARGET_BASE_ARCH) -DNEED_CPU_H QEMU_CFLAGS+=-I$(SRC_PATH)/include @@ -76,6 +76,7 @@ $(QEMU_PROG)-simpletrace.stp: $(BUILD_DIR)/trace-events-all else stap: endif +.PHONY: stap all: $(PROGS) stap @@ -92,7 +93,7 @@ obj-$(CONFIG_TCG_INTERPRETER) += tci.o obj-y += tcg/tcg-common.o obj-$(CONFIG_TCG_INTERPRETER) += disas/tci.o obj-y += fpu/softfloat.o -obj-y += target-$(TARGET_BASE_ARCH)/ +obj-y += target/$(TARGET_BASE_ARCH)/ obj-y += disas.o obj-y += tcg-runtime.o obj-$(call notempty,$(TARGET_XML_FILES)) += gdbstub-xml.o @@ -1 +1 @@ -2.7.94 +2.8.50 @@ -28,8 +28,6 @@ TMPB="qemu-conf" TMPC="${TMPDIR1}/${TMPB}.c" TMPO="${TMPDIR1}/${TMPB}.o" TMPCXX="${TMPDIR1}/${TMPB}.cxx" -TMPL="${TMPDIR1}/${TMPB}.lo" -TMPA="${TMPDIR1}/lib${TMPB}.la" TMPE="${TMPDIR1}/${TMPB}.exe" TMPMO="${TMPDIR1}/${TMPB}.mo" @@ -313,6 +311,7 @@ gnutls_rnd="" nettle="" nettle_kdf="no" gcrypt="" +gcrypt_hmac="no" gcrypt_kdf="no" vte="" virglrenderer="" @@ -2417,6 +2416,19 @@ EOF if compile_prog "$gcrypt_cflags" "$gcrypt_libs" ; then gcrypt_kdf=yes fi + + cat > $TMPC << EOF +#include <gcrypt.h> +int main(void) { + gcry_mac_hd_t handle; + gcry_mac_open(&handle, GCRY_MAC_HMAC_MD5, + GCRY_MAC_FLAG_SECURE, NULL); + return 0; +} +EOF + if compile_prog "$gcrypt_cflags" "$gcrypt_libs" ; then + gcrypt_hmac=yes + fi else if test "$gcrypt" = "yes"; then feature_not_found "gcrypt" "Install gcrypt devel" @@ -5387,6 +5399,9 @@ if test "$gnutls_rnd" = "yes" ; then fi if test "$gcrypt" = "yes" ; then echo "CONFIG_GCRYPT=y" >> $config_host_mak + if test "$gcrypt_hmac" = "yes" ; then + echo "CONFIG_GCRYPT_HMAC=y" >> $config_host_mak + fi if test "$gcrypt_kdf" = "yes" ; then echo "CONFIG_GCRYPT_KDF=y" >> $config_host_mak fi diff --git a/crypto/Makefile.objs b/crypto/Makefile.objs index a36d2d9bdf..1f749f2087 100644 --- a/crypto/Makefile.objs +++ b/crypto/Makefile.objs @@ -3,6 +3,10 @@ crypto-obj-y += hash.o crypto-obj-$(CONFIG_NETTLE) += hash-nettle.o crypto-obj-$(if $(CONFIG_NETTLE),n,$(CONFIG_GCRYPT)) += hash-gcrypt.o crypto-obj-$(if $(CONFIG_NETTLE),n,$(if $(CONFIG_GCRYPT),n,y)) += hash-glib.o +crypto-obj-y += hmac.o +crypto-obj-$(CONFIG_NETTLE) += hmac-nettle.o +crypto-obj-$(CONFIG_GCRYPT_HMAC) += hmac-gcrypt.o +crypto-obj-$(if $(CONFIG_NETTLE),n,$(if $(CONFIG_GCRYPT_HMAC),n,y)) += hmac-glib.o crypto-obj-y += aes.o crypto-obj-y += desrfb.o crypto-obj-y += cipher.o diff --git a/crypto/cipher-gcrypt.c b/crypto/cipher-gcrypt.c index c550db9008..6487ecaf37 100644 --- a/crypto/cipher-gcrypt.c +++ b/crypto/cipher-gcrypt.c @@ -29,6 +29,7 @@ bool qcrypto_cipher_supports(QCryptoCipherAlgorithm alg, { switch (alg) { case QCRYPTO_CIPHER_ALG_DES_RFB: + case QCRYPTO_CIPHER_ALG_3DES: case QCRYPTO_CIPHER_ALG_AES_128: case QCRYPTO_CIPHER_ALG_AES_192: case QCRYPTO_CIPHER_ALG_AES_256: @@ -99,6 +100,10 @@ QCryptoCipher *qcrypto_cipher_new(QCryptoCipherAlgorithm alg, gcryalg = GCRY_CIPHER_DES; break; + case QCRYPTO_CIPHER_ALG_3DES: + gcryalg = GCRY_CIPHER_3DES; + break; + case QCRYPTO_CIPHER_ALG_AES_128: gcryalg = GCRY_CIPHER_AES128; break; @@ -200,6 +205,7 @@ QCryptoCipher *qcrypto_cipher_new(QCryptoCipherAlgorithm alg, case QCRYPTO_CIPHER_ALG_TWOFISH_256: ctx->blocksize = 16; break; + case QCRYPTO_CIPHER_ALG_3DES: case QCRYPTO_CIPHER_ALG_CAST5_128: ctx->blocksize = 8; break; diff --git a/crypto/cipher-nettle.c b/crypto/cipher-nettle.c index cd094cd6a5..dfc9030227 100644 --- a/crypto/cipher-nettle.c +++ b/crypto/cipher-nettle.c @@ -78,6 +78,18 @@ static void des_decrypt_native(cipher_ctx_t ctx, cipher_length_t length, des_decrypt(ctx, length, dst, src); } +static void des3_encrypt_native(cipher_ctx_t ctx, cipher_length_t length, + uint8_t *dst, const uint8_t *src) +{ + des3_encrypt(ctx, length, dst, src); +} + +static void des3_decrypt_native(cipher_ctx_t ctx, cipher_length_t length, + uint8_t *dst, const uint8_t *src) +{ + des3_decrypt(ctx, length, dst, src); +} + static void cast128_encrypt_native(cipher_ctx_t ctx, cipher_length_t length, uint8_t *dst, const uint8_t *src) { @@ -140,6 +152,18 @@ static void des_decrypt_wrapper(const void *ctx, size_t length, des_decrypt(ctx, length, dst, src); } +static void des3_encrypt_wrapper(const void *ctx, size_t length, + uint8_t *dst, const uint8_t *src) +{ + des3_encrypt(ctx, length, dst, src); +} + +static void des3_decrypt_wrapper(const void *ctx, size_t length, + uint8_t *dst, const uint8_t *src) +{ + des3_decrypt(ctx, length, dst, src); +} + static void cast128_encrypt_wrapper(const void *ctx, size_t length, uint8_t *dst, const uint8_t *src) { @@ -197,6 +221,7 @@ bool qcrypto_cipher_supports(QCryptoCipherAlgorithm alg, { switch (alg) { case QCRYPTO_CIPHER_ALG_DES_RFB: + case QCRYPTO_CIPHER_ALG_3DES: case QCRYPTO_CIPHER_ALG_AES_128: case QCRYPTO_CIPHER_ALG_AES_192: case QCRYPTO_CIPHER_ALG_AES_256: @@ -254,6 +279,7 @@ QCryptoCipher *qcrypto_cipher_new(QCryptoCipherAlgorithm alg, cipher->mode = mode; ctx = g_new0(QCryptoCipherNettle, 1); + cipher->opaque = ctx; switch (alg) { case QCRYPTO_CIPHER_ALG_DES_RFB: @@ -270,6 +296,18 @@ QCryptoCipher *qcrypto_cipher_new(QCryptoCipherAlgorithm alg, ctx->blocksize = DES_BLOCK_SIZE; break; + case QCRYPTO_CIPHER_ALG_3DES: + ctx->ctx = g_new0(struct des3_ctx, 1); + des3_set_key(ctx->ctx, key); + + ctx->alg_encrypt_native = des3_encrypt_native; + ctx->alg_decrypt_native = des3_decrypt_native; + ctx->alg_encrypt_wrapper = des3_encrypt_wrapper; + ctx->alg_decrypt_wrapper = des3_decrypt_wrapper; + + ctx->blocksize = DES3_BLOCK_SIZE; + break; + case QCRYPTO_CIPHER_ALG_AES_128: case QCRYPTO_CIPHER_ALG_AES_192: case QCRYPTO_CIPHER_ALG_AES_256: @@ -384,13 +422,11 @@ QCryptoCipher *qcrypto_cipher_new(QCryptoCipherAlgorithm alg, } ctx->iv = g_new0(uint8_t, ctx->blocksize); - cipher->opaque = ctx; return cipher; error: - g_free(cipher); - g_free(ctx); + qcrypto_cipher_free(cipher); return NULL; } diff --git a/crypto/cipher.c b/crypto/cipher.c index a9bca41302..9ecaff702b 100644 --- a/crypto/cipher.c +++ b/crypto/cipher.c @@ -28,6 +28,7 @@ static size_t alg_key_len[QCRYPTO_CIPHER_ALG__MAX] = { [QCRYPTO_CIPHER_ALG_AES_192] = 24, [QCRYPTO_CIPHER_ALG_AES_256] = 32, [QCRYPTO_CIPHER_ALG_DES_RFB] = 8, + [QCRYPTO_CIPHER_ALG_3DES] = 24, [QCRYPTO_CIPHER_ALG_CAST5_128] = 16, [QCRYPTO_CIPHER_ALG_SERPENT_128] = 16, [QCRYPTO_CIPHER_ALG_SERPENT_192] = 24, @@ -42,6 +43,7 @@ static size_t alg_block_len[QCRYPTO_CIPHER_ALG__MAX] = { [QCRYPTO_CIPHER_ALG_AES_192] = 16, [QCRYPTO_CIPHER_ALG_AES_256] = 16, [QCRYPTO_CIPHER_ALG_DES_RFB] = 8, + [QCRYPTO_CIPHER_ALG_3DES] = 8, [QCRYPTO_CIPHER_ALG_CAST5_128] = 8, [QCRYPTO_CIPHER_ALG_SERPENT_128] = 16, [QCRYPTO_CIPHER_ALG_SERPENT_192] = 16, @@ -107,8 +109,9 @@ qcrypto_cipher_validate_key_length(QCryptoCipherAlgorithm alg, } if (mode == QCRYPTO_CIPHER_MODE_XTS) { - if (alg == QCRYPTO_CIPHER_ALG_DES_RFB) { - error_setg(errp, "XTS mode not compatible with DES-RFB"); + if (alg == QCRYPTO_CIPHER_ALG_DES_RFB + || alg == QCRYPTO_CIPHER_ALG_3DES) { + error_setg(errp, "XTS mode not compatible with DES-RFB/3DES"); return false; } if (nkey % 2) { diff --git a/crypto/hmac-gcrypt.c b/crypto/hmac-gcrypt.c new file mode 100644 index 0000000000..21189e694f --- /dev/null +++ b/crypto/hmac-gcrypt.c @@ -0,0 +1,152 @@ +/* + * QEMU Crypto hmac algorithms (based on libgcrypt) + * + * Copyright (c) 2016 HUAWEI TECHNOLOGIES CO., LTD. + * + * Authors: + * Longpeng(Mike) <longpeng2@huawei.com> + * + * This work is licensed under the terms of the GNU GPL, version 2 or + * (at your option) any later version. See the COPYING file in the + * top-level directory. + * + */ + +#include "qemu/osdep.h" +#include "qapi/error.h" +#include "crypto/hmac.h" +#include <gcrypt.h> + +static int qcrypto_hmac_alg_map[QCRYPTO_HASH_ALG__MAX] = { + [QCRYPTO_HASH_ALG_MD5] = GCRY_MAC_HMAC_MD5, + [QCRYPTO_HASH_ALG_SHA1] = GCRY_MAC_HMAC_SHA1, + [QCRYPTO_HASH_ALG_SHA224] = GCRY_MAC_HMAC_SHA224, + [QCRYPTO_HASH_ALG_SHA256] = GCRY_MAC_HMAC_SHA256, + [QCRYPTO_HASH_ALG_SHA384] = GCRY_MAC_HMAC_SHA384, + [QCRYPTO_HASH_ALG_SHA512] = GCRY_MAC_HMAC_SHA512, + [QCRYPTO_HASH_ALG_RIPEMD160] = GCRY_MAC_HMAC_RMD160, +}; + +typedef struct QCryptoHmacGcrypt QCryptoHmacGcrypt; +struct QCryptoHmacGcrypt { + gcry_mac_hd_t handle; +}; + +bool qcrypto_hmac_supports(QCryptoHashAlgorithm alg) +{ + if (alg < G_N_ELEMENTS(qcrypto_hmac_alg_map) && + qcrypto_hmac_alg_map[alg] != GCRY_MAC_NONE) { + return true; + } + + return false; +} + +QCryptoHmac *qcrypto_hmac_new(QCryptoHashAlgorithm alg, + const uint8_t *key, size_t nkey, + Error **errp) +{ + QCryptoHmac *hmac; + QCryptoHmacGcrypt *ctx; + gcry_error_t err; + + if (!qcrypto_hmac_supports(alg)) { + error_setg(errp, "Unsupported hmac algorithm %s", + QCryptoHashAlgorithm_lookup[alg]); + return NULL; + } + + hmac = g_new0(QCryptoHmac, 1); + hmac->alg = alg; + + ctx = g_new0(QCryptoHmacGcrypt, 1); + + err = gcry_mac_open(&ctx->handle, qcrypto_hmac_alg_map[alg], + GCRY_MAC_FLAG_SECURE, NULL); + if (err != 0) { + error_setg(errp, "Cannot initialize hmac: %s", + gcry_strerror(err)); + goto error; + } + + err = gcry_mac_setkey(ctx->handle, (const void *)key, nkey); + if (err != 0) { + error_setg(errp, "Cannot set key: %s", + gcry_strerror(err)); + goto error; + } + + hmac->opaque = ctx; + return hmac; + +error: + g_free(ctx); + g_free(hmac); + return NULL; +} + +void qcrypto_hmac_free(QCryptoHmac *hmac) +{ + QCryptoHmacGcrypt *ctx; + + if (!hmac) { + return; + } + + ctx = hmac->opaque; + gcry_mac_close(ctx->handle); + + g_free(ctx); + g_free(hmac); +} + +int qcrypto_hmac_bytesv(QCryptoHmac *hmac, + const struct iovec *iov, + size_t niov, + uint8_t **result, + size_t *resultlen, + Error **errp) +{ + QCryptoHmacGcrypt *ctx; + gcry_error_t err; + uint32_t ret; + int i; + + ctx = hmac->opaque; + + for (i = 0; i < niov; i++) { + gcry_mac_write(ctx->handle, iov[i].iov_base, iov[i].iov_len); + } + + ret = gcry_mac_get_algo_maclen(qcrypto_hmac_alg_map[hmac->alg]); + if (ret <= 0) { + error_setg(errp, "Unable to get hmac length: %s", + gcry_strerror(ret)); + return -1; + } + + if (*resultlen == 0) { + *resultlen = ret; + *result = g_new0(uint8_t, *resultlen); + } else if (*resultlen != ret) { + error_setg(errp, "Result buffer size %zu is smaller than hmac %d", + *resultlen, ret); + return -1; + } + + err = gcry_mac_read(ctx->handle, *result, resultlen); + if (err != 0) { + error_setg(errp, "Cannot get result: %s", + gcry_strerror(err)); + return -1; + } + + err = gcry_mac_reset(ctx->handle); + if (err != 0) { + error_setg(errp, "Cannot reset hmac context: %s", + gcry_strerror(err)); + return -1; + } + + return 0; +} diff --git a/crypto/hmac-glib.c b/crypto/hmac-glib.c new file mode 100644 index 0000000000..08a1fdd10a --- /dev/null +++ b/crypto/hmac-glib.c @@ -0,0 +1,166 @@ +/* + * QEMU Crypto hmac algorithms (based on glib) + * + * Copyright (c) 2016 HUAWEI TECHNOLOGIES CO., LTD. + * + * Authors: + * Longpeng(Mike) <longpeng2@huawei.com> + * + * This work is licensed under the terms of the GNU GPL, version 2 or + * (at your option) any later version. See the COPYING file in the + * top-level directory. + * + */ + +#include "qemu/osdep.h" +#include "qapi/error.h" +#include "crypto/hmac.h" + +/* Support for HMAC Algos has been added in GLib 2.30 */ +#if GLIB_CHECK_VERSION(2, 30, 0) + +static int qcrypto_hmac_alg_map[QCRYPTO_HASH_ALG__MAX] = { + [QCRYPTO_HASH_ALG_MD5] = G_CHECKSUM_MD5, + [QCRYPTO_HASH_ALG_SHA1] = G_CHECKSUM_SHA1, + [QCRYPTO_HASH_ALG_SHA256] = G_CHECKSUM_SHA256, +/* Support for HMAC SHA-512 in GLib 2.42 */ +#if GLIB_CHECK_VERSION(2, 42, 0) + [QCRYPTO_HASH_ALG_SHA512] = G_CHECKSUM_SHA512, +#else + [QCRYPTO_HASH_ALG_SHA512] = -1, +#endif + [QCRYPTO_HASH_ALG_SHA224] = -1, + [QCRYPTO_HASH_ALG_SHA384] = -1, + [QCRYPTO_HASH_ALG_RIPEMD160] = -1, +}; + +typedef struct QCryptoHmacGlib QCryptoHmacGlib; +struct QCryptoHmacGlib { + GHmac *ghmac; +}; + +bool qcrypto_hmac_supports(QCryptoHashAlgorithm alg) +{ + if (alg < G_N_ELEMENTS(qcrypto_hmac_alg_map) && + qcrypto_hmac_alg_map[alg] != -1) { + return true; + } + + return false; +} + +QCryptoHmac *qcrypto_hmac_new(QCryptoHashAlgorithm alg, + const uint8_t *key, size_t nkey, + Error **errp) +{ + QCryptoHmac *hmac; + QCryptoHmacGlib *ctx; + + if (!qcrypto_hmac_supports(alg)) { + error_setg(errp, "Unsupported hmac algorithm %s", + QCryptoHashAlgorithm_lookup[alg]); + return NULL; + } + + hmac = g_new0(QCryptoHmac, 1); + hmac->alg = alg; + + ctx = g_new0(QCryptoHmacGlib, 1); + + ctx->ghmac = g_hmac_new(qcrypto_hmac_alg_map[alg], + (const uint8_t *)key, nkey); + if (!ctx->ghmac) { + error_setg(errp, "Cannot initialize hmac and set key"); + goto error; + } + + hmac->opaque = ctx; + return hmac; + +error: + g_free(ctx); + g_free(hmac); + return NULL; +} + +void qcrypto_hmac_free(QCryptoHmac *hmac) +{ + QCryptoHmacGlib *ctx; + + if (!hmac) { + return; + } + + ctx = hmac->opaque; + g_hmac_unref(ctx->ghmac); + + g_free(ctx); + g_free(hmac); +} + +int qcrypto_hmac_bytesv(QCryptoHmac *hmac, + const struct iovec *iov, + size_t niov, + uint8_t **result, + size_t *resultlen, + Error **errp) +{ + QCryptoHmacGlib *ctx; + int i, ret; + + ctx = hmac->opaque; + + for (i = 0; i < niov; i++) { + g_hmac_update(ctx->ghmac, iov[i].iov_base, iov[i].iov_len); + } + + ret = g_checksum_type_get_length(qcrypto_hmac_alg_map[hmac->alg]); + if (ret < 0) { + error_setg(errp, "Unable to get hmac length"); + return -1; + } + + if (*resultlen == 0) { + *resultlen = ret; + *result = g_new0(uint8_t, *resultlen); + } else if (*resultlen != ret) { + error_setg(errp, "Result buffer size %zu is smaller than hmac %d", + *resultlen, ret); + return -1; + } + + g_hmac_get_digest(ctx->ghmac, *result, resultlen); + + return 0; +} + +#else + +bool qcrypto_hmac_supports(QCryptoHashAlgorithm alg) +{ + return false; +} + +QCryptoHmac *qcrypto_hmac_new(QCryptoHashAlgorithm alg, + const uint8_t *key, size_t nkey, + Error **errp) +{ + return NULL; +} + +void qcrypto_hmac_free(QCryptoHmac *hmac) +{ + return; +} + +int qcrypto_hmac_bytesv(QCryptoHmac *hmac, + const struct iovec *iov, + size_t niov, + uint8_t **result, + size_t *resultlen, + Error **errp) +{ + return -1; +} + +#endif diff --git a/crypto/hmac-nettle.c b/crypto/hmac-nettle.c new file mode 100644 index 0000000000..4a9e6b2c7d --- /dev/null +++ b/crypto/hmac-nettle.c @@ -0,0 +1,175 @@ +/* + * QEMU Crypto hmac algorithms (based on nettle) + * + * Copyright (c) 2016 HUAWEI TECHNOLOGIES CO., LTD. + * + * Authors: + * Longpeng(Mike) <longpeng2@huawei.com> + * + * This work is licensed under the terms of the GNU GPL, version 2 or + * (at your option) any later version. See the COPYING file in the + * top-level directory. + * + */ + +#include "qemu/osdep.h" +#include "qapi/error.h" +#include "crypto/hmac.h" +#include <nettle/hmac.h> + +typedef void (*qcrypto_nettle_hmac_setkey)(void *ctx, + size_t key_length, const uint8_t *key); + +typedef void (*qcrypto_nettle_hmac_update)(void *ctx, + size_t length, const uint8_t *data); + +typedef void (*qcrypto_nettle_hmac_digest)(void *ctx, + size_t length, uint8_t *digest); + +typedef struct QCryptoHmacNettle QCryptoHmacNettle; +struct QCryptoHmacNettle { + union qcrypto_nettle_hmac_ctx { + struct hmac_md5_ctx md5_ctx; + struct hmac_sha1_ctx sha1_ctx; + struct hmac_sha256_ctx sha256_ctx; /* equals hmac_sha224_ctx */ + struct hmac_sha512_ctx sha512_ctx; /* equals hmac_sha384_ctx */ + struct hmac_ripemd160_ctx ripemd160_ctx; + } u; +}; + +struct qcrypto_nettle_hmac_alg { + qcrypto_nettle_hmac_setkey setkey; + qcrypto_nettle_hmac_update update; + qcrypto_nettle_hmac_digest digest; + size_t len; +} qcrypto_hmac_alg_map[QCRYPTO_HASH_ALG__MAX] = { + [QCRYPTO_HASH_ALG_MD5] = { + .setkey = (qcrypto_nettle_hmac_setkey)hmac_md5_set_key, + .update = (qcrypto_nettle_hmac_update)hmac_md5_update, + .digest = (qcrypto_nettle_hmac_digest)hmac_md5_digest, + .len = MD5_DIGEST_SIZE, + }, + [QCRYPTO_HASH_ALG_SHA1] = { + .setkey = (qcrypto_nettle_hmac_setkey)hmac_sha1_set_key, + .update = (qcrypto_nettle_hmac_update)hmac_sha1_update, + .digest = (qcrypto_nettle_hmac_digest)hmac_sha1_digest, + .len = SHA1_DIGEST_SIZE, + }, + [QCRYPTO_HASH_ALG_SHA224] = { + .setkey = (qcrypto_nettle_hmac_setkey)hmac_sha224_set_key, + .update = (qcrypto_nettle_hmac_update)hmac_sha224_update, + .digest = (qcrypto_nettle_hmac_digest)hmac_sha224_digest, + .len = SHA224_DIGEST_SIZE, + }, + [QCRYPTO_HASH_ALG_SHA256] = { + .setkey = (qcrypto_nettle_hmac_setkey)hmac_sha256_set_key, + .update = (qcrypto_nettle_hmac_update)hmac_sha256_update, + .digest = (qcrypto_nettle_hmac_digest)hmac_sha256_digest, + .len = SHA256_DIGEST_SIZE, + }, + [QCRYPTO_HASH_ALG_SHA384] = { + .setkey = (qcrypto_nettle_hmac_setkey)hmac_sha384_set_key, + .update = (qcrypto_nettle_hmac_update)hmac_sha384_update, + .digest = (qcrypto_nettle_hmac_digest)hmac_sha384_digest, + .len = SHA384_DIGEST_SIZE, + }, + [QCRYPTO_HASH_ALG_SHA512] = { + .setkey = (qcrypto_nettle_hmac_setkey)hmac_sha512_set_key, + .update = (qcrypto_nettle_hmac_update)hmac_sha512_update, + .digest = (qcrypto_nettle_hmac_digest)hmac_sha512_digest, + .len = SHA512_DIGEST_SIZE, + }, + [QCRYPTO_HASH_ALG_RIPEMD160] = { + .setkey = (qcrypto_nettle_hmac_setkey)hmac_ripemd160_set_key, + .update = (qcrypto_nettle_hmac_update)hmac_ripemd160_update, + .digest = (qcrypto_nettle_hmac_digest)hmac_ripemd160_digest, + .len = RIPEMD160_DIGEST_SIZE, + }, +}; + +bool qcrypto_hmac_supports(QCryptoHashAlgorithm alg) +{ + if (alg < G_N_ELEMENTS(qcrypto_hmac_alg_map) && + qcrypto_hmac_alg_map[alg].setkey != NULL) { + return true; + } + + return false; +} + +QCryptoHmac *qcrypto_hmac_new(QCryptoHashAlgorithm alg, + const uint8_t *key, size_t nkey, + Error **errp) +{ + QCryptoHmac *hmac; + QCryptoHmacNettle *ctx; + + if (!qcrypto_hmac_supports(alg)) { + error_setg(errp, "Unsupported hmac algorithm %s", + QCryptoHashAlgorithm_lookup[alg]); + return NULL; + } + + hmac = g_new0(QCryptoHmac, 1); + hmac->alg = alg; + + ctx = g_new0(QCryptoHmacNettle, 1); + + qcrypto_hmac_alg_map[alg].setkey(&ctx->u, nkey, key); + + hmac->opaque = ctx; + + return hmac; +} + +void qcrypto_hmac_free(QCryptoHmac *hmac) +{ + QCryptoHmacNettle *ctx; + + if (!hmac) { + return; + } + + ctx = hmac->opaque; + + g_free(ctx); + g_free(hmac); +} + +int qcrypto_hmac_bytesv(QCryptoHmac *hmac, + const struct iovec *iov, + size_t niov, + uint8_t **result, + size_t *resultlen, + Error **errp) +{ + QCryptoHmacNettle *ctx; + int i; + + ctx = (QCryptoHmacNettle *)hmac->opaque; + + for (i = 0; i < niov; ++i) { + size_t len = iov[i].iov_len; + uint8_t *base = iov[i].iov_base; + while (len) { + size_t shortlen = MIN(len, UINT_MAX); + qcrypto_hmac_alg_map[hmac->alg].update(&ctx->u, len, base); + len -= shortlen; + base += len; + } + } + + if (*resultlen == 0) { + *resultlen = qcrypto_hmac_alg_map[hmac->alg].len; + *result = g_new0(uint8_t, *resultlen); + } else if (*resultlen != qcrypto_hmac_alg_map[hmac->alg].len) { + error_setg(errp, + "Result buffer size %zu is smaller than hash %zu", + *resultlen, qcrypto_hmac_alg_map[hmac->alg].len); + return -1; + } + + qcrypto_hmac_alg_map[hmac->alg].digest(&ctx->u, *resultlen, *result); + + return 0; +} diff --git a/crypto/hmac.c b/crypto/hmac.c new file mode 100644 index 0000000000..5750405cfb --- /dev/null +++ b/crypto/hmac.c @@ -0,0 +1,72 @@ +/* + * QEMU Crypto hmac algorithms + * + * Copyright (c) 2016 HUAWEI TECHNOLOGIES CO., LTD. + * + * This work is licensed under the terms of the GNU GPL, version 2 or + * (at your option) any later version. See the COPYING file in the + * top-level directory. + * + */ + +#include "qemu/osdep.h" +#include "qapi/error.h" +#include "crypto/hmac.h" + +static const char hex[] = "0123456789abcdef"; + +int qcrypto_hmac_bytes(QCryptoHmac *hmac, + const char *buf, + size_t len, + uint8_t **result, + size_t *resultlen, + Error **errp) +{ + struct iovec iov = { + .iov_base = (char *)buf, + .iov_len = len + }; + + return qcrypto_hmac_bytesv(hmac, &iov, 1, result, resultlen, errp); +} + +int qcrypto_hmac_digestv(QCryptoHmac *hmac, + const struct iovec *iov, + size_t niov, + char **digest, + Error **errp) +{ + uint8_t *result = NULL; + size_t resultlen = 0; + size_t i; + + if (qcrypto_hmac_bytesv(hmac, iov, niov, &result, &resultlen, errp) < 0) { + return -1; + } + + *digest = g_new0(char, (resultlen * 2) + 1); + + for (i = 0 ; i < resultlen ; i++) { + (*digest)[(i * 2)] = hex[(result[i] >> 4) & 0xf]; + (*digest)[(i * 2) + 1] = hex[result[i] & 0xf]; + } + + (*digest)[resultlen * 2] = '\0'; + + g_free(result); + return 0; +} + +int qcrypto_hmac_digest(QCryptoHmac *hmac, + const char *buf, + size_t len, + char **digest, + Error **errp) +{ + struct iovec iov = { + .iov_base = (char *)buf, + .iov_len = len + }; + + return qcrypto_hmac_digestv(hmac, &iov, 1, digest, errp); +} diff --git a/crypto/hmac.h b/crypto/hmac.h new file mode 100644 index 0000000000..0d3acd728a --- /dev/null +++ b/crypto/hmac.h @@ -0,0 +1,166 @@ +/* + * QEMU Crypto hmac algorithms + * + * Copyright (c) 2016 HUAWEI TECHNOLOGIES CO., LTD. + * + * This work is licensed under the terms of the GNU GPL, version 2 or + * (at your option) any later version. See the COPYING file in the + * top-level directory. + * + */ + +#ifndef QCRYPTO_HMAC_H +#define QCRYPTO_HMAC_H + +#include "qapi-types.h" + +typedef struct QCryptoHmac QCryptoHmac; +struct QCryptoHmac { + QCryptoHashAlgorithm alg; + void *opaque; +}; + +/** + * qcrypto_hmac_supports: + * @alg: the hmac algorithm + * + * Determine if @alg hmac algorithm is supported by + * the current configured build + * + * Returns: + * true if the algorithm is supported, false otherwise + */ +bool qcrypto_hmac_supports(QCryptoHashAlgorithm alg); + +/** + * qcrypto_hmac_new: + * @alg: the hmac algorithm + * @key: the key bytes + * @nkey: the length of @key + * @errp: pointer to a NULL-initialized error object + * + * Creates a new hmac object with the algorithm @alg + * + * The @key parameter provides the bytes representing + * the secret key to use. The @nkey parameter specifies + * the length of @key in bytes + * + * Note: must use qcrypto_hmac_free() to release the + * returned hmac object when no longer required + * + * Returns: + * a new hmac object, or NULL on error + */ +QCryptoHmac *qcrypto_hmac_new(QCryptoHashAlgorithm alg, + const uint8_t *key, size_t nkey, + Error **errp); + +/** + * qcrypto_hmac_free: + * @hmac: the hmac object + * + * Release the memory associated with @hmac that was + * previously allocated by qcrypto_hmac_new() + */ +void qcrypto_hmac_free(QCryptoHmac *hmac); + +/** + * qcrypto_hmac_bytesv: + * @hmac: the hmac object + * @iov: the array of memory regions to hmac + * @niov: the length of @iov + * @result: pointer to hold output hmac + * @resultlen: pointer to hold length of @result + * @errp: pointer to a NULL-initialized error object + * + * Computes the hmac across all the memory regions + * present in @iov. The @result pointer will be + * filled with raw bytes representing the computed + * hmac, which will have length @resultlen. The + * memory pointer in @result must be released + * with a call to g_free() when no longer required. + * + * Returns: + * 0 on success, -1 on error + */ +int qcrypto_hmac_bytesv(QCryptoHmac *hmac, + const struct iovec *iov, + size_t niov, + uint8_t **result, + size_t *resultlen, + Error **errp); + +/** + * qcrypto_hmac_bytes: + * @hmac: the hmac object + * @buf: the memory region to hmac + * @len: the length of @buf + * @result: pointer to hold output hmac + * @resultlen: pointer to hold length of @result + * @errp: pointer to a NULL-initialized error object + * + * Computes the hmac across all the memory region + * @buf of length @len. The @result pointer will be + * filled with raw bytes representing the computed + * hmac, which will have length @resultlen. The + * memory pointer in @result must be released + * with a call to g_free() when no longer required. + * + * Returns: + * 0 on success, -1 on error + */ +int qcrypto_hmac_bytes(QCryptoHmac *hmac, + const char *buf, + size_t len, + uint8_t **result, + size_t *resultlen, + Error **errp); + +/** + * qcrypto_hmac_digestv: + * @hmac: the hmac object + * @iov: the array of memory regions to hmac + * @niov: the length of @iov + * @digest: pointer to hold output hmac + * @errp: pointer to a NULL-initialized error object + * + * Computes the hmac across all the memory regions + * present in @iov. The @digest pointer will be + * filled with the printable hex digest of the computed + * hmac, which will be terminated by '\0'. The + * memory pointer in @digest must be released + * with a call to g_free() when no longer required. + * + * Returns: + * 0 on success, -1 on error + */ +int qcrypto_hmac_digestv(QCryptoHmac *hmac, + const struct iovec *iov, + size_t niov, + char **digest, + Error **errp); + +/** + * qcrypto_hmac_digest: + * @hmac: the hmac object + * @buf: the memory region to hmac + * @len: the length of @buf + * @digest: pointer to hold output hmac + * @errp: pointer to a NULL-initialized error object + * + * Computes the hmac across all the memory region + * @buf of length @len. The @digest pointer will be + * filled with the printable hex digest of the computed + * hmac, which will be terminated by '\0'. The + * memory pointer in @digest must be released + * with a call to g_free() when no longer required. + * + * Returns: 0 on success, -1 on error + */ +int qcrypto_hmac_digest(QCryptoHmac *hmac, + const char *buf, + size_t len, + char **digest, + Error **errp); + +#endif diff --git a/disas/cris.c b/disas/cris.c index 7f35bc0c6b..08161d1f21 100644 --- a/disas/cris.c +++ b/disas/cris.c @@ -21,9 +21,7 @@ #include "qemu/osdep.h" #include "qemu-common.h" #include "disas/bfd.h" -//#include "sysdep.h" -#include "target-cris/opcode-cris.h" -//#include "libiberty.h" +#include "target/cris/opcode-cris.h" #define CONST_STRNEQ(STR1,STR2) (strncmp ((STR1), (STR2), sizeof (STR2) - 1) == 0) diff --git a/disas/m68k.c b/disas/m68k.c index 8e7c3f76c4..073abb9efd 100644 --- a/disas/m68k.c +++ b/disas/m68k.c @@ -4698,10 +4698,6 @@ get_field (const unsigned char *data, enum floatformat_byteorders order, return result; } -#ifndef min -#define min(a, b) ((a) < (b) ? (a) : (b)) -#endif - /* Convert from FMT to a double. FROM is the address of the extended float. Store the double in *TO. */ @@ -4733,7 +4729,7 @@ floatformat_to_double (const struct floatformat *fmt, nan = 0; while (mant_bits_left > 0) { - mant_bits = min (mant_bits_left, 32); + mant_bits = MIN(mant_bits_left, 32); if (get_field (ufrom, fmt->byteorder, fmt->totalsize, mant_off, mant_bits) != 0) @@ -4793,7 +4789,7 @@ floatformat_to_double (const struct floatformat *fmt, while (mant_bits_left > 0) { - mant_bits = min (mant_bits_left, 32); + mant_bits = MIN(mant_bits_left, 32); mant = get_field (ufrom, fmt->byteorder, fmt->totalsize, mant_off, mant_bits); @@ -2938,6 +2938,31 @@ bool address_space_access_valid(AddressSpace *as, hwaddr addr, int len, bool is_ return true; } +static hwaddr +address_space_extend_translation(AddressSpace *as, hwaddr addr, hwaddr target_len, + MemoryRegion *mr, hwaddr base, hwaddr len, + bool is_write) +{ + hwaddr done = 0; + hwaddr xlat; + MemoryRegion *this_mr; + + for (;;) { + target_len -= len; + addr += len; + done += len; + if (target_len == 0) { + return done; + } + + len = target_len; + this_mr = address_space_translate(as, addr, &xlat, &len, is_write); + if (this_mr != mr || xlat != base + done) { + return done; + } + } +} + /* Map a physical memory region into a host virtual address. * May map a subset of the requested range, given by and returned in *plen. * May return NULL if resources needed to perform the mapping are exhausted. @@ -2951,9 +2976,8 @@ void *address_space_map(AddressSpace *as, bool is_write) { hwaddr len = *plen; - hwaddr done = 0; - hwaddr l, xlat, base; - MemoryRegion *mr, *this_mr; + hwaddr l, xlat; + MemoryRegion *mr; void *ptr; if (len == 0) { @@ -2987,26 +3011,10 @@ void *address_space_map(AddressSpace *as, return bounce.buffer; } - base = xlat; - - for (;;) { - len -= l; - addr += l; - done += l; - if (len == 0) { - break; - } - - l = len; - this_mr = address_space_translate(as, addr, &xlat, &l, is_write); - if (this_mr != mr || xlat != base + done) { - break; - } - } memory_region_ref(mr); - *plen = done; - ptr = qemu_ram_ptr_length(mr->ram_block, base, plen); + *plen = address_space_extend_translation(as, addr, len, mr, xlat, l, is_write); + ptr = qemu_ram_ptr_length(mr->ram_block, xlat, plen); rcu_read_unlock(); return ptr; @@ -3058,597 +3066,92 @@ void cpu_physical_memory_unmap(void *buffer, hwaddr len, return address_space_unmap(&address_space_memory, buffer, len, is_write, access_len); } -/* warning: addr must be aligned */ -static inline uint32_t address_space_ldl_internal(AddressSpace *as, hwaddr addr, - MemTxAttrs attrs, - MemTxResult *result, - enum device_endian endian) -{ - uint8_t *ptr; - uint64_t val; - MemoryRegion *mr; - hwaddr l = 4; - hwaddr addr1; - MemTxResult r; - bool release_lock = false; - - rcu_read_lock(); - mr = address_space_translate(as, addr, &addr1, &l, false); - if (l < 4 || !memory_access_is_direct(mr, false)) { - release_lock |= prepare_mmio_access(mr); - - /* I/O case */ - r = memory_region_dispatch_read(mr, addr1, &val, 4, attrs); -#if defined(TARGET_WORDS_BIGENDIAN) - if (endian == DEVICE_LITTLE_ENDIAN) { - val = bswap32(val); - } -#else - if (endian == DEVICE_BIG_ENDIAN) { - val = bswap32(val); - } -#endif - } else { - /* RAM case */ - ptr = qemu_map_ram_ptr(mr->ram_block, addr1); - switch (endian) { - case DEVICE_LITTLE_ENDIAN: - val = ldl_le_p(ptr); - break; - case DEVICE_BIG_ENDIAN: - val = ldl_be_p(ptr); - break; - default: - val = ldl_p(ptr); - break; - } - r = MEMTX_OK; - } - if (result) { - *result = r; - } - if (release_lock) { - qemu_mutex_unlock_iothread(); - } - rcu_read_unlock(); - return val; -} - -uint32_t address_space_ldl(AddressSpace *as, hwaddr addr, - MemTxAttrs attrs, MemTxResult *result) -{ - return address_space_ldl_internal(as, addr, attrs, result, - DEVICE_NATIVE_ENDIAN); -} - -uint32_t address_space_ldl_le(AddressSpace *as, hwaddr addr, - MemTxAttrs attrs, MemTxResult *result) -{ - return address_space_ldl_internal(as, addr, attrs, result, - DEVICE_LITTLE_ENDIAN); -} - -uint32_t address_space_ldl_be(AddressSpace *as, hwaddr addr, - MemTxAttrs attrs, MemTxResult *result) -{ - return address_space_ldl_internal(as, addr, attrs, result, - DEVICE_BIG_ENDIAN); -} - -uint32_t ldl_phys(AddressSpace *as, hwaddr addr) -{ - return address_space_ldl(as, addr, MEMTXATTRS_UNSPECIFIED, NULL); -} - -uint32_t ldl_le_phys(AddressSpace *as, hwaddr addr) -{ - return address_space_ldl_le(as, addr, MEMTXATTRS_UNSPECIFIED, NULL); -} - -uint32_t ldl_be_phys(AddressSpace *as, hwaddr addr) -{ - return address_space_ldl_be(as, addr, MEMTXATTRS_UNSPECIFIED, NULL); -} - -/* warning: addr must be aligned */ -static inline uint64_t address_space_ldq_internal(AddressSpace *as, hwaddr addr, - MemTxAttrs attrs, - MemTxResult *result, - enum device_endian endian) -{ - uint8_t *ptr; - uint64_t val; - MemoryRegion *mr; - hwaddr l = 8; - hwaddr addr1; - MemTxResult r; - bool release_lock = false; - - rcu_read_lock(); - mr = address_space_translate(as, addr, &addr1, &l, - false); - if (l < 8 || !memory_access_is_direct(mr, false)) { - release_lock |= prepare_mmio_access(mr); - - /* I/O case */ - r = memory_region_dispatch_read(mr, addr1, &val, 8, attrs); -#if defined(TARGET_WORDS_BIGENDIAN) - if (endian == DEVICE_LITTLE_ENDIAN) { - val = bswap64(val); - } -#else - if (endian == DEVICE_BIG_ENDIAN) { - val = bswap64(val); - } -#endif - } else { - /* RAM case */ - ptr = qemu_map_ram_ptr(mr->ram_block, addr1); - switch (endian) { - case DEVICE_LITTLE_ENDIAN: - val = ldq_le_p(ptr); - break; - case DEVICE_BIG_ENDIAN: - val = ldq_be_p(ptr); - break; - default: - val = ldq_p(ptr); - break; - } - r = MEMTX_OK; - } - if (result) { - *result = r; - } - if (release_lock) { - qemu_mutex_unlock_iothread(); - } - rcu_read_unlock(); - return val; -} - -uint64_t address_space_ldq(AddressSpace *as, hwaddr addr, - MemTxAttrs attrs, MemTxResult *result) -{ - return address_space_ldq_internal(as, addr, attrs, result, - DEVICE_NATIVE_ENDIAN); -} - -uint64_t address_space_ldq_le(AddressSpace *as, hwaddr addr, - MemTxAttrs attrs, MemTxResult *result) -{ - return address_space_ldq_internal(as, addr, attrs, result, - DEVICE_LITTLE_ENDIAN); -} - -uint64_t address_space_ldq_be(AddressSpace *as, hwaddr addr, - MemTxAttrs attrs, MemTxResult *result) -{ - return address_space_ldq_internal(as, addr, attrs, result, - DEVICE_BIG_ENDIAN); -} - -uint64_t ldq_phys(AddressSpace *as, hwaddr addr) -{ - return address_space_ldq(as, addr, MEMTXATTRS_UNSPECIFIED, NULL); -} - -uint64_t ldq_le_phys(AddressSpace *as, hwaddr addr) -{ - return address_space_ldq_le(as, addr, MEMTXATTRS_UNSPECIFIED, NULL); -} - -uint64_t ldq_be_phys(AddressSpace *as, hwaddr addr) -{ - return address_space_ldq_be(as, addr, MEMTXATTRS_UNSPECIFIED, NULL); -} - -/* XXX: optimize */ -uint32_t address_space_ldub(AddressSpace *as, hwaddr addr, - MemTxAttrs attrs, MemTxResult *result) -{ - uint8_t val; - MemTxResult r; - - r = address_space_rw(as, addr, attrs, &val, 1, 0); - if (result) { - *result = r; - } - return val; -} - -uint32_t ldub_phys(AddressSpace *as, hwaddr addr) -{ - return address_space_ldub(as, addr, MEMTXATTRS_UNSPECIFIED, NULL); -} - -/* warning: addr must be aligned */ -static inline uint32_t address_space_lduw_internal(AddressSpace *as, - hwaddr addr, - MemTxAttrs attrs, - MemTxResult *result, - enum device_endian endian) -{ - uint8_t *ptr; - uint64_t val; - MemoryRegion *mr; - hwaddr l = 2; - hwaddr addr1; - MemTxResult r; - bool release_lock = false; - - rcu_read_lock(); - mr = address_space_translate(as, addr, &addr1, &l, - false); - if (l < 2 || !memory_access_is_direct(mr, false)) { - release_lock |= prepare_mmio_access(mr); - - /* I/O case */ - r = memory_region_dispatch_read(mr, addr1, &val, 2, attrs); -#if defined(TARGET_WORDS_BIGENDIAN) - if (endian == DEVICE_LITTLE_ENDIAN) { - val = bswap16(val); - } -#else - if (endian == DEVICE_BIG_ENDIAN) { - val = bswap16(val); - } -#endif - } else { - /* RAM case */ - ptr = qemu_map_ram_ptr(mr->ram_block, addr1); - switch (endian) { - case DEVICE_LITTLE_ENDIAN: - val = lduw_le_p(ptr); - break; - case DEVICE_BIG_ENDIAN: - val = lduw_be_p(ptr); - break; - default: - val = lduw_p(ptr); - break; - } - r = MEMTX_OK; - } - if (result) { - *result = r; - } - if (release_lock) { - qemu_mutex_unlock_iothread(); - } - rcu_read_unlock(); - return val; -} - -uint32_t address_space_lduw(AddressSpace *as, hwaddr addr, - MemTxAttrs attrs, MemTxResult *result) -{ - return address_space_lduw_internal(as, addr, attrs, result, - DEVICE_NATIVE_ENDIAN); -} - -uint32_t address_space_lduw_le(AddressSpace *as, hwaddr addr, - MemTxAttrs attrs, MemTxResult *result) -{ - return address_space_lduw_internal(as, addr, attrs, result, - DEVICE_LITTLE_ENDIAN); -} - -uint32_t address_space_lduw_be(AddressSpace *as, hwaddr addr, - MemTxAttrs attrs, MemTxResult *result) -{ - return address_space_lduw_internal(as, addr, attrs, result, - DEVICE_BIG_ENDIAN); -} - -uint32_t lduw_phys(AddressSpace *as, hwaddr addr) -{ - return address_space_lduw(as, addr, MEMTXATTRS_UNSPECIFIED, NULL); -} - -uint32_t lduw_le_phys(AddressSpace *as, hwaddr addr) -{ - return address_space_lduw_le(as, addr, MEMTXATTRS_UNSPECIFIED, NULL); -} - -uint32_t lduw_be_phys(AddressSpace *as, hwaddr addr) -{ - return address_space_lduw_be(as, addr, MEMTXATTRS_UNSPECIFIED, NULL); -} - -/* warning: addr must be aligned. The ram page is not masked as dirty - and the code inside is not invalidated. It is useful if the dirty - bits are used to track modified PTEs */ -void address_space_stl_notdirty(AddressSpace *as, hwaddr addr, uint32_t val, - MemTxAttrs attrs, MemTxResult *result) -{ - uint8_t *ptr; - MemoryRegion *mr; - hwaddr l = 4; - hwaddr addr1; - MemTxResult r; - uint8_t dirty_log_mask; - bool release_lock = false; - - rcu_read_lock(); - mr = address_space_translate(as, addr, &addr1, &l, - true); - if (l < 4 || !memory_access_is_direct(mr, true)) { - release_lock |= prepare_mmio_access(mr); - - r = memory_region_dispatch_write(mr, addr1, val, 4, attrs); - } else { - ptr = qemu_map_ram_ptr(mr->ram_block, addr1); - stl_p(ptr, val); - - dirty_log_mask = memory_region_get_dirty_log_mask(mr); - dirty_log_mask &= ~(1 << DIRTY_MEMORY_CODE); - cpu_physical_memory_set_dirty_range(memory_region_get_ram_addr(mr) + addr, - 4, dirty_log_mask); - r = MEMTX_OK; - } - if (result) { - *result = r; - } - if (release_lock) { - qemu_mutex_unlock_iothread(); - } - rcu_read_unlock(); -} - -void stl_phys_notdirty(AddressSpace *as, hwaddr addr, uint32_t val) -{ - address_space_stl_notdirty(as, addr, val, MEMTXATTRS_UNSPECIFIED, NULL); -} - -/* warning: addr must be aligned */ -static inline void address_space_stl_internal(AddressSpace *as, - hwaddr addr, uint32_t val, - MemTxAttrs attrs, - MemTxResult *result, - enum device_endian endian) -{ - uint8_t *ptr; - MemoryRegion *mr; - hwaddr l = 4; - hwaddr addr1; - MemTxResult r; - bool release_lock = false; - - rcu_read_lock(); - mr = address_space_translate(as, addr, &addr1, &l, - true); - if (l < 4 || !memory_access_is_direct(mr, true)) { - release_lock |= prepare_mmio_access(mr); - -#if defined(TARGET_WORDS_BIGENDIAN) - if (endian == DEVICE_LITTLE_ENDIAN) { - val = bswap32(val); - } -#else - if (endian == DEVICE_BIG_ENDIAN) { - val = bswap32(val); - } -#endif - r = memory_region_dispatch_write(mr, addr1, val, 4, attrs); - } else { - /* RAM case */ - ptr = qemu_map_ram_ptr(mr->ram_block, addr1); - switch (endian) { - case DEVICE_LITTLE_ENDIAN: - stl_le_p(ptr, val); - break; - case DEVICE_BIG_ENDIAN: - stl_be_p(ptr, val); - break; - default: - stl_p(ptr, val); - break; - } - invalidate_and_set_dirty(mr, addr1, 4); - r = MEMTX_OK; - } - if (result) { - *result = r; - } - if (release_lock) { - qemu_mutex_unlock_iothread(); - } - rcu_read_unlock(); -} - -void address_space_stl(AddressSpace *as, hwaddr addr, uint32_t val, - MemTxAttrs attrs, MemTxResult *result) -{ - address_space_stl_internal(as, addr, val, attrs, result, - DEVICE_NATIVE_ENDIAN); -} - -void address_space_stl_le(AddressSpace *as, hwaddr addr, uint32_t val, - MemTxAttrs attrs, MemTxResult *result) -{ - address_space_stl_internal(as, addr, val, attrs, result, - DEVICE_LITTLE_ENDIAN); -} - -void address_space_stl_be(AddressSpace *as, hwaddr addr, uint32_t val, - MemTxAttrs attrs, MemTxResult *result) -{ - address_space_stl_internal(as, addr, val, attrs, result, - DEVICE_BIG_ENDIAN); -} - -void stl_phys(AddressSpace *as, hwaddr addr, uint32_t val) -{ - address_space_stl(as, addr, val, MEMTXATTRS_UNSPECIFIED, NULL); -} - -void stl_le_phys(AddressSpace *as, hwaddr addr, uint32_t val) -{ - address_space_stl_le(as, addr, val, MEMTXATTRS_UNSPECIFIED, NULL); -} - -void stl_be_phys(AddressSpace *as, hwaddr addr, uint32_t val) -{ - address_space_stl_be(as, addr, val, MEMTXATTRS_UNSPECIFIED, NULL); -} - -/* XXX: optimize */ -void address_space_stb(AddressSpace *as, hwaddr addr, uint32_t val, - MemTxAttrs attrs, MemTxResult *result) -{ - uint8_t v = val; - MemTxResult r; - - r = address_space_rw(as, addr, attrs, &v, 1, 1); - if (result) { - *result = r; - } -} - -void stb_phys(AddressSpace *as, hwaddr addr, uint32_t val) -{ - address_space_stb(as, addr, val, MEMTXATTRS_UNSPECIFIED, NULL); -} +#define ARG1_DECL AddressSpace *as +#define ARG1 as +#define SUFFIX +#define TRANSLATE(...) address_space_translate(as, __VA_ARGS__) +#define IS_DIRECT(mr, is_write) memory_access_is_direct(mr, is_write) +#define MAP_RAM(mr, ofs) qemu_map_ram_ptr((mr)->ram_block, ofs) +#define INVALIDATE(mr, ofs, len) invalidate_and_set_dirty(mr, ofs, len) +#define RCU_READ_LOCK(...) rcu_read_lock() +#define RCU_READ_UNLOCK(...) rcu_read_unlock() +#include "memory_ldst.inc.c" -/* warning: addr must be aligned */ -static inline void address_space_stw_internal(AddressSpace *as, - hwaddr addr, uint32_t val, - MemTxAttrs attrs, - MemTxResult *result, - enum device_endian endian) +int64_t address_space_cache_init(MemoryRegionCache *cache, + AddressSpace *as, + hwaddr addr, + hwaddr len, + bool is_write) { - uint8_t *ptr; + hwaddr l, xlat; MemoryRegion *mr; - hwaddr l = 2; - hwaddr addr1; - MemTxResult r; - bool release_lock = false; + void *ptr; - rcu_read_lock(); - mr = address_space_translate(as, addr, &addr1, &l, true); - if (l < 2 || !memory_access_is_direct(mr, true)) { - release_lock |= prepare_mmio_access(mr); + assert(len > 0); -#if defined(TARGET_WORDS_BIGENDIAN) - if (endian == DEVICE_LITTLE_ENDIAN) { - val = bswap16(val); - } -#else - if (endian == DEVICE_BIG_ENDIAN) { - val = bswap16(val); - } -#endif - r = memory_region_dispatch_write(mr, addr1, val, 2, attrs); - } else { - /* RAM case */ - ptr = qemu_map_ram_ptr(mr->ram_block, addr1); - switch (endian) { - case DEVICE_LITTLE_ENDIAN: - stw_le_p(ptr, val); - break; - case DEVICE_BIG_ENDIAN: - stw_be_p(ptr, val); - break; - default: - stw_p(ptr, val); - break; - } - invalidate_and_set_dirty(mr, addr1, 2); - r = MEMTX_OK; - } - if (result) { - *result = r; - } - if (release_lock) { - qemu_mutex_unlock_iothread(); + l = len; + mr = address_space_translate(as, addr, &xlat, &l, is_write); + if (!memory_access_is_direct(mr, is_write)) { + return -EINVAL; } - rcu_read_unlock(); -} - -void address_space_stw(AddressSpace *as, hwaddr addr, uint32_t val, - MemTxAttrs attrs, MemTxResult *result) -{ - address_space_stw_internal(as, addr, val, attrs, result, - DEVICE_NATIVE_ENDIAN); -} -void address_space_stw_le(AddressSpace *as, hwaddr addr, uint32_t val, - MemTxAttrs attrs, MemTxResult *result) -{ - address_space_stw_internal(as, addr, val, attrs, result, - DEVICE_LITTLE_ENDIAN); -} + l = address_space_extend_translation(as, addr, len, mr, xlat, l, is_write); + ptr = qemu_ram_ptr_length(mr->ram_block, xlat, &l); -void address_space_stw_be(AddressSpace *as, hwaddr addr, uint32_t val, - MemTxAttrs attrs, MemTxResult *result) -{ - address_space_stw_internal(as, addr, val, attrs, result, - DEVICE_BIG_ENDIAN); -} + cache->xlat = xlat; + cache->is_write = is_write; + cache->mr = mr; + cache->ptr = ptr; + cache->len = l; + memory_region_ref(cache->mr); -void stw_phys(AddressSpace *as, hwaddr addr, uint32_t val) -{ - address_space_stw(as, addr, val, MEMTXATTRS_UNSPECIFIED, NULL); -} - -void stw_le_phys(AddressSpace *as, hwaddr addr, uint32_t val) -{ - address_space_stw_le(as, addr, val, MEMTXATTRS_UNSPECIFIED, NULL); + return l; } -void stw_be_phys(AddressSpace *as, hwaddr addr, uint32_t val) +void address_space_cache_invalidate(MemoryRegionCache *cache, + hwaddr addr, + hwaddr access_len) { - address_space_stw_be(as, addr, val, MEMTXATTRS_UNSPECIFIED, NULL); + assert(cache->is_write); + invalidate_and_set_dirty(cache->mr, addr + cache->xlat, access_len); } -/* XXX: optimize */ -void address_space_stq(AddressSpace *as, hwaddr addr, uint64_t val, - MemTxAttrs attrs, MemTxResult *result) +void address_space_cache_destroy(MemoryRegionCache *cache) { - MemTxResult r; - val = tswap64(val); - r = address_space_rw(as, addr, attrs, (void *) &val, 8, 1); - if (result) { - *result = r; + if (!cache->mr) { + return; } -} -void address_space_stq_le(AddressSpace *as, hwaddr addr, uint64_t val, - MemTxAttrs attrs, MemTxResult *result) -{ - MemTxResult r; - val = cpu_to_le64(val); - r = address_space_rw(as, addr, attrs, (void *) &val, 8, 1); - if (result) { - *result = r; - } -} -void address_space_stq_be(AddressSpace *as, hwaddr addr, uint64_t val, - MemTxAttrs attrs, MemTxResult *result) -{ - MemTxResult r; - val = cpu_to_be64(val); - r = address_space_rw(as, addr, attrs, (void *) &val, 8, 1); - if (result) { - *result = r; + if (xen_enabled()) { + xen_invalidate_map_cache_entry(cache->ptr); } + memory_region_unref(cache->mr); } -void stq_phys(AddressSpace *as, hwaddr addr, uint64_t val) -{ - address_space_stq(as, addr, val, MEMTXATTRS_UNSPECIFIED, NULL); -} - -void stq_le_phys(AddressSpace *as, hwaddr addr, uint64_t val) -{ - address_space_stq_le(as, addr, val, MEMTXATTRS_UNSPECIFIED, NULL); -} - -void stq_be_phys(AddressSpace *as, hwaddr addr, uint64_t val) -{ - address_space_stq_be(as, addr, val, MEMTXATTRS_UNSPECIFIED, NULL); -} +/* Called from RCU critical section. This function has the same + * semantics as address_space_translate, but it only works on a + * predefined range of a MemoryRegion that was mapped with + * address_space_cache_init. + */ +static inline MemoryRegion *address_space_translate_cached( + MemoryRegionCache *cache, hwaddr addr, hwaddr *xlat, + hwaddr *plen, bool is_write) +{ + assert(addr < cache->len && *plen <= cache->len - addr); + *xlat = addr + cache->xlat; + return cache->mr; +} + +#define ARG1_DECL MemoryRegionCache *cache +#define ARG1 cache +#define SUFFIX _cached +#define TRANSLATE(...) address_space_translate_cached(cache, __VA_ARGS__) +#define IS_DIRECT(mr, is_write) true +#define MAP_RAM(mr, ofs) (cache->ptr + (ofs - cache->xlat)) +#define INVALIDATE(mr, ofs, len) ((void)0) +#define RCU_READ_LOCK() ((void)0) +#define RCU_READ_UNLOCK() ((void)0) +#include "memory_ldst.inc.c" /* virtual memory access for debug (includes writing to ROM) */ int cpu_memory_rw_debug(CPUState *cpu, target_ulong addr, diff --git a/hw/alpha/alpha_sys.h b/hw/alpha/alpha_sys.h index ed911f22a1..b6d8369ed7 100644 --- a/hw/alpha/alpha_sys.h +++ b/hw/alpha/alpha_sys.h @@ -3,7 +3,7 @@ #ifndef HW_ALPHA_SYS_H #define HW_ALPHA_SYS_H -#include "target-alpha/cpu-qom.h" +#include "target/alpha/cpu-qom.h" #include "hw/pci/pci.h" #include "hw/pci/pci_host.h" #include "hw/ide.h" diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c index c7206fda6d..40c13838fb 100644 --- a/hw/arm/aspeed.c +++ b/hw/arm/aspeed.c @@ -34,13 +34,18 @@ typedef struct AspeedBoardState { typedef struct AspeedBoardConfig { const char *soc_name; uint32_t hw_strap1; + const char *fmc_model; + const char *spi_model; + uint32_t num_cs; } AspeedBoardConfig; enum { PALMETTO_BMC, AST2500_EVB, + ROMULUS_BMC, }; +/* Palmetto hardware value: 0x120CE416 */ #define PALMETTO_BMC_HW_STRAP1 ( \ SCU_AST2400_HW_STRAP_DRAM_SIZE(DRAM_SIZE_256MB) | \ SCU_AST2400_HW_STRAP_DRAM_CONFIG(2 /* DDR3 with CL=6, CWL=5 */) | \ @@ -54,6 +59,7 @@ enum { SCU_HW_STRAP_VGA_SIZE_SET(VGA_16M_DRAM) | \ SCU_AST2400_HW_STRAP_BOOT_MODE(AST2400_SPI_BOOT)) +/* AST2500 evb hardware value: 0xF100C2E6 */ #define AST2500_EVB_HW_STRAP1 (( \ AST2500_HW_STRAP1_DEFAULTS | \ SCU_AST2500_HW_STRAP_SPI_AUTOFETCH_ENABLE | \ @@ -64,9 +70,38 @@ enum { SCU_HW_STRAP_MAC0_RGMII) & \ ~SCU_HW_STRAP_2ND_BOOT_WDT) +/* Romulus hardware value: 0xF10AD206 */ +#define ROMULUS_BMC_HW_STRAP1 ( \ + AST2500_HW_STRAP1_DEFAULTS | \ + SCU_AST2500_HW_STRAP_SPI_AUTOFETCH_ENABLE | \ + SCU_AST2500_HW_STRAP_GPIO_STRAP_ENABLE | \ + SCU_AST2500_HW_STRAP_UART_DEBUG | \ + SCU_AST2500_HW_STRAP_DDR4_ENABLE | \ + SCU_AST2500_HW_STRAP_ACPI_ENABLE | \ + SCU_HW_STRAP_SPI_MODE(SCU_HW_STRAP_SPI_MASTER)) + static const AspeedBoardConfig aspeed_boards[] = { - [PALMETTO_BMC] = { "ast2400-a0", PALMETTO_BMC_HW_STRAP1 }, - [AST2500_EVB] = { "ast2500-a1", AST2500_EVB_HW_STRAP1 }, + [PALMETTO_BMC] = { + .soc_name = "ast2400-a1", + .hw_strap1 = PALMETTO_BMC_HW_STRAP1, + .fmc_model = "n25q256a", + .spi_model = "mx25l25635e", + .num_cs = 1, + }, + [AST2500_EVB] = { + .soc_name = "ast2500-a1", + .hw_strap1 = AST2500_EVB_HW_STRAP1, + .fmc_model = "n25q256a", + .spi_model = "mx25l25635e", + .num_cs = 1, + }, + [ROMULUS_BMC] = { + .soc_name = "ast2500-a1", + .hw_strap1 = ROMULUS_BMC_HW_STRAP1, + .fmc_model = "n25q256a", + .spi_model = "mx66l1g45g", + .num_cs = 2, + }, }; static void aspeed_board_init_flashes(AspeedSMCState *s, const char *flashtype, @@ -112,6 +147,8 @@ static void aspeed_board_init(MachineState *machine, &error_abort); object_property_set_int(OBJECT(&bmc->soc), cfg->hw_strap1, "hw-strap1", &error_abort); + object_property_set_int(OBJECT(&bmc->soc), cfg->num_cs, "num-cs", + &error_abort); object_property_set_bool(OBJECT(&bmc->soc), true, "realized", &error_abort); @@ -128,8 +165,8 @@ static void aspeed_board_init(MachineState *machine, object_property_add_const_link(OBJECT(&bmc->soc), "ram", OBJECT(&bmc->ram), &error_abort); - aspeed_board_init_flashes(&bmc->soc.fmc, "n25q256a", &error_abort); - aspeed_board_init_flashes(&bmc->soc.spi[0], "mx25l25635e", &error_abort); + aspeed_board_init_flashes(&bmc->soc.fmc, cfg->fmc_model, &error_abort); + aspeed_board_init_flashes(&bmc->soc.spi[0], cfg->spi_model, &error_abort); aspeed_board_binfo.kernel_filename = machine->kernel_filename; aspeed_board_binfo.initrd_filename = machine->initrd_filename; @@ -188,10 +225,35 @@ static const TypeInfo ast2500_evb_type = { .class_init = ast2500_evb_class_init, }; +static void romulus_bmc_init(MachineState *machine) +{ + aspeed_board_init(machine, &aspeed_boards[ROMULUS_BMC]); +} + +static void romulus_bmc_class_init(ObjectClass *oc, void *data) +{ + MachineClass *mc = MACHINE_CLASS(oc); + + mc->desc = "OpenPOWER Romulus BMC (ARM1176)"; + mc->init = romulus_bmc_init; + mc->max_cpus = 1; + mc->no_sdcard = 1; + mc->no_floppy = 1; + mc->no_cdrom = 1; + mc->no_parallel = 1; +} + +static const TypeInfo romulus_bmc_type = { + .name = MACHINE_TYPE_NAME("romulus-bmc"), + .parent = TYPE_MACHINE, + .class_init = romulus_bmc_class_init, +}; + static void aspeed_machine_init(void) { type_register_static(&palmetto_bmc_type); type_register_static(&ast2500_evb_type); + type_register_static(&romulus_bmc_type); } type_init(aspeed_machine_init) diff --git a/hw/arm/aspeed_soc.c b/hw/arm/aspeed_soc.c index e14f5c217e..b3e7f07b61 100644 --- a/hw/arm/aspeed_soc.c +++ b/hw/arm/aspeed_soc.c @@ -29,6 +29,7 @@ #define ASPEED_SOC_VIC_BASE 0x1E6C0000 #define ASPEED_SOC_SDMC_BASE 0x1E6E0000 #define ASPEED_SOC_SCU_BASE 0x1E6E2000 +#define ASPEED_SOC_SRAM_BASE 0x1E720000 #define ASPEED_SOC_TIMER_BASE 0x1E782000 #define ASPEED_SOC_I2C_BASE 0x1E78A000 @@ -47,15 +48,47 @@ static const char *aspeed_soc_ast2500_typenames[] = { "aspeed.smc.ast2500-spi1", "aspeed.smc.ast2500-spi2" }; static const AspeedSoCInfo aspeed_socs[] = { - { "ast2400-a0", "arm926", AST2400_A0_SILICON_REV, AST2400_SDRAM_BASE, - 1, aspeed_soc_ast2400_spi_bases, - "aspeed.smc.fmc", aspeed_soc_ast2400_typenames }, - { "ast2400", "arm926", AST2400_A0_SILICON_REV, AST2400_SDRAM_BASE, - 1, aspeed_soc_ast2400_spi_bases, - "aspeed.smc.fmc", aspeed_soc_ast2400_typenames }, - { "ast2500-a1", "arm1176", AST2500_A1_SILICON_REV, AST2500_SDRAM_BASE, - 2, aspeed_soc_ast2500_spi_bases, - "aspeed.smc.ast2500-fmc", aspeed_soc_ast2500_typenames }, + { + .name = "ast2400-a0", + .cpu_model = "arm926", + .silicon_rev = AST2400_A0_SILICON_REV, + .sdram_base = AST2400_SDRAM_BASE, + .sram_size = 0x8000, + .spis_num = 1, + .spi_bases = aspeed_soc_ast2400_spi_bases, + .fmc_typename = "aspeed.smc.fmc", + .spi_typename = aspeed_soc_ast2400_typenames, + }, { + .name = "ast2400-a1", + .cpu_model = "arm926", + .silicon_rev = AST2400_A1_SILICON_REV, + .sdram_base = AST2400_SDRAM_BASE, + .sram_size = 0x8000, + .spis_num = 1, + .spi_bases = aspeed_soc_ast2400_spi_bases, + .fmc_typename = "aspeed.smc.fmc", + .spi_typename = aspeed_soc_ast2400_typenames, + }, { + .name = "ast2400", + .cpu_model = "arm926", + .silicon_rev = AST2400_A0_SILICON_REV, + .sdram_base = AST2400_SDRAM_BASE, + .sram_size = 0x8000, + .spis_num = 1, + .spi_bases = aspeed_soc_ast2400_spi_bases, + .fmc_typename = "aspeed.smc.fmc", + .spi_typename = aspeed_soc_ast2400_typenames, + }, { + .name = "ast2500-a1", + .cpu_model = "arm1176", + .silicon_rev = AST2500_A1_SILICON_REV, + .sdram_base = AST2500_SDRAM_BASE, + .sram_size = 0x9000, + .spis_num = 2, + .spi_bases = aspeed_soc_ast2500_spi_bases, + .fmc_typename = "aspeed.smc.ast2500-fmc", + .spi_typename = aspeed_soc_ast2500_typenames, + }, }; /* @@ -87,9 +120,13 @@ static void aspeed_soc_init(Object *obj) { AspeedSoCState *s = ASPEED_SOC(obj); AspeedSoCClass *sc = ASPEED_SOC_GET_CLASS(s); + char *cpu_typename; int i; - s->cpu = cpu_arm_init(sc->info->cpu_model); + cpu_typename = g_strdup_printf("%s-" TYPE_ARM_CPU, sc->info->cpu_model); + object_initialize(&s->cpu, sizeof(s->cpu), cpu_typename); + object_property_add_child(obj, "cpu", OBJECT(&s->cpu), NULL); + g_free(cpu_typename); object_initialize(&s->vic, sizeof(s->vic), TYPE_ASPEED_VIC); object_property_add_child(obj, "vic", OBJECT(&s->vic), NULL); @@ -116,11 +153,13 @@ static void aspeed_soc_init(Object *obj) object_initialize(&s->fmc, sizeof(s->fmc), sc->info->fmc_typename); object_property_add_child(obj, "fmc", OBJECT(&s->fmc), NULL); qdev_set_parent_bus(DEVICE(&s->fmc), sysbus_get_default()); + object_property_add_alias(obj, "num-cs", OBJECT(&s->fmc), "num-cs", + &error_abort); for (i = 0; i < sc->info->spis_num; i++) { object_initialize(&s->spi[i], sizeof(s->spi[i]), sc->info->spi_typename[i]); - object_property_add_child(obj, "spi", OBJECT(&s->spi[i]), NULL); + object_property_add_child(obj, "spi[*]", OBJECT(&s->spi[i]), NULL); qdev_set_parent_bus(DEVICE(&s->spi[i]), sysbus_get_default()); } @@ -146,6 +185,24 @@ static void aspeed_soc_realize(DeviceState *dev, Error **errp) memory_region_add_subregion_overlap(get_system_memory(), ASPEED_SOC_IOMEM_BASE, &s->iomem, -1); + /* CPU */ + object_property_set_bool(OBJECT(&s->cpu), true, "realized", &err); + if (err) { + error_propagate(errp, err); + return; + } + + /* SRAM */ + memory_region_init_ram(&s->sram, OBJECT(dev), "aspeed.sram", + sc->info->sram_size, &err); + if (err) { + error_propagate(errp, err); + return; + } + vmstate_register_ram_global(&s->sram); + memory_region_add_subregion(get_system_memory(), ASPEED_SOC_SRAM_BASE, + &s->sram); + /* VIC */ object_property_set_bool(OBJECT(&s->vic), true, "realized", &err); if (err) { @@ -154,9 +211,9 @@ static void aspeed_soc_realize(DeviceState *dev, Error **errp) } sysbus_mmio_map(SYS_BUS_DEVICE(&s->vic), 0, ASPEED_SOC_VIC_BASE); sysbus_connect_irq(SYS_BUS_DEVICE(&s->vic), 0, - qdev_get_gpio_in(DEVICE(s->cpu), ARM_CPU_IRQ)); + qdev_get_gpio_in(DEVICE(&s->cpu), ARM_CPU_IRQ)); sysbus_connect_irq(SYS_BUS_DEVICE(&s->vic), 1, - qdev_get_gpio_in(DEVICE(s->cpu), ARM_CPU_FIQ)); + qdev_get_gpio_in(DEVICE(&s->cpu), ARM_CPU_FIQ)); /* Timer */ object_property_set_bool(OBJECT(&s->timerctrl), true, "realized", &err); @@ -195,10 +252,8 @@ static void aspeed_soc_realize(DeviceState *dev, Error **errp) sysbus_connect_irq(SYS_BUS_DEVICE(&s->i2c), 0, qdev_get_gpio_in(DEVICE(&s->vic), 12)); - /* FMC */ - object_property_set_int(OBJECT(&s->fmc), 1, "num-cs", &err); - object_property_set_bool(OBJECT(&s->fmc), true, "realized", &local_err); - error_propagate(&err, local_err); + /* FMC, The number of CS is set at the board level */ + object_property_set_bool(OBJECT(&s->fmc), true, "realized", &err); if (err) { error_propagate(errp, err); return; @@ -240,12 +295,6 @@ static void aspeed_soc_class_init(ObjectClass *oc, void *data) sc->info = (AspeedSoCInfo *) data; dc->realize = aspeed_soc_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 aspeed_soc_type_info = { diff --git a/hw/arm/pxa2xx.c b/hw/arm/pxa2xx.c index 21ea1d6210..bdcf6bcce7 100644 --- a/hw/arm/pxa2xx.c +++ b/hw/arm/pxa2xx.c @@ -1449,17 +1449,10 @@ static const VMStateDescription vmstate_pxa2xx_i2c = { } }; -static int pxa2xx_i2c_slave_init(I2CSlave *i2c) -{ - /* Nothing to do. */ - return 0; -} - static void pxa2xx_i2c_slave_class_init(ObjectClass *klass, void *data) { I2CSlaveClass *k = I2C_SLAVE_CLASS(klass); - k->init = pxa2xx_i2c_slave_init; k->event = pxa2xx_i2c_event; k->recv = pxa2xx_i2c_rx; k->send = pxa2xx_i2c_tx; @@ -2070,7 +2063,7 @@ PXA2xxState *pxa270_init(MemoryRegion *address_space, } if (!revision) revision = "pxa270"; - + s->cpu = cpu_arm_init(revision); if (s->cpu == NULL) { fprintf(stderr, "Unable to find CPU definition\n"); diff --git a/hw/arm/strongarm.h b/hw/arm/strongarm.h index 1470eac4f5..e98840b461 100644 --- a/hw/arm/strongarm.h +++ b/hw/arm/strongarm.h @@ -2,7 +2,7 @@ #define STRONGARM_H #include "exec/memory.h" -#include "target-arm/cpu-qom.h" +#include "target/arm/cpu-qom.h" #define SA_CS0 0x00000000 #define SA_CS1 0x08000000 diff --git a/hw/arm/tosa.c b/hw/arm/tosa.c index 1ee12f49b3..39d9dbbae6 100644 --- a/hw/arm/tosa.c +++ b/hw/arm/tosa.c @@ -202,12 +202,6 @@ static int tosa_dac_recv(I2CSlave *s) return -1; } -static int tosa_dac_init(I2CSlave *i2c) -{ - /* Nothing to do. */ - return 0; -} - static void tosa_tg_init(PXA2xxState *cpu) { I2CBus *bus = pxa2xx_i2c_bus(cpu->i2c[0]); @@ -275,7 +269,6 @@ static void tosa_dac_class_init(ObjectClass *klass, void *data) { I2CSlaveClass *k = I2C_SLAVE_CLASS(klass); - k->init = tosa_dac_init; k->event = tosa_dac_event; k->recv = tosa_dac_recv; k->send = tosa_dac_send; diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c index d4160dfa7d..7102686882 100644 --- a/hw/arm/virt-acpi-build.c +++ b/hw/arm/virt-acpi-build.c @@ -33,7 +33,7 @@ #include "qemu/bitmap.h" #include "trace.h" #include "qom/cpu.h" -#include "target-arm/cpu.h" +#include "target/arm/cpu.h" #include "hw/acpi/acpi-defs.h" #include "hw/acpi/acpi.h" #include "hw/nvram/fw_cfg.h" diff --git a/hw/arm/virt.c b/hw/arm/virt.c index d04e4acbd9..11c53a56e0 100644 --- a/hw/arm/virt.c +++ b/hw/arm/virt.c @@ -1525,7 +1525,7 @@ static void machvirt_machine_init(void) } type_init(machvirt_machine_init); -static void virt_2_8_instance_init(Object *obj) +static void virt_2_9_instance_init(Object *obj) { VirtMachineState *vms = VIRT_MACHINE(obj); @@ -1558,10 +1558,25 @@ static void virt_2_8_instance_init(Object *obj) "Valid values are 2, 3 and host", NULL); } +static void virt_machine_2_9_options(MachineClass *mc) +{ +} +DEFINE_VIRT_MACHINE_AS_LATEST(2, 9) + +#define VIRT_COMPAT_2_8 \ + HW_COMPAT_2_8 + +static void virt_2_8_instance_init(Object *obj) +{ + virt_2_9_instance_init(obj); +} + static void virt_machine_2_8_options(MachineClass *mc) { + virt_machine_2_9_options(mc); + SET_MACHINE_COMPAT(mc, VIRT_COMPAT_2_8); } -DEFINE_VIRT_MACHINE_AS_LATEST(2, 8) +DEFINE_VIRT_MACHINE(2, 8) #define VIRT_COMPAT_2_7 \ HW_COMPAT_2_7 diff --git a/hw/arm/z2.c b/hw/arm/z2.c index 68a92f3184..b3a6bbd210 100644 --- a/hw/arm/z2.c +++ b/hw/arm/z2.c @@ -263,12 +263,6 @@ static int aer915_recv(I2CSlave *slave) return retval; } -static int aer915_init(I2CSlave *i2c) -{ - /* Nothing to do. */ - return 0; -} - static VMStateDescription vmstate_aer915_state = { .name = "aer915", .version_id = 1, @@ -285,7 +279,6 @@ static void aer915_class_init(ObjectClass *klass, void *data) DeviceClass *dc = DEVICE_CLASS(klass); I2CSlaveClass *k = I2C_SLAVE_CLASS(klass); - k->init = aer915_init; k->event = aer915_event; k->recv = aer915_recv; k->send = aer915_send; diff --git a/hw/block/m25p80.c b/hw/block/m25p80.c index d29ff4cb4f..e3c1166ea6 100644 --- a/hw/block/m25p80.c +++ b/hw/block/m25p80.c @@ -203,6 +203,7 @@ static const FlashPartInfo known_devices[] = { { INFO("mx25l25655e", 0xc22619, 0, 64 << 10, 512, 0) }, { INFO("mx66u51235f", 0xc2253a, 0, 64 << 10, 1024, ER_4K | ER_32K) }, { INFO("mx66u1g45g", 0xc2253b, 0, 64 << 10, 2048, ER_4K | ER_32K) }, + { INFO("mx66l1g45g", 0xc2201b, 0, 64 << 10, 2048, ER_4K | ER_32K) }, /* Micron */ { INFO("n25q032a11", 0x20bb16, 0, 64 << 10, 64, ER_4K) }, diff --git a/hw/block/pflash_cfi01.c b/hw/block/pflash_cfi01.c index 62d7a5661d..5f0ee9db00 100644 --- a/hw/block/pflash_cfi01.c +++ b/hw/block/pflash_cfi01.c @@ -707,6 +707,19 @@ static void pflash_cfi01_realize(DeviceState *dev, Error **errp) int num_devices; Error *local_err = NULL; + if (pfl->sector_len == 0) { + error_setg(errp, "attribute \"sector-length\" not specified or zero."); + return; + } + if (pfl->nb_blocs == 0) { + error_setg(errp, "attribute \"num-blocks\" not specified or zero."); + return; + } + if (pfl->name == NULL) { + error_setg(errp, "attribute \"name\" not specified."); + return; + } + total_len = pfl->sector_len * pfl->nb_blocs; /* These are only used to expose the parameters of each device diff --git a/hw/block/pflash_cfi02.c b/hw/block/pflash_cfi02.c index 4f6105cc58..ef71322759 100644 --- a/hw/block/pflash_cfi02.c +++ b/hw/block/pflash_cfi02.c @@ -600,6 +600,19 @@ static void pflash_cfi02_realize(DeviceState *dev, Error **errp) int ret; Error *local_err = NULL; + if (pfl->sector_len == 0) { + error_setg(errp, "attribute \"sector-length\" not specified or zero."); + return; + } + if (pfl->nb_blocs == 0) { + error_setg(errp, "attribute \"num-blocks\" not specified or zero."); + return; + } + if (pfl->name == NULL) { + error_setg(errp, "attribute \"name\" not specified."); + return; + } + chip_len = pfl->sector_len * pfl->nb_blocs; /* XXX: to be fixed */ #if 0 diff --git a/hw/char/cadence_uart.c b/hw/char/cadence_uart.c index 0215d6518d..4dcee571c0 100644 --- a/hw/char/cadence_uart.c +++ b/hw/char/cadence_uart.c @@ -138,9 +138,10 @@ static void fifo_trigger_update(void *opaque) { CadenceUARTState *s = opaque; - s->r[R_CISR] |= UART_INTR_TIMEOUT; - - uart_update_status(s); + if (s->r[R_RTOR]) { + s->r[R_CISR] |= UART_INTR_TIMEOUT; + uart_update_status(s); + } } static void uart_rx_reset(CadenceUARTState *s) @@ -502,6 +503,13 @@ static int cadence_uart_post_load(void *opaque, int version_id) { CadenceUARTState *s = opaque; + /* Ensure these two aren't invalid numbers */ + if (s->r[R_BRGR] < 1 || s->r[R_BRGR] & ~0xFFFF || + s->r[R_BDIV] <= 3 || s->r[R_BDIV] & ~0xFF) { + /* Value is invalid, abort */ + return 1; + } + uart_parameters_setup(s); uart_update_status(s); return 0; diff --git a/hw/i2c/core.c b/hw/i2c/core.c index abd4c4cddb..e40781ea3b 100644 --- a/hw/i2c/core.c +++ b/hw/i2c/core.c @@ -260,7 +260,11 @@ static int i2c_slave_qdev_init(DeviceState *dev) I2CSlave *s = I2C_SLAVE(dev); I2CSlaveClass *sc = I2C_SLAVE_GET_CLASS(s); - return sc->init(s); + if (sc->init) { + return sc->init(s); + } + + return 0; } DeviceState *i2c_create_slave(I2CBus *bus, const char *name, uint8_t addr) diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c index 9708cdc463..42ecf619d5 100644 --- a/hw/i386/acpi-build.c +++ b/hw/i386/acpi-build.c @@ -29,7 +29,7 @@ #include "hw/pci/pci.h" #include "qom/cpu.h" #include "hw/i386/pc.h" -#include "target-i386/cpu.h" +#include "target/i386/cpu.h" #include "hw/timer/hpet.h" #include "hw/acpi/acpi-defs.h" #include "hw/acpi/acpi.h" diff --git a/hw/i386/kvm/apic.c b/hw/i386/kvm/apic.c index 01cbaa88d2..df5180b1e0 100644 --- a/hw/i386/kvm/apic.c +++ b/hw/i386/kvm/apic.c @@ -15,7 +15,7 @@ #include "hw/i386/apic_internal.h" #include "hw/pci/msi.h" #include "sysemu/kvm.h" -#include "target-i386/kvm_i386.h" +#include "target/i386/kvm_i386.h" static inline void kvm_apic_set_reg(struct kvm_lapic_state *kapic, int reg_id, uint32_t val) diff --git a/hw/i386/kvm/clock.c b/hw/i386/kvm/clock.c index 0f75dd385a..ef9d560f9c 100644 --- a/hw/i386/kvm/clock.c +++ b/hw/i386/kvm/clock.c @@ -36,6 +36,13 @@ typedef struct KVMClockState { uint64_t clock; bool clock_valid; + + /* whether machine type supports reliable KVM_GET_CLOCK */ + bool mach_use_reliable_get_clock; + + /* whether the 'clock' value was obtained in a host with + * reliable KVM_GET_CLOCK */ + bool clock_is_reliable; } KVMClockState; struct pvclock_vcpu_time_info { @@ -81,6 +88,60 @@ static uint64_t kvmclock_current_nsec(KVMClockState *s) return nsec + time.system_time; } +static void kvm_update_clock(KVMClockState *s) +{ + struct kvm_clock_data data; + int ret; + + ret = kvm_vm_ioctl(kvm_state, KVM_GET_CLOCK, &data); + if (ret < 0) { + fprintf(stderr, "KVM_GET_CLOCK failed: %s\n", strerror(ret)); + abort(); + } + s->clock = data.clock; + + /* If kvm_has_adjust_clock_stable() is false, KVM_GET_CLOCK returns + * essentially CLOCK_MONOTONIC plus a guest-specific adjustment. This + * can drift from the TSC-based value that is computed by the guest, + * so we need to go through kvmclock_current_nsec(). If + * kvm_has_adjust_clock_stable() is true, and the flags contain + * KVM_CLOCK_TSC_STABLE, then KVM_GET_CLOCK returns a TSC-based value + * and kvmclock_current_nsec() is not necessary. + * + * Here, however, we need not check KVM_CLOCK_TSC_STABLE. This is because: + * + * - if the host has disabled the kvmclock master clock, the guest already + * has protection against time going backwards. This "safety net" is only + * absent when kvmclock is stable; + * + * - therefore, we can replace a check like + * + * if last KVM_GET_CLOCK was not reliable then + * read from memory + * + * with + * + * if last KVM_GET_CLOCK was not reliable && masterclock is enabled + * read from memory + * + * However: + * + * - if kvm_has_adjust_clock_stable() returns false, the left side is + * always true (KVM_GET_CLOCK is never reliable), and the right side is + * unknown (because we don't have data.flags). We must assume it's true + * and read from memory. + * + * - if kvm_has_adjust_clock_stable() returns true, the result of the && + * is always false (masterclock is enabled iff KVM_GET_CLOCK is reliable) + * + * So we can just use this instead: + * + * if !kvm_has_adjust_clock_stable() then + * read from memory + */ + s->clock_is_reliable = kvm_has_adjust_clock_stable(); +} + static void kvmclock_vm_state_change(void *opaque, int running, RunState state) { @@ -91,15 +152,21 @@ static void kvmclock_vm_state_change(void *opaque, int running, if (running) { struct kvm_clock_data data = {}; - uint64_t time_at_migration = kvmclock_current_nsec(s); - - s->clock_valid = false; - /* We can't rely on the migrated clock value, just discard it */ - if (time_at_migration) { - s->clock = time_at_migration; + /* + * If the host where s->clock was read did not support reliable + * KVM_GET_CLOCK, read kvmclock value from memory. + */ + if (!s->clock_is_reliable) { + uint64_t pvclock_via_mem = kvmclock_current_nsec(s); + /* We can't rely on the saved clock value, just discard it */ + if (pvclock_via_mem) { + s->clock = pvclock_via_mem; + } } + s->clock_valid = false; + data.clock = s->clock; ret = kvm_vm_ioctl(kvm_state, KVM_SET_CLOCK, &data); if (ret < 0) { @@ -120,8 +187,6 @@ static void kvmclock_vm_state_change(void *opaque, int running, } } } else { - struct kvm_clock_data data; - int ret; if (s->clock_valid) { return; @@ -129,13 +194,7 @@ static void kvmclock_vm_state_change(void *opaque, int running, kvm_synchronize_all_tsc(); - ret = kvm_vm_ioctl(kvm_state, KVM_GET_CLOCK, &data); - if (ret < 0) { - fprintf(stderr, "KVM_GET_CLOCK failed: %s\n", strerror(ret)); - abort(); - } - s->clock = data.clock; - + kvm_update_clock(s); /* * If the VM is stopped, declare the clock state valid to * avoid re-reading it on next vmsave (which would return @@ -149,25 +208,78 @@ static void kvmclock_realize(DeviceState *dev, Error **errp) { KVMClockState *s = KVM_CLOCK(dev); + kvm_update_clock(s); + qemu_add_vm_change_state_handler(kvmclock_vm_state_change, s); } +static bool kvmclock_clock_is_reliable_needed(void *opaque) +{ + KVMClockState *s = opaque; + + return s->mach_use_reliable_get_clock; +} + +static const VMStateDescription kvmclock_reliable_get_clock = { + .name = "kvmclock/clock_is_reliable", + .version_id = 1, + .minimum_version_id = 1, + .needed = kvmclock_clock_is_reliable_needed, + .fields = (VMStateField[]) { + VMSTATE_BOOL(clock_is_reliable, KVMClockState), + VMSTATE_END_OF_LIST() + } +}; + +/* + * When migrating, read the clock just before migration, + * so that the guest clock counts during the events + * between: + * + * * vm_stop() + * * + * * pre_save() + * + * This reduces kvmclock difference on migration from 5s + * to 0.1s (when max_downtime == 5s), because sending the + * final pages of memory (which happens between vm_stop() + * and pre_save()) takes max_downtime. + */ +static void kvmclock_pre_save(void *opaque) +{ + KVMClockState *s = opaque; + + kvm_update_clock(s); +} + static const VMStateDescription kvmclock_vmsd = { .name = "kvmclock", .version_id = 1, .minimum_version_id = 1, + .pre_save = kvmclock_pre_save, .fields = (VMStateField[]) { VMSTATE_UINT64(clock, KVMClockState), VMSTATE_END_OF_LIST() + }, + .subsections = (const VMStateDescription * []) { + &kvmclock_reliable_get_clock, + NULL } }; +static Property kvmclock_properties[] = { + DEFINE_PROP_BOOL("x-mach-use-reliable-get-clock", KVMClockState, + mach_use_reliable_get_clock, true), + DEFINE_PROP_END_OF_LIST(), +}; + static void kvmclock_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); dc->realize = kvmclock_realize; dc->vmsd = &kvmclock_vmsd; + dc->props = kvmclock_properties; } static const TypeInfo kvmclock_info = { diff --git a/hw/i386/multiboot.c b/hw/i386/multiboot.c index 387caa67d4..f13e23139b 100644 --- a/hw/i386/multiboot.c +++ b/hw/i386/multiboot.c @@ -109,7 +109,7 @@ static uint32_t mb_add_cmdline(MultibootState *s, const char *cmdline) hwaddr p = s->offset_cmdlines; char *b = (char *)s->mb_buf + p; - get_opt_value(b, strlen(cmdline) + 1, cmdline); + memcpy(b, cmdline, strlen(cmdline) + 1); s->offset_cmdlines += strlen(b) + 1; return s->mb_buf_phys + p; } @@ -287,7 +287,8 @@ int load_multiboot(FWCfgState *fw_cfg, mbs.offset_bootloader = mbs.offset_cmdlines + cmdline_len; if (initrd_filename) { - char *next_initrd, not_last; + const char *next_initrd; + char not_last, tmpbuf[strlen(initrd_filename) + 1]; mbs.offset_mods = mbs.mb_buf_size; @@ -296,25 +297,24 @@ int load_multiboot(FWCfgState *fw_cfg, int mb_mod_length; uint32_t offs = mbs.mb_buf_size; - next_initrd = (char *)get_opt_value(NULL, 0, initrd_filename); + next_initrd = get_opt_value(tmpbuf, sizeof(tmpbuf), initrd_filename); not_last = *next_initrd; - *next_initrd = '\0'; /* if a space comes after the module filename, treat everything after that as parameters */ - hwaddr c = mb_add_cmdline(&mbs, initrd_filename); - if ((next_space = strchr(initrd_filename, ' '))) + hwaddr c = mb_add_cmdline(&mbs, tmpbuf); + if ((next_space = strchr(tmpbuf, ' '))) *next_space = '\0'; - mb_debug("multiboot loading module: %s\n", initrd_filename); - mb_mod_length = get_image_size(initrd_filename); + mb_debug("multiboot loading module: %s\n", tmpbuf); + mb_mod_length = get_image_size(tmpbuf); if (mb_mod_length < 0) { - fprintf(stderr, "Failed to open file '%s'\n", initrd_filename); + fprintf(stderr, "Failed to open file '%s'\n", tmpbuf); exit(1); } mbs.mb_buf_size = TARGET_PAGE_ALIGN(mb_mod_length + mbs.mb_buf_size); mbs.mb_buf = g_realloc(mbs.mb_buf, mbs.mb_buf_size); - load_image(initrd_filename, (unsigned char *)mbs.mb_buf + offs); + load_image(tmpbuf, (unsigned char *)mbs.mb_buf + offs); mb_add_mod(&mbs, mbs.mb_buf_phys + offs, mbs.mb_buf_phys + offs + mb_mod_length, c); diff --git a/hw/i386/pc.c b/hw/i386/pc.c index a9e64a88e5..25e8586b48 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -400,13 +400,13 @@ static void pc_cmos_init_late(void *opaque) int i, trans; val = 0; - if (ide_get_geometry(arg->idebus[0], 0, - &cylinders, &heads, §ors) >= 0) { + if (arg->idebus[0] && ide_get_geometry(arg->idebus[0], 0, + &cylinders, &heads, §ors) >= 0) { cmos_init_hd(s, 0x19, 0x1b, cylinders, heads, sectors); val |= 0xf0; } - if (ide_get_geometry(arg->idebus[0], 1, - &cylinders, &heads, §ors) >= 0) { + if (arg->idebus[0] && ide_get_geometry(arg->idebus[0], 1, + &cylinders, &heads, §ors) >= 0) { cmos_init_hd(s, 0x1a, 0x24, cylinders, heads, sectors); val |= 0x0f; } @@ -418,7 +418,8 @@ static void pc_cmos_init_late(void *opaque) geometry. It is always such that: 1 <= sects <= 63, 1 <= heads <= 16, 1 <= cylinders <= 16383. The BIOS geometry can be different if a translation is done. */ - if (ide_get_geometry(arg->idebus[i / 2], i % 2, + if (arg->idebus[i / 2] && + ide_get_geometry(arg->idebus[i / 2], i % 2, &cylinders, &heads, §ors) >= 0) { trans = ide_get_bios_chs_trans(arg->idebus[i / 2], i % 2) - 1; assert((trans & ~3) == 0); @@ -1535,6 +1536,7 @@ void pc_basic_device_init(ISABus *isa_bus, qemu_irq *gsi, ISADevice **rtc_state, bool create_fdctrl, bool no_vmport, + bool has_pit, uint32_t hpet_irqs) { int i; @@ -1588,7 +1590,7 @@ void pc_basic_device_init(ISABus *isa_bus, qemu_irq *gsi, qemu_register_boot_set(pc_boot_set, *rtc_state); - if (!xen_enabled()) { + if (!xen_enabled() && has_pit) { if (kvm_pit_in_kernel()) { pit = kvm_pit_init(isa_bus, 0x40); } else { @@ -2158,6 +2160,48 @@ static void pc_machine_set_nvdimm(Object *obj, bool value, Error **errp) pcms->acpi_nvdimm_state.is_enabled = value; } +static bool pc_machine_get_smbus(Object *obj, Error **errp) +{ + PCMachineState *pcms = PC_MACHINE(obj); + + return pcms->smbus; +} + +static void pc_machine_set_smbus(Object *obj, bool value, Error **errp) +{ + PCMachineState *pcms = PC_MACHINE(obj); + + pcms->smbus = value; +} + +static bool pc_machine_get_sata(Object *obj, Error **errp) +{ + PCMachineState *pcms = PC_MACHINE(obj); + + return pcms->sata; +} + +static void pc_machine_set_sata(Object *obj, bool value, Error **errp) +{ + PCMachineState *pcms = PC_MACHINE(obj); + + pcms->sata = value; +} + +static bool pc_machine_get_pit(Object *obj, Error **errp) +{ + PCMachineState *pcms = PC_MACHINE(obj); + + return pcms->pit; +} + +static void pc_machine_set_pit(Object *obj, bool value, Error **errp) +{ + PCMachineState *pcms = PC_MACHINE(obj); + + pcms->pit = value; +} + static void pc_machine_initfn(Object *obj) { PCMachineState *pcms = PC_MACHINE(obj); @@ -2169,6 +2213,9 @@ static void pc_machine_initfn(Object *obj) pcms->acpi_nvdimm_state.is_enabled = false; /* acpi build is enabled by default if machine supports it */ pcms->acpi_build_enabled = PC_MACHINE_GET_CLASS(pcms)->has_acpi_build; + pcms->smbus = true; + pcms->sata = true; + pcms->pit = true; } static void pc_machine_reset(void) @@ -2329,6 +2376,15 @@ static void pc_machine_class_init(ObjectClass *oc, void *data) object_class_property_add_bool(oc, PC_MACHINE_NVDIMM, pc_machine_get_nvdimm, pc_machine_set_nvdimm, &error_abort); + + object_class_property_add_bool(oc, PC_MACHINE_SMBUS, + pc_machine_get_smbus, pc_machine_set_smbus, &error_abort); + + object_class_property_add_bool(oc, PC_MACHINE_SATA, + pc_machine_get_sata, pc_machine_set_sata, &error_abort); + + object_class_property_add_bool(oc, PC_MACHINE_PIT, + pc_machine_get_pit, pc_machine_set_pit, &error_abort); } static const TypeInfo pc_machine_info = { diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c index a54a468c0a..5e1adbe53c 100644 --- a/hw/i386/pc_piix.c +++ b/hw/i386/pc_piix.c @@ -235,7 +235,7 @@ static void pc_init1(MachineState *machine, /* init basic PC hardware */ pc_basic_device_init(isa_bus, pcms->gsi, &rtc_state, true, - (pcms->vmport != ON_OFF_AUTO_ON), 0x4); + (pcms->vmport != ON_OFF_AUTO_ON), pcms->pit, 0x4); pc_nic_init(isa_bus, pci_bus); diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c index b40d19ee00..d042fe0843 100644 --- a/hw/i386/pc_q35.c +++ b/hw/i386/pc_q35.c @@ -227,32 +227,39 @@ static void pc_q35_init(MachineState *machine) /* init basic PC hardware */ pc_basic_device_init(isa_bus, pcms->gsi, &rtc_state, !mc->no_floppy, - (pcms->vmport != ON_OFF_AUTO_ON), 0xff0104); + (pcms->vmport != ON_OFF_AUTO_ON), pcms->pit, + 0xff0104); /* connect pm stuff to lpc */ ich9_lpc_pm_init(lpc, pc_machine_is_smm_enabled(pcms)); - /* ahci and SATA device, for q35 1 ahci controller is built-in */ - ahci = pci_create_simple_multifunction(host_bus, - PCI_DEVFN(ICH9_SATA1_DEV, - ICH9_SATA1_FUNC), - true, "ich9-ahci"); - idebus[0] = qdev_get_child_bus(&ahci->qdev, "ide.0"); - idebus[1] = qdev_get_child_bus(&ahci->qdev, "ide.1"); - g_assert(MAX_SATA_PORTS == ICH_AHCI(ahci)->ahci.ports); - ide_drive_get(hd, ICH_AHCI(ahci)->ahci.ports); - ahci_ide_create_devs(ahci, hd); + if (pcms->sata) { + /* ahci and SATA device, for q35 1 ahci controller is built-in */ + ahci = pci_create_simple_multifunction(host_bus, + PCI_DEVFN(ICH9_SATA1_DEV, + ICH9_SATA1_FUNC), + true, "ich9-ahci"); + idebus[0] = qdev_get_child_bus(&ahci->qdev, "ide.0"); + idebus[1] = qdev_get_child_bus(&ahci->qdev, "ide.1"); + g_assert(MAX_SATA_PORTS == ICH_AHCI(ahci)->ahci.ports); + ide_drive_get(hd, ICH_AHCI(ahci)->ahci.ports); + ahci_ide_create_devs(ahci, hd); + } else { + idebus[0] = idebus[1] = NULL; + } if (machine_usb(machine)) { /* Should we create 6 UHCI according to ich9 spec? */ ehci_create_ich9_with_companions(host_bus, 0x1d); } - /* TODO: Populate SPD eeprom data. */ - smbus_eeprom_init(ich9_smb_init(host_bus, - PCI_DEVFN(ICH9_SMB_DEV, ICH9_SMB_FUNC), - 0xb100), - 8, NULL, 0); + if (pcms->smbus) { + /* TODO: Populate SPD eeprom data. */ + smbus_eeprom_init(ich9_smb_init(host_bus, + PCI_DEVFN(ICH9_SMB_DEV, ICH9_SMB_FUNC), + 0xb100), + 8, NULL, 0); + } pc_cmos_init(pcms, idebus[0], idebus[1], rtc_state); diff --git a/hw/intc/arm_gicv3.c b/hw/intc/arm_gicv3.c index 8a6c647219..f0c967b304 100644 --- a/hw/intc/arm_gicv3.c +++ b/hw/intc/arm_gicv3.c @@ -54,6 +54,7 @@ static uint32_t gicd_int_pending(GICv3State *s, int irq) * + the PENDING latch is set OR it is level triggered and the input is 1 * + its ENABLE bit is set * + the GICD enable bit for its group is set + * + its ACTIVE bit is not set (otherwise it would be Active+Pending) * Conveniently we can bulk-calculate this with bitwise operations. */ uint32_t pend, grpmask; @@ -63,9 +64,11 @@ static uint32_t gicd_int_pending(GICv3State *s, int irq) uint32_t group = *gic_bmp_ptr32(s->group, irq); uint32_t grpmod = *gic_bmp_ptr32(s->grpmod, irq); uint32_t enable = *gic_bmp_ptr32(s->enabled, irq); + uint32_t active = *gic_bmp_ptr32(s->active, irq); pend = pending | (~edge_trigger & level); pend &= enable; + pend &= ~active; if (s->gicd_ctlr & GICD_CTLR_DS) { grpmod = 0; @@ -96,12 +99,14 @@ static uint32_t gicr_int_pending(GICv3CPUState *cs) * + the PENDING latch is set OR it is level triggered and the input is 1 * + its ENABLE bit is set * + the GICD enable bit for its group is set + * + its ACTIVE bit is not set (otherwise it would be Active+Pending) * Conveniently we can bulk-calculate this with bitwise operations. */ uint32_t pend, grpmask, grpmod; pend = cs->gicr_ipendr0 | (~cs->edge_trigger & cs->level); pend &= cs->gicr_ienabler0; + pend &= ~cs->gicr_iactiver0; if (cs->gic->gicd_ctlr & GICD_CTLR_DS) { grpmod = 0; diff --git a/hw/intc/arm_gicv3_common.c b/hw/intc/arm_gicv3_common.c index 0f8c4b86e0..0aa9b9ca66 100644 --- a/hw/intc/arm_gicv3_common.c +++ b/hw/intc/arm_gicv3_common.c @@ -204,7 +204,8 @@ static void arm_gicv3_common_realize(DeviceState *dev, Error **errp) /* The CPU mp-affinity property is in MPIDR register format; squash * the affinity bytes into 32 bits as the GICR_TYPER has them. */ - cpu_affid = (cpu_affid & 0xFF00000000ULL >> 8) | (cpu_affid & 0xFFFFFF); + cpu_affid = ((cpu_affid & 0xFF00000000ULL) >> 8) | + (cpu_affid & 0xFFFFFF); s->cpu[i].gicr_typer = (cpu_affid << 32) | (1 << 24) | (i << 8) | diff --git a/hw/intc/arm_gicv3_cpuif.c b/hw/intc/arm_gicv3_cpuif.c index bca30c49da..35e8eb30fc 100644 --- a/hw/intc/arm_gicv3_cpuif.c +++ b/hw/intc/arm_gicv3_cpuif.c @@ -1118,35 +1118,35 @@ static const ARMCPRegInfo gicv3_cpuif_reginfo[] = { .opc0 = 3, .opc1 = 0, .crn = 12, .crm = 8, .opc2 = 3, .type = ARM_CP_IO | ARM_CP_NO_RAW, .access = PL1_RW, .accessfn = gicv3_fiq_access, - .fieldoffset = offsetof(GICv3CPUState, icc_bpr[GICV3_G0]), + .readfn = icc_bpr_read, .writefn = icc_bpr_write, }, { .name = "ICC_AP0R0_EL1", .state = ARM_CP_STATE_BOTH, .opc0 = 3, .opc1 = 0, .crn = 12, .crm = 8, .opc2 = 4, .type = ARM_CP_IO | ARM_CP_NO_RAW, .access = PL1_RW, .accessfn = gicv3_fiq_access, - .fieldoffset = offsetof(GICv3CPUState, icc_apr[GICV3_G0][0]), + .readfn = icc_ap_read, .writefn = icc_ap_write, }, { .name = "ICC_AP0R1_EL1", .state = ARM_CP_STATE_BOTH, .opc0 = 3, .opc1 = 0, .crn = 12, .crm = 8, .opc2 = 5, .type = ARM_CP_IO | ARM_CP_NO_RAW, .access = PL1_RW, .accessfn = gicv3_fiq_access, - .fieldoffset = offsetof(GICv3CPUState, icc_apr[GICV3_G0][1]), + .readfn = icc_ap_read, .writefn = icc_ap_write, }, { .name = "ICC_AP0R2_EL1", .state = ARM_CP_STATE_BOTH, .opc0 = 3, .opc1 = 0, .crn = 12, .crm = 8, .opc2 = 6, .type = ARM_CP_IO | ARM_CP_NO_RAW, .access = PL1_RW, .accessfn = gicv3_fiq_access, - .fieldoffset = offsetof(GICv3CPUState, icc_apr[GICV3_G0][2]), + .readfn = icc_ap_read, .writefn = icc_ap_write, }, { .name = "ICC_AP0R3_EL1", .state = ARM_CP_STATE_BOTH, .opc0 = 3, .opc1 = 0, .crn = 12, .crm = 8, .opc2 = 7, .type = ARM_CP_IO | ARM_CP_NO_RAW, .access = PL1_RW, .accessfn = gicv3_fiq_access, - .fieldoffset = offsetof(GICv3CPUState, icc_apr[GICV3_G0][3]), + .readfn = icc_ap_read, .writefn = icc_ap_write, }, /* All the ICC_AP1R*_EL1 registers are banked */ @@ -1275,7 +1275,7 @@ static const ARMCPRegInfo gicv3_cpuif_reginfo[] = { .opc0 = 3, .opc1 = 0, .crn = 12, .crm = 12, .opc2 = 6, .type = ARM_CP_IO | ARM_CP_NO_RAW, .access = PL1_RW, .accessfn = gicv3_fiq_access, - .fieldoffset = offsetof(GICv3CPUState, icc_igrpen[GICV3_G0]), + .readfn = icc_igrpen_read, .writefn = icc_igrpen_write, }, /* This register is banked */ @@ -1299,7 +1299,6 @@ static const ARMCPRegInfo gicv3_cpuif_reginfo[] = { .opc0 = 3, .opc1 = 6, .crn = 12, .crm = 12, .opc2 = 4, .type = ARM_CP_IO | ARM_CP_NO_RAW, .access = PL3_RW, - .fieldoffset = offsetof(GICv3CPUState, icc_ctlr_el3), .readfn = icc_ctlr_el3_read, .writefn = icc_ctlr_el3_write, }, diff --git a/hw/intc/ioapic.c b/hw/intc/ioapic.c index fd9208fde0..ea7ea0bce8 100644 --- a/hw/intc/ioapic.c +++ b/hw/intc/ioapic.c @@ -30,7 +30,7 @@ #include "hw/i386/ioapic_internal.h" #include "include/hw/pci/msi.h" #include "sysemu/kvm.h" -#include "target-i386/cpu.h" +#include "target/i386/cpu.h" #include "hw/i386/apic-msidef.h" #include "hw/i386/x86-iommu.h" diff --git a/hw/misc/aspeed_scu.c b/hw/misc/aspeed_scu.c index b1f3e6f6b8..95022d3607 100644 --- a/hw/misc/aspeed_scu.c +++ b/hw/misc/aspeed_scu.c @@ -86,7 +86,7 @@ #define BMC_DEV_ID TO_REG(0x1A4) #define PROT_KEY_UNLOCK 0x1688A8A8 -#define SCU_IO_REGION_SIZE 0x20000 +#define SCU_IO_REGION_SIZE 0x1000 static const uint32_t ast2400_a0_resets[ASPEED_SCU_NR_REGS] = { [SYS_RST_CTRL] = 0xFFCFFEDCU, @@ -231,6 +231,7 @@ static void aspeed_scu_reset(DeviceState *dev) switch (s->silicon_rev) { case AST2400_A0_SILICON_REV: + case AST2400_A1_SILICON_REV: reset = ast2400_a0_resets; break; case AST2500_A0_SILICON_REV: @@ -249,6 +250,7 @@ static void aspeed_scu_reset(DeviceState *dev) static uint32_t aspeed_silicon_revs[] = { AST2400_A0_SILICON_REV, + AST2400_A1_SILICON_REV, AST2500_A0_SILICON_REV, AST2500_A1_SILICON_REV, }; diff --git a/hw/misc/aspeed_sdmc.c b/hw/misc/aspeed_sdmc.c index 8830dc084c..5f3ac0b6f6 100644 --- a/hw/misc/aspeed_sdmc.c +++ b/hw/misc/aspeed_sdmc.c @@ -119,6 +119,7 @@ static void aspeed_sdmc_write(void *opaque, hwaddr addr, uint64_t data, /* Make sure readonly bits are kept */ switch (s->silicon_rev) { case AST2400_A0_SILICON_REV: + case AST2400_A1_SILICON_REV: data &= ~ASPEED_SDMC_READONLY_MASK; break; case AST2500_A0_SILICON_REV: @@ -193,6 +194,7 @@ static void aspeed_sdmc_reset(DeviceState *dev) /* Set ram size bit and defaults values */ switch (s->silicon_rev) { case AST2400_A0_SILICON_REV: + case AST2400_A1_SILICON_REV: s->regs[R_CONF] |= ASPEED_SDMC_VGA_COMPAT | ASPEED_SDMC_DRAM_SIZE(s->ram_bits); @@ -224,6 +226,7 @@ static void aspeed_sdmc_realize(DeviceState *dev, Error **errp) switch (s->silicon_rev) { case AST2400_A0_SILICON_REV: + case AST2400_A1_SILICON_REV: s->ram_bits = ast2400_rambits(s); break; case AST2500_A0_SILICON_REV: diff --git a/hw/misc/hyperv_testdev.c b/hw/misc/hyperv_testdev.c index 6cae9e9010..dbd7cdda07 100644 --- a/hw/misc/hyperv_testdev.c +++ b/hw/misc/hyperv_testdev.c @@ -17,7 +17,7 @@ #include "hw/qdev.h" #include "hw/isa/isa.h" #include "sysemu/kvm.h" -#include "target-i386/hyperv.h" +#include "target/i386/hyperv.h" #include "kvm_i386.h" #define HV_TEST_DEV_MAX_SINT_ROUTES 64 diff --git a/hw/ppc/fdt.c b/hw/ppc/fdt.c index e67d60d03c..38a7234b46 100644 --- a/hw/ppc/fdt.c +++ b/hw/ppc/fdt.c @@ -9,7 +9,7 @@ #include "qemu/osdep.h" #include "qapi/error.h" -#include "target-ppc/cpu.h" +#include "target/ppc/cpu.h" #include "hw/ppc/fdt.h" diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c index 9df7b25315..83597fe92b 100644 --- a/hw/ppc/pnv.c +++ b/hw/ppc/pnv.c @@ -22,7 +22,7 @@ #include "sysemu/sysemu.h" #include "sysemu/numa.h" #include "hw/hw.h" -#include "target-ppc/cpu.h" +#include "target/ppc/cpu.h" #include "qemu/log.h" #include "hw/ppc/fdt.h" #include "hw/ppc/ppc.h" diff --git a/hw/ppc/pnv_core.c b/hw/ppc/pnv_core.c index 76ce854b0c..d79d530b48 100644 --- a/hw/ppc/pnv_core.c +++ b/hw/ppc/pnv_core.c @@ -20,7 +20,7 @@ #include "sysemu/sysemu.h" #include "qapi/error.h" #include "qemu/log.h" -#include "target-ppc/cpu.h" +#include "target/ppc/cpu.h" #include "hw/ppc/ppc.h" #include "hw/ppc/pnv.h" #include "hw/ppc/pnv_core.h" diff --git a/hw/ppc/pnv_lpc.c b/hw/ppc/pnv_lpc.c index 0e2117f0f5..78db52415b 100644 --- a/hw/ppc/pnv_lpc.c +++ b/hw/ppc/pnv_lpc.c @@ -19,7 +19,7 @@ #include "qemu/osdep.h" #include "sysemu/sysemu.h" -#include "target-ppc/cpu.h" +#include "target/ppc/cpu.h" #include "qapi/error.h" #include "qemu/log.h" diff --git a/hw/ppc/pnv_xscom.c b/hw/ppc/pnv_xscom.c index 8da271872f..b82af4f086 100644 --- a/hw/ppc/pnv_xscom.c +++ b/hw/ppc/pnv_xscom.c @@ -21,7 +21,7 @@ #include "hw/hw.h" #include "qemu/log.h" #include "sysemu/kvm.h" -#include "target-ppc/cpu.h" +#include "target/ppc/cpu.h" #include "hw/sysbus.h" #include "hw/ppc/fdt.h" diff --git a/hw/ppc/spapr_cpu_core.c b/hw/ppc/spapr_cpu_core.c index e0c14f6b77..c18632bbff 100644 --- a/hw/ppc/spapr_cpu_core.c +++ b/hw/ppc/spapr_cpu_core.c @@ -8,14 +8,14 @@ */ #include "hw/cpu/core.h" #include "hw/ppc/spapr_cpu_core.h" -#include "target-ppc/cpu.h" +#include "target/ppc/cpu.h" #include "hw/ppc/spapr.h" #include "hw/boards.h" #include "qapi/error.h" #include "sysemu/cpus.h" -#include "target-ppc/kvm_ppc.h" +#include "target/ppc/kvm_ppc.h" #include "hw/ppc/ppc.h" -#include "target-ppc/mmu-hash64.h" +#include "target/ppc/mmu-hash64.h" #include "sysemu/numa.h" static void spapr_cpu_reset(void *opaque) diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c index a96319138a..bdd1e5f86c 100644 --- a/hw/scsi/scsi-disk.c +++ b/hw/scsi/scsi-disk.c @@ -2157,6 +2157,13 @@ static int32_t scsi_disk_dma_command(SCSIRequest *req, uint8_t *buf) DPRINTF("Write %s(sector %" PRId64 ", count %u)\n", (command & 0xe) == 0xe ? "And Verify " : "", r->req.cmd.lba, len); + case VERIFY_10: + case VERIFY_12: + case VERIFY_16: + /* We get here only for BYTCHK == 0x01 and only for scsi-block. + * As far as DMA is concerned, we can treat it the same as a write; + * scsi_block_do_sgio will send VERIFY commands. + */ if (r->req.cmd.buf[1] & 0xe0) { goto illegal_request; } @@ -2712,7 +2719,7 @@ static bool scsi_block_is_passthrough(SCSIDiskState *s, uint8_t *buf) case WRITE_VERIFY_16: /* MMC writing cannot be done via DMA helpers, because it sometimes * involves writing beyond the maximum LBA or to negative LBA (lead-in). - * We might use scsi_disk_dma_reqops as long as no writing commands are + * We might use scsi_block_dma_reqops as long as no writing commands are * seen, but performance usually isn't paramount on optical media. So, * just make scsi-block operate the same as scsi-generic for them. */ diff --git a/hw/scsi/virtio-scsi.c b/hw/scsi/virtio-scsi.c index 10fd687193..34bba35d83 100644 --- a/hw/scsi/virtio-scsi.c +++ b/hw/scsi/virtio-scsi.c @@ -420,6 +420,20 @@ static void virtio_scsi_handle_ctrl_req(VirtIOSCSI *s, VirtIOSCSIReq *req) } } +static inline void virtio_scsi_acquire(VirtIOSCSI *s) +{ + if (s->ctx) { + aio_context_acquire(s->ctx); + } +} + +static inline void virtio_scsi_release(VirtIOSCSI *s) +{ + if (s->ctx) { + aio_context_release(s->ctx); + } +} + void virtio_scsi_handle_ctrl_vq(VirtIOSCSI *s, VirtQueue *vq) { VirtIOSCSIReq *req; @@ -691,10 +705,7 @@ void virtio_scsi_push_event(VirtIOSCSI *s, SCSIDevice *dev, return; } - if (s->dataplane_started) { - assert(s->ctx); - aio_context_acquire(s->ctx); - } + virtio_scsi_acquire(s); req = virtio_scsi_pop_req(s, vs->event_vq); if (!req) { @@ -730,9 +741,7 @@ void virtio_scsi_push_event(VirtIOSCSI *s, SCSIDevice *dev, } virtio_scsi_complete_req(req); out: - if (s->dataplane_started) { - aio_context_release(s->ctx); - } + virtio_scsi_release(s); } void virtio_scsi_handle_event_vq(VirtIOSCSI *s, VirtQueue *vq) @@ -778,9 +787,9 @@ static void virtio_scsi_hotplug(HotplugHandler *hotplug_dev, DeviceState *dev, if (blk_op_is_blocked(sd->conf.blk, BLOCK_OP_TYPE_DATAPLANE, errp)) { return; } - aio_context_acquire(s->ctx); + virtio_scsi_acquire(s); blk_set_aio_context(sd->conf.blk, s->ctx); - aio_context_release(s->ctx); + virtio_scsi_release(s); } diff --git a/hw/sh4/shix.c b/hw/sh4/shix.c index 14d4007c1c..fd00cc5ea2 100644 --- a/hw/sh4/shix.c +++ b/hw/sh4/shix.c @@ -25,7 +25,7 @@ Shix 2.0 board by Alexis Polti, described at https://web.archive.org/web/20070917001736/perso.enst.fr/~polti/realisations/shix20 - More information in target-sh4/README.sh4 + More information in target/sh4/README.sh4 */ #include "qemu/osdep.h" #include "qapi/error.h" diff --git a/hw/ssi/aspeed_smc.c b/hw/ssi/aspeed_smc.c index 6e8403ebc2..78f5aed532 100644 --- a/hw/ssi/aspeed_smc.c +++ b/hw/ssi/aspeed_smc.c @@ -253,7 +253,8 @@ static void aspeed_smc_flash_set_segment(AspeedSMCState *s, int cs, qemu_log_mask(LOG_GUEST_ERROR, "%s: Tried to change CS0 start address to 0x%" HWADDR_PRIx "\n", s->ctrl->name, seg.addr); - return; + seg.addr = s->ctrl->flash_window_base; + new = aspeed_smc_segment_to_reg(&seg); } /* @@ -267,8 +268,10 @@ static void aspeed_smc_flash_set_segment(AspeedSMCState *s, int cs, s->ctrl->segments[cs].size) { qemu_log_mask(LOG_GUEST_ERROR, "%s: Tried to change CS%d end address to 0x%" - HWADDR_PRIx "\n", s->ctrl->name, cs, seg.addr); - return; + HWADDR_PRIx "\n", s->ctrl->name, cs, seg.addr + seg.size); + seg.size = s->ctrl->segments[cs].addr + s->ctrl->segments[cs].size - + seg.addr; + new = aspeed_smc_segment_to_reg(&seg); } /* Keep the segment in the overall flash window */ @@ -281,16 +284,14 @@ static void aspeed_smc_flash_set_segment(AspeedSMCState *s, int cs, } /* Check start address vs. alignment */ - if (seg.addr % seg.size) { + if (seg.size && !QEMU_IS_ALIGNED(seg.addr, seg.size)) { qemu_log_mask(LOG_GUEST_ERROR, "%s: new segment for CS%d is not " "aligned : [ 0x%"HWADDR_PRIx" - 0x%"HWADDR_PRIx" ]\n", s->ctrl->name, cs, seg.addr, seg.addr + seg.size); } - /* And segments should not overlap */ - if (aspeed_smc_flash_overlap(s, &seg, cs)) { - return; - } + /* And segments should not overlap (in the specs) */ + aspeed_smc_flash_overlap(s, &seg, cs); /* All should be fine now to move the region */ memory_region_transaction_begin(); diff --git a/hw/timer/ds1338.c b/hw/timer/ds1338.c index 0112949e23..f5d04dd5d7 100644 --- a/hw/timer/ds1338.c +++ b/hw/timer/ds1338.c @@ -198,11 +198,6 @@ static int ds1338_send(I2CSlave *i2c, uint8_t data) return 0; } -static int ds1338_init(I2CSlave *i2c) -{ - return 0; -} - static void ds1338_reset(DeviceState *dev) { DS1338State *s = DS1338(dev); @@ -220,7 +215,6 @@ static void ds1338_class_init(ObjectClass *klass, void *data) DeviceClass *dc = DEVICE_CLASS(klass); I2CSlaveClass *k = I2C_SLAVE_CLASS(klass); - k->init = ds1338_init; k->event = ds1338_event; k->recv = ds1338_recv; k->send = ds1338_send; diff --git a/hw/watchdog/wdt_i6300esb.c b/hw/watchdog/wdt_i6300esb.c index a83d951213..49b3cd188a 100644 --- a/hw/watchdog/wdt_i6300esb.c +++ b/hw/watchdog/wdt_i6300esb.c @@ -428,6 +428,14 @@ static void i6300esb_realize(PCIDevice *dev, Error **errp) /* qemu_register_coalesced_mmio (addr, 0x10); ? */ } +static void i6300esb_exit(PCIDevice *dev) +{ + I6300State *d = WATCHDOG_I6300ESB_DEVICE(dev); + + timer_del(d->timer); + timer_free(d->timer); +} + static WatchdogTimerModel model = { .wdt_name = "i6300esb", .wdt_description = "Intel 6300ESB", @@ -441,6 +449,7 @@ static void i6300esb_class_init(ObjectClass *klass, void *data) k->config_read = i6300esb_config_read; k->config_write = i6300esb_config_write; k->realize = i6300esb_realize; + k->exit = i6300esb_exit; k->vendor_id = PCI_VENDOR_ID_INTEL; k->device_id = PCI_DEVICE_ID_INTEL_ESB_9; k->class_id = PCI_CLASS_SYSTEM_OTHER; diff --git a/include/block/aio.h b/include/block/aio.h index c7ae27c91c..ca551e346f 100644 --- a/include/block/aio.h +++ b/include/block/aio.h @@ -195,8 +195,8 @@ QEMUBH *aio_bh_new(AioContext *ctx, QEMUBHFunc *cb, void *opaque); * aio_notify: Force processing of pending events. * * Similar to signaling a condition variable, aio_notify forces - * aio_wait to exit, so that the next call will re-examine pending events. - * The caller of aio_notify will usually call aio_wait again very soon, + * aio_poll to exit, so that the next call will re-examine pending events. + * The caller of aio_notify will usually call aio_poll again very soon, * or go through another iteration of the GLib main loop. Hence, aio_notify * also has the side effect of recalculating the sets of file descriptors * that the main loop waits for. diff --git a/include/exec/cpu-all.h b/include/exec/cpu-all.h index e9004e5798..ffe43d5654 100644 --- a/include/exec/cpu-all.h +++ b/include/exec/cpu-all.h @@ -186,6 +186,29 @@ void address_space_stl(AddressSpace *as, hwaddr addr, uint32_t val, MemTxAttrs attrs, MemTxResult *result); void address_space_stq(AddressSpace *as, hwaddr addr, uint64_t val, MemTxAttrs attrs, MemTxResult *result); + +uint32_t lduw_phys_cached(MemoryRegionCache *cache, hwaddr addr); +uint32_t ldl_phys_cached(MemoryRegionCache *cache, hwaddr addr); +uint64_t ldq_phys_cached(MemoryRegionCache *cache, hwaddr addr); +void stl_phys_notdirty_cached(MemoryRegionCache *cache, hwaddr addr, uint32_t val); +void stw_phys_cached(MemoryRegionCache *cache, hwaddr addr, uint32_t val); +void stl_phys_cached(MemoryRegionCache *cache, hwaddr addr, uint32_t val); +void stq_phys_cached(MemoryRegionCache *cache, hwaddr addr, uint64_t val); + +uint32_t address_space_lduw_cached(MemoryRegionCache *cache, hwaddr addr, + MemTxAttrs attrs, MemTxResult *result); +uint32_t address_space_ldl_cached(MemoryRegionCache *cache, hwaddr addr, + MemTxAttrs attrs, MemTxResult *result); +uint64_t address_space_ldq_cached(MemoryRegionCache *cache, hwaddr addr, + MemTxAttrs attrs, MemTxResult *result); +void address_space_stl_notdirty_cached(MemoryRegionCache *cache, hwaddr addr, + uint32_t val, MemTxAttrs attrs, MemTxResult *result); +void address_space_stw_cached(MemoryRegionCache *cache, hwaddr addr, uint32_t val, + MemTxAttrs attrs, MemTxResult *result); +void address_space_stl_cached(MemoryRegionCache *cache, hwaddr addr, uint32_t val, + MemTxAttrs attrs, MemTxResult *result); +void address_space_stq_cached(MemoryRegionCache *cache, hwaddr addr, uint64_t val, + MemTxAttrs attrs, MemTxResult *result); #endif /* page related stuff */ diff --git a/include/exec/cpu-common.h b/include/exec/cpu-common.h index cffdc130e6..bd15853e51 100644 --- a/include/exec/cpu-common.h +++ b/include/exec/cpu-common.h @@ -94,21 +94,6 @@ bool cpu_physical_memory_is_io(hwaddr phys_addr); */ void qemu_flush_coalesced_mmio_buffer(void); -uint32_t ldub_phys(AddressSpace *as, hwaddr addr); -uint32_t lduw_le_phys(AddressSpace *as, hwaddr addr); -uint32_t lduw_be_phys(AddressSpace *as, hwaddr addr); -uint32_t ldl_le_phys(AddressSpace *as, hwaddr addr); -uint32_t ldl_be_phys(AddressSpace *as, hwaddr addr); -uint64_t ldq_le_phys(AddressSpace *as, hwaddr addr); -uint64_t ldq_be_phys(AddressSpace *as, hwaddr addr); -void stb_phys(AddressSpace *as, hwaddr addr, uint32_t val); -void stw_le_phys(AddressSpace *as, hwaddr addr, uint32_t val); -void stw_be_phys(AddressSpace *as, hwaddr addr, uint32_t val); -void stl_le_phys(AddressSpace *as, hwaddr addr, uint32_t val); -void stl_be_phys(AddressSpace *as, hwaddr addr, uint32_t val); -void stq_le_phys(AddressSpace *as, hwaddr addr, uint64_t val); -void stq_be_phys(AddressSpace *as, hwaddr addr, uint64_t val); - void cpu_physical_memory_write_rom(AddressSpace *as, hwaddr addr, const uint8_t *buf, int len); void cpu_flush_icache_range(hwaddr start, int len); diff --git a/include/exec/memory.h b/include/exec/memory.h index 9728a2fb1a..64560f61b4 100644 --- a/include/exec/memory.h +++ b/include/exec/memory.h @@ -1404,6 +1404,140 @@ void address_space_stq_le(AddressSpace *as, hwaddr addr, uint64_t val, void address_space_stq_be(AddressSpace *as, hwaddr addr, uint64_t val, MemTxAttrs attrs, MemTxResult *result); +uint32_t ldub_phys(AddressSpace *as, hwaddr addr); +uint32_t lduw_le_phys(AddressSpace *as, hwaddr addr); +uint32_t lduw_be_phys(AddressSpace *as, hwaddr addr); +uint32_t ldl_le_phys(AddressSpace *as, hwaddr addr); +uint32_t ldl_be_phys(AddressSpace *as, hwaddr addr); +uint64_t ldq_le_phys(AddressSpace *as, hwaddr addr); +uint64_t ldq_be_phys(AddressSpace *as, hwaddr addr); +void stb_phys(AddressSpace *as, hwaddr addr, uint32_t val); +void stw_le_phys(AddressSpace *as, hwaddr addr, uint32_t val); +void stw_be_phys(AddressSpace *as, hwaddr addr, uint32_t val); +void stl_le_phys(AddressSpace *as, hwaddr addr, uint32_t val); +void stl_be_phys(AddressSpace *as, hwaddr addr, uint32_t val); +void stq_le_phys(AddressSpace *as, hwaddr addr, uint64_t val); +void stq_be_phys(AddressSpace *as, hwaddr addr, uint64_t val); + +struct MemoryRegionCache { + hwaddr xlat; + void *ptr; + hwaddr len; + MemoryRegion *mr; + bool is_write; +}; + +/* address_space_cache_init: prepare for repeated access to a physical + * memory region + * + * @cache: #MemoryRegionCache to be filled + * @as: #AddressSpace to be accessed + * @addr: address within that address space + * @len: length of buffer + * @is_write: indicates the transfer direction + * + * Will only work with RAM, and may map a subset of the requested range by + * returning a value that is less than @len. On failure, return a negative + * errno value. + * + * Because it only works with RAM, this function can be used for + * read-modify-write operations. In this case, is_write should be %true. + * + * Note that addresses passed to the address_space_*_cached functions + * are relative to @addr. + */ +int64_t address_space_cache_init(MemoryRegionCache *cache, + AddressSpace *as, + hwaddr addr, + hwaddr len, + bool is_write); + +/** + * address_space_cache_invalidate: complete a write to a #MemoryRegionCache + * + * @cache: The #MemoryRegionCache to operate on. + * @addr: The first physical address that was written, relative to the + * address that was passed to @address_space_cache_init. + * @access_len: The number of bytes that were written starting at @addr. + */ +void address_space_cache_invalidate(MemoryRegionCache *cache, + hwaddr addr, + hwaddr access_len); + +/** + * address_space_cache_destroy: free a #MemoryRegionCache + * + * @cache: The #MemoryRegionCache whose memory should be released. + */ +void address_space_cache_destroy(MemoryRegionCache *cache); + +/* address_space_ld*_cached: load from a cached #MemoryRegion + * address_space_st*_cached: store into a cached #MemoryRegion + * + * These functions perform a load or store of the byte, word, + * longword or quad to the specified address. The address is + * a physical address in the AddressSpace, but it must lie within + * a #MemoryRegion that was mapped with address_space_cache_init. + * + * The _le suffixed functions treat the data as little endian; + * _be indicates big endian; no suffix indicates "same endianness + * as guest CPU". + * + * The "guest CPU endianness" accessors are deprecated for use outside + * target-* code; devices should be CPU-agnostic and use either the LE + * or the BE accessors. + * + * @cache: previously initialized #MemoryRegionCache to be accessed + * @addr: address within the address space + * @val: data value, for stores + * @attrs: memory transaction attributes + * @result: location to write the success/failure of the transaction; + * if NULL, this information is discarded + */ +uint32_t address_space_ldub_cached(MemoryRegionCache *cache, hwaddr addr, + MemTxAttrs attrs, MemTxResult *result); +uint32_t address_space_lduw_le_cached(MemoryRegionCache *cache, hwaddr addr, + MemTxAttrs attrs, MemTxResult *result); +uint32_t address_space_lduw_be_cached(MemoryRegionCache *cache, hwaddr addr, + MemTxAttrs attrs, MemTxResult *result); +uint32_t address_space_ldl_le_cached(MemoryRegionCache *cache, hwaddr addr, + MemTxAttrs attrs, MemTxResult *result); +uint32_t address_space_ldl_be_cached(MemoryRegionCache *cache, hwaddr addr, + MemTxAttrs attrs, MemTxResult *result); +uint64_t address_space_ldq_le_cached(MemoryRegionCache *cache, hwaddr addr, + MemTxAttrs attrs, MemTxResult *result); +uint64_t address_space_ldq_be_cached(MemoryRegionCache *cache, hwaddr addr, + MemTxAttrs attrs, MemTxResult *result); +void address_space_stb_cached(MemoryRegionCache *cache, hwaddr addr, uint32_t val, + MemTxAttrs attrs, MemTxResult *result); +void address_space_stw_le_cached(MemoryRegionCache *cache, hwaddr addr, uint32_t val, + MemTxAttrs attrs, MemTxResult *result); +void address_space_stw_be_cached(MemoryRegionCache *cache, hwaddr addr, uint32_t val, + MemTxAttrs attrs, MemTxResult *result); +void address_space_stl_le_cached(MemoryRegionCache *cache, hwaddr addr, uint32_t val, + MemTxAttrs attrs, MemTxResult *result); +void address_space_stl_be_cached(MemoryRegionCache *cache, hwaddr addr, uint32_t val, + MemTxAttrs attrs, MemTxResult *result); +void address_space_stq_le_cached(MemoryRegionCache *cache, hwaddr addr, uint64_t val, + MemTxAttrs attrs, MemTxResult *result); +void address_space_stq_be_cached(MemoryRegionCache *cache, hwaddr addr, uint64_t val, + MemTxAttrs attrs, MemTxResult *result); + +uint32_t ldub_phys_cached(MemoryRegionCache *cache, hwaddr addr); +uint32_t lduw_le_phys_cached(MemoryRegionCache *cache, hwaddr addr); +uint32_t lduw_be_phys_cached(MemoryRegionCache *cache, hwaddr addr); +uint32_t ldl_le_phys_cached(MemoryRegionCache *cache, hwaddr addr); +uint32_t ldl_be_phys_cached(MemoryRegionCache *cache, hwaddr addr); +uint64_t ldq_le_phys_cached(MemoryRegionCache *cache, hwaddr addr); +uint64_t ldq_be_phys_cached(MemoryRegionCache *cache, hwaddr addr); +void stb_phys_cached(MemoryRegionCache *cache, hwaddr addr, uint32_t val); +void stw_le_phys_cached(MemoryRegionCache *cache, hwaddr addr, uint32_t val); +void stw_be_phys_cached(MemoryRegionCache *cache, hwaddr addr, uint32_t val); +void stl_le_phys_cached(MemoryRegionCache *cache, hwaddr addr, uint32_t val); +void stl_be_phys_cached(MemoryRegionCache *cache, hwaddr addr, uint32_t val); +void stq_le_phys_cached(MemoryRegionCache *cache, hwaddr addr, uint64_t val); +void stq_be_phys_cached(MemoryRegionCache *cache, hwaddr addr, uint64_t val); + /* address_space_translate: translate an address range into an address space * into a MemoryRegion and an address range into that section. Should be * called from an RCU critical section, to avoid that the last reference @@ -1529,6 +1663,38 @@ MemTxResult address_space_read(AddressSpace *as, hwaddr addr, MemTxAttrs attrs, return result; } +/** + * address_space_read_cached: read from a cached RAM region + * + * @cache: Cached region to be addressed + * @addr: address relative to the base of the RAM region + * @buf: buffer with the data transferred + * @len: length of the data transferred + */ +static inline void +address_space_read_cached(MemoryRegionCache *cache, hwaddr addr, + void *buf, int len) +{ + assert(addr < cache->len && len <= cache->len - addr); + memcpy(buf, cache->ptr + addr, len); +} + +/** + * address_space_write_cached: write to a cached RAM region + * + * @cache: Cached region to be addressed + * @addr: address relative to the base of the RAM region + * @buf: buffer with the data transferred + * @len: length of the data transferred + */ +static inline void +address_space_write_cached(MemoryRegionCache *cache, hwaddr addr, + void *buf, int len) +{ + assert(addr < cache->len && len <= cache->len - addr); + memcpy(cache->ptr + addr, buf, len); +} + #endif #endif diff --git a/include/hw/arm/arm.h b/include/hw/arm/arm.h index aeeebfed90..c175c0e999 100644 --- a/include/hw/arm/arm.h +++ b/include/hw/arm/arm.h @@ -12,7 +12,7 @@ #define HW_ARM_H #include "exec/memory.h" -#include "target-arm/cpu-qom.h" +#include "target/arm/cpu-qom.h" #include "hw/irq.h" #include "qemu/notify.h" diff --git a/include/hw/arm/aspeed_soc.h b/include/hw/arm/aspeed_soc.h index 5406b498d7..1ab5deaa08 100644 --- a/include/hw/arm/aspeed_soc.h +++ b/include/hw/arm/aspeed_soc.h @@ -27,8 +27,9 @@ typedef struct AspeedSoCState { DeviceState parent; /*< public >*/ - ARMCPU *cpu; + ARMCPU cpu; MemoryRegion iomem; + MemoryRegion sram; AspeedVICState vic; AspeedTimerCtrlState timerctrl; AspeedI2CState i2c; @@ -46,6 +47,7 @@ typedef struct AspeedSoCInfo { const char *cpu_model; uint32_t silicon_rev; hwaddr sdram_base; + uint64_t sram_size; int spis_num; const hwaddr *spi_bases; const char *fmc_typename; diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h index 29fef8bfa1..76bb6d4203 100644 --- a/include/hw/arm/exynos4210.h +++ b/include/hw/arm/exynos4210.h @@ -27,7 +27,7 @@ #include "qemu-common.h" #include "exec/memory.h" -#include "target-arm/cpu-qom.h" +#include "target/arm/cpu-qom.h" #define EXYNOS4210_NCPUS 2 diff --git a/include/hw/arm/omap.h b/include/hw/arm/omap.h index f026c8df57..f25870b718 100644 --- a/include/hw/arm/omap.h +++ b/include/hw/arm/omap.h @@ -20,7 +20,7 @@ #include "exec/memory.h" # define hw_omap_h "omap.h" #include "hw/irq.h" -#include "target-arm/cpu-qom.h" +#include "target/arm/cpu-qom.h" # define OMAP_EMIFS_BASE 0x00000000 # define OMAP2_Q0_BASE 0x00000000 diff --git a/include/hw/arm/pxa.h b/include/hw/arm/pxa.h index 191e068184..0df1199caa 100644 --- a/include/hw/arm/pxa.h +++ b/include/hw/arm/pxa.h @@ -11,7 +11,7 @@ #define PXA_H #include "exec/memory.h" -#include "target-arm/cpu-qom.h" +#include "target/arm/cpu-qom.h" /* Interrupt numbers */ # define PXA2XX_PIC_SSP3 0 diff --git a/include/hw/compat.h b/include/hw/compat.h index 8dfc7a38c0..4fe44d1c7a 100644 --- a/include/hw/compat.h +++ b/include/hw/compat.h @@ -1,6 +1,9 @@ #ifndef HW_COMPAT_H #define HW_COMPAT_H +#define HW_COMPAT_2_8 \ + /* empty */ + #define HW_COMPAT_2_7 \ {\ .driver = "virtio-pci",\ diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h index 4b74130559..b22e699c46 100644 --- a/include/hw/i386/pc.h +++ b/include/hw/i386/pc.h @@ -63,6 +63,9 @@ struct PCMachineState { AcpiNVDIMMState acpi_nvdimm_state; bool acpi_build_enabled; + bool smbus; + bool sata; + bool pit; /* RAM information (sizes, addresses, configuration): */ ram_addr_t below_4g_mem_size, above_4g_mem_size; @@ -88,6 +91,9 @@ struct PCMachineState { #define PC_MACHINE_VMPORT "vmport" #define PC_MACHINE_SMM "smm" #define PC_MACHINE_NVDIMM "nvdimm" +#define PC_MACHINE_SMBUS "smbus" +#define PC_MACHINE_SATA "sata" +#define PC_MACHINE_PIT "pit" /** * PCMachineClass: @@ -260,6 +266,7 @@ void pc_basic_device_init(ISABus *isa_bus, qemu_irq *gsi, ISADevice **rtc_state, bool create_fdctrl, bool no_vmport, + bool has_pit, uint32_t hpet_irqs); void pc_init_ne2k_isa(ISABus *bus, NICInfo *nd); void pc_cmos_init(PCMachineState *pcms, @@ -372,6 +379,11 @@ bool e820_get_entry(int, uint32_t, uint64_t *, uint64_t *); #define PC_COMPAT_2_7 \ HW_COMPAT_2_7 \ {\ + .driver = "kvmclock",\ + .property = "x-mach-use-reliable-get-clock",\ + .value = "off",\ + },\ + {\ .driver = TYPE_X86_CPU,\ .property = "l3-cache",\ .value = "off",\ diff --git a/include/hw/m68k/mcf.h b/include/hw/m68k/mcf.h index 0f0d2288e6..fdae229502 100644 --- a/include/hw/m68k/mcf.h +++ b/include/hw/m68k/mcf.h @@ -2,7 +2,7 @@ #define HW_MCF_H /* Motorola ColdFire device prototypes. */ -#include "target-m68k/cpu-qom.h" +#include "target/m68k/cpu-qom.h" struct MemoryRegion; diff --git a/include/hw/mips/cpudevs.h b/include/hw/mips/cpudevs.h index 8673daa39d..698339b83e 100644 --- a/include/hw/mips/cpudevs.h +++ b/include/hw/mips/cpudevs.h @@ -1,7 +1,7 @@ #ifndef HW_MIPS_CPUDEVS_H #define HW_MIPS_CPUDEVS_H -#include "target-mips/cpu-qom.h" +#include "target/mips/cpu-qom.h" /* Definitions for MIPS CPU internal devices. */ diff --git a/include/hw/misc/aspeed_scu.h b/include/hw/misc/aspeed_scu.h index 14ffc43de8..bd4ac013f9 100644 --- a/include/hw/misc/aspeed_scu.h +++ b/include/hw/misc/aspeed_scu.h @@ -32,6 +32,7 @@ typedef struct AspeedSCUState { } AspeedSCUState; #define AST2400_A0_SILICON_REV 0x02000303U +#define AST2400_A1_SILICON_REV 0x02010303U #define AST2500_A0_SILICON_REV 0x04000303U #define AST2500_A1_SILICON_REV 0x04010303U diff --git a/include/hw/ppc/fdt.h b/include/hw/ppc/fdt.h index 0cabb6af04..bd5b0a8c3d 100644 --- a/include/hw/ppc/fdt.h +++ b/include/hw/ppc/fdt.h @@ -11,7 +11,7 @@ #define PPC_FDT_H #include "qemu/error-report.h" -#include "target-ppc/cpu-qom.h" +#include "target/ppc/cpu-qom.h" #define _FDT(exp) \ do { \ diff --git a/include/hw/ppc/ppc.h b/include/hw/ppc/ppc.h index 00c1fb1e72..4e7fe110d6 100644 --- a/include/hw/ppc/ppc.h +++ b/include/hw/ppc/ppc.h @@ -1,7 +1,7 @@ #ifndef HW_PPC_H #define HW_PPC_H -#include "target-ppc/cpu-qom.h" +#include "target/ppc/cpu-qom.h" void ppc_set_irq(PowerPCCPU *cpu, int n_IRQ, int level); diff --git a/include/hw/ppc/spapr_cpu_core.h b/include/hw/ppc/spapr_cpu_core.h index 283969bafb..50292f48b1 100644 --- a/include/hw/ppc/spapr_cpu_core.h +++ b/include/hw/ppc/spapr_cpu_core.h @@ -11,7 +11,7 @@ #include "hw/qdev.h" #include "hw/cpu/core.h" -#include "target-ppc/cpu-qom.h" +#include "target/ppc/cpu-qom.h" #define TYPE_SPAPR_CPU_CORE "spapr-cpu-core" #define SPAPR_CPU_CORE(obj) \ diff --git a/include/hw/sh4/sh.h b/include/hw/sh4/sh.h index 070312d921..e59b9e7c45 100644 --- a/include/hw/sh4/sh.h +++ b/include/hw/sh4/sh.h @@ -3,7 +3,7 @@ /* Definitions for SH board emulation. */ #include "hw/sh4/sh_intc.h" -#include "target-sh4/cpu-qom.h" +#include "target/sh4/cpu-qom.h" #define A7ADDR(x) ((x) & 0x1fffffff) #define P4ADDR(x) ((x) | 0xe0000000) diff --git a/include/qemu/main-loop.h b/include/qemu/main-loop.h index 470f600bbc..a9d4f23cd9 100644 --- a/include/qemu/main-loop.h +++ b/include/qemu/main-loop.h @@ -238,7 +238,7 @@ bool qemu_mutex_iothread_locked(void); * qemu_mutex_lock_iothread: Lock the main loop mutex. * * This function locks the main loop mutex. The mutex is taken by - * qemu_init_main_loop and always taken except while waiting on + * main() in vl.c and always taken except while waiting on * external events (such as with select). The mutex should be taken * by threads other than the main loop thread when calling * qemu_bh_new(), qemu_set_fd_handler() and basically all other @@ -253,7 +253,7 @@ void qemu_mutex_lock_iothread(void); * qemu_mutex_unlock_iothread: Unlock the main loop mutex. * * This function unlocks the main loop mutex. The mutex is taken by - * qemu_init_main_loop and always taken except while waiting on + * main() in vl.c and always taken except while waiting on * external events (such as with select). The mutex should be unlocked * as soon as possible by threads other than the main loop thread, * because it prevents the main loop from processing callbacks, diff --git a/include/qemu/timer.h b/include/qemu/timer.h index bdfae004e4..9abed51ae8 100644 --- a/include/qemu/timer.h +++ b/include/qemu/timer.h @@ -133,7 +133,7 @@ bool qemu_clock_has_timers(QEMUClockType type); * @type: the clock type * * Determines whether a clock's default timer list - * has an expired clock. + * has an expired timer. * * Returns: true if the clock's default timer list has * an expired timer diff --git a/include/qemu/typedefs.h b/include/qemu/typedefs.h index 1b8c30a7a0..9a8bcbde36 100644 --- a/include/qemu/typedefs.h +++ b/include/qemu/typedefs.h @@ -45,6 +45,7 @@ typedef struct MachineState MachineState; typedef struct MemoryListener MemoryListener; typedef struct MemoryMappingList MemoryMappingList; typedef struct MemoryRegion MemoryRegion; +typedef struct MemoryRegionCache MemoryRegionCache; typedef struct MemoryRegionSection MemoryRegionSection; typedef struct MigrationIncomingState MigrationIncomingState; typedef struct MigrationParams MigrationParams; diff --git a/include/standard-headers/linux/input.h b/include/standard-headers/linux/input.h index 7361a16b50..b472b8530c 100644 --- a/include/standard-headers/linux/input.h +++ b/include/standard-headers/linux/input.h @@ -245,6 +245,7 @@ struct input_mask { #define BUS_SPI 0x1C #define BUS_RMI 0x1D #define BUS_CEC 0x1E +#define BUS_INTEL_ISHTP 0x1F /* * MT_TOOL types diff --git a/include/standard-headers/linux/pci_regs.h b/include/standard-headers/linux/pci_regs.h index 404095124a..e5a2e68b22 100644 --- a/include/standard-headers/linux/pci_regs.h +++ b/include/standard-headers/linux/pci_regs.h @@ -612,6 +612,8 @@ */ #define PCI_EXP_DEVCAP2 36 /* Device Capabilities 2 */ #define PCI_EXP_DEVCAP2_ARI 0x00000020 /* Alternative Routing-ID */ +#define PCI_EXP_DEVCAP2_ATOMIC_ROUTE 0x00000040 /* Atomic Op routing */ +#define PCI_EXP_DEVCAP2_ATOMIC_COMP64 0x00000100 /* Atomic 64-bit compare */ #define PCI_EXP_DEVCAP2_LTR 0x00000800 /* Latency tolerance reporting */ #define PCI_EXP_DEVCAP2_OBFF_MASK 0x000c0000 /* OBFF support mechanism */ #define PCI_EXP_DEVCAP2_OBFF_MSG 0x00040000 /* New message signaling */ @@ -619,6 +621,7 @@ #define PCI_EXP_DEVCTL2 40 /* Device Control 2 */ #define PCI_EXP_DEVCTL2_COMP_TIMEOUT 0x000f /* Completion Timeout Value */ #define PCI_EXP_DEVCTL2_ARI 0x0020 /* Alternative Routing-ID */ +#define PCI_EXP_DEVCTL2_ATOMIC_REQ 0x0040 /* Set Atomic requests */ #define PCI_EXP_DEVCTL2_IDO_REQ_EN 0x0100 /* Allow IDO for requests */ #define PCI_EXP_DEVCTL2_IDO_CMP_EN 0x0200 /* Allow IDO for completions */ #define PCI_EXP_DEVCTL2_LTR_EN 0x0400 /* Enable LTR mechanism */ @@ -671,7 +674,8 @@ #define PCI_EXT_CAP_ID_PMUX 0x1A /* Protocol Multiplexing */ #define PCI_EXT_CAP_ID_PASID 0x1B /* Process Address Space ID */ #define PCI_EXT_CAP_ID_DPC 0x1D /* Downstream Port Containment */ -#define PCI_EXT_CAP_ID_MAX PCI_EXT_CAP_ID_DPC +#define PCI_EXT_CAP_ID_PTM 0x1F /* Precision Time Measurement */ +#define PCI_EXT_CAP_ID_MAX PCI_EXT_CAP_ID_PTM #define PCI_EXT_CAP_DSN_SIZEOF 12 #define PCI_EXT_CAP_MCAST_ENDPOINT_SIZEOF 40 @@ -964,4 +968,13 @@ #define PCI_EXP_DPC_SOURCE_ID 10 /* DPC Source Identifier */ +/* Precision Time Measurement */ +#define PCI_PTM_CAP 0x04 /* PTM Capability */ +#define PCI_PTM_CAP_REQ 0x00000001 /* Requester capable */ +#define PCI_PTM_CAP_ROOT 0x00000004 /* Root capable */ +#define PCI_PTM_GRANULARITY_MASK 0x0000FF00 /* Clock granularity */ +#define PCI_PTM_CTRL 0x08 /* PTM Control */ +#define PCI_PTM_CTRL_ENABLE 0x00000001 /* PTM enable */ +#define PCI_PTM_CTRL_ROOT 0x00000002 /* Root select */ + #endif /* LINUX_PCI_REGS_H */ diff --git a/linux-headers/asm-arm/kvm.h b/linux-headers/asm-arm/kvm.h index 541268c946..2fb7859465 100644 --- a/linux-headers/asm-arm/kvm.h +++ b/linux-headers/asm-arm/kvm.h @@ -84,6 +84,13 @@ struct kvm_regs { #define KVM_VGIC_V2_DIST_SIZE 0x1000 #define KVM_VGIC_V2_CPU_SIZE 0x2000 +/* Supported VGICv3 address types */ +#define KVM_VGIC_V3_ADDR_TYPE_DIST 2 +#define KVM_VGIC_V3_ADDR_TYPE_REDIST 3 + +#define KVM_VGIC_V3_DIST_SIZE SZ_64K +#define KVM_VGIC_V3_REDIST_SIZE (2 * SZ_64K) + #define KVM_ARM_VCPU_POWER_OFF 0 /* CPU is started in OFF state */ #define KVM_ARM_VCPU_PSCI_0_2 1 /* CPU uses PSCI v0.2 */ diff --git a/linux-headers/asm-x86/unistd_32.h b/linux-headers/asm-x86/unistd_32.h index abeaf40d37..d45ea28e15 100644 --- a/linux-headers/asm-x86/unistd_32.h +++ b/linux-headers/asm-x86/unistd_32.h @@ -377,5 +377,8 @@ #define __NR_copy_file_range 377 #define __NR_preadv2 378 #define __NR_pwritev2 379 +#define __NR_pkey_mprotect 380 +#define __NR_pkey_alloc 381 +#define __NR_pkey_free 382 #endif /* _ASM_X86_UNISTD_32_H */ diff --git a/linux-headers/asm-x86/unistd_64.h b/linux-headers/asm-x86/unistd_64.h index 73c3d1f66a..e22db9171e 100644 --- a/linux-headers/asm-x86/unistd_64.h +++ b/linux-headers/asm-x86/unistd_64.h @@ -330,5 +330,8 @@ #define __NR_copy_file_range 326 #define __NR_preadv2 327 #define __NR_pwritev2 328 +#define __NR_pkey_mprotect 329 +#define __NR_pkey_alloc 330 +#define __NR_pkey_free 331 #endif /* _ASM_X86_UNISTD_64_H */ diff --git a/linux-headers/asm-x86/unistd_x32.h b/linux-headers/asm-x86/unistd_x32.h index e5aea761f8..84e58b202d 100644 --- a/linux-headers/asm-x86/unistd_x32.h +++ b/linux-headers/asm-x86/unistd_x32.h @@ -283,6 +283,9 @@ #define __NR_membarrier (__X32_SYSCALL_BIT + 324) #define __NR_mlock2 (__X32_SYSCALL_BIT + 325) #define __NR_copy_file_range (__X32_SYSCALL_BIT + 326) +#define __NR_pkey_mprotect (__X32_SYSCALL_BIT + 329) +#define __NR_pkey_alloc (__X32_SYSCALL_BIT + 330) +#define __NR_pkey_free (__X32_SYSCALL_BIT + 331) #define __NR_rt_sigaction (__X32_SYSCALL_BIT + 512) #define __NR_rt_sigreturn (__X32_SYSCALL_BIT + 513) #define __NR_ioctl (__X32_SYSCALL_BIT + 514) diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h index 4806e069e7..bb0ed71223 100644 --- a/linux-headers/linux/kvm.h +++ b/linux-headers/linux/kvm.h @@ -972,12 +972,19 @@ struct kvm_irqfd { __u8 pad[16]; }; +/* For KVM_CAP_ADJUST_CLOCK */ + +/* Do not use 1, KVM_CHECK_EXTENSION returned it before we had flags. */ +#define KVM_CLOCK_TSC_STABLE 2 + struct kvm_clock_data { __u64 clock; __u32 flags; __u32 pad[9]; }; +/* For KVM_CAP_SW_TLB */ + #define KVM_MMU_FSL_BOOKE_NOHV 0 #define KVM_MMU_FSL_BOOKE_HV 1 diff --git a/linux-user/main.c b/linux-user/main.c index 75b199f274..c1d5eb4d6f 100644 --- a/linux-user/main.c +++ b/linux-user/main.c @@ -2864,6 +2864,13 @@ void cpu_loop(CPUM68KState *env) info._sifields._sigfault._addr = env->pc; queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info); break; + case EXCP_DIV0: + info.si_signo = TARGET_SIGFPE; + info.si_errno = 0; + info.si_code = TARGET_FPE_INTDIV; + info._sifields._sigfault._addr = env->pc; + queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info); + break; case EXCP_TRAP0: { abi_long ret; diff --git a/memory_ldst.inc.c b/memory_ldst.inc.c new file mode 100644 index 0000000000..5dbff9cef8 --- /dev/null +++ b/memory_ldst.inc.c @@ -0,0 +1,709 @@ +/* + * Physical memory access templates + * + * Copyright (c) 2003 Fabrice Bellard + * Copyright (c) 2015 Linaro, Inc. + * Copyright (c) 2016 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * 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/>. + */ + +/* warning: addr must be aligned */ +static inline uint32_t glue(address_space_ldl_internal, SUFFIX)(ARG1_DECL, + hwaddr addr, MemTxAttrs attrs, MemTxResult *result, + enum device_endian endian) +{ + uint8_t *ptr; + uint64_t val; + MemoryRegion *mr; + hwaddr l = 4; + hwaddr addr1; + MemTxResult r; + bool release_lock = false; + + RCU_READ_LOCK(); + mr = TRANSLATE(addr, &addr1, &l, false); + if (l < 4 || !IS_DIRECT(mr, false)) { + release_lock |= prepare_mmio_access(mr); + + /* I/O case */ + r = memory_region_dispatch_read(mr, addr1, &val, 4, attrs); +#if defined(TARGET_WORDS_BIGENDIAN) + if (endian == DEVICE_LITTLE_ENDIAN) { + val = bswap32(val); + } +#else + if (endian == DEVICE_BIG_ENDIAN) { + val = bswap32(val); + } +#endif + } else { + /* RAM case */ + ptr = MAP_RAM(mr, addr1); + switch (endian) { + case DEVICE_LITTLE_ENDIAN: + val = ldl_le_p(ptr); + break; + case DEVICE_BIG_ENDIAN: + val = ldl_be_p(ptr); + break; + default: + val = ldl_p(ptr); + break; + } + r = MEMTX_OK; + } + if (result) { + *result = r; + } + if (release_lock) { + qemu_mutex_unlock_iothread(); + } + RCU_READ_UNLOCK(); + return val; +} + +uint32_t glue(address_space_ldl, SUFFIX)(ARG1_DECL, + hwaddr addr, MemTxAttrs attrs, MemTxResult *result) +{ + return glue(address_space_ldl_internal, SUFFIX)(ARG1, addr, attrs, result, + DEVICE_NATIVE_ENDIAN); +} + +uint32_t glue(address_space_ldl_le, SUFFIX)(ARG1_DECL, + hwaddr addr, MemTxAttrs attrs, MemTxResult *result) +{ + return glue(address_space_ldl_internal, SUFFIX)(ARG1, addr, attrs, result, + DEVICE_LITTLE_ENDIAN); +} + +uint32_t glue(address_space_ldl_be, SUFFIX)(ARG1_DECL, + hwaddr addr, MemTxAttrs attrs, MemTxResult *result) +{ + return glue(address_space_ldl_internal, SUFFIX)(ARG1, addr, attrs, result, + DEVICE_BIG_ENDIAN); +} + +uint32_t glue(ldl_phys, SUFFIX)(ARG1_DECL, hwaddr addr) +{ + return glue(address_space_ldl, SUFFIX)(ARG1, addr, + MEMTXATTRS_UNSPECIFIED, NULL); +} + +uint32_t glue(ldl_le_phys, SUFFIX)(ARG1_DECL, hwaddr addr) +{ + return glue(address_space_ldl_le, SUFFIX)(ARG1, addr, + MEMTXATTRS_UNSPECIFIED, NULL); +} + +uint32_t glue(ldl_be_phys, SUFFIX)(ARG1_DECL, hwaddr addr) +{ + return glue(address_space_ldl_be, SUFFIX)(ARG1, addr, + MEMTXATTRS_UNSPECIFIED, NULL); +} + +/* warning: addr must be aligned */ +static inline uint64_t glue(address_space_ldq_internal, SUFFIX)(ARG1_DECL, + hwaddr addr, MemTxAttrs attrs, MemTxResult *result, + enum device_endian endian) +{ + uint8_t *ptr; + uint64_t val; + MemoryRegion *mr; + hwaddr l = 8; + hwaddr addr1; + MemTxResult r; + bool release_lock = false; + + RCU_READ_LOCK(); + mr = TRANSLATE(addr, &addr1, &l, false); + if (l < 8 || !IS_DIRECT(mr, false)) { + release_lock |= prepare_mmio_access(mr); + + /* I/O case */ + r = memory_region_dispatch_read(mr, addr1, &val, 8, attrs); +#if defined(TARGET_WORDS_BIGENDIAN) + if (endian == DEVICE_LITTLE_ENDIAN) { + val = bswap64(val); + } +#else + if (endian == DEVICE_BIG_ENDIAN) { + val = bswap64(val); + } +#endif + } else { + /* RAM case */ + ptr = MAP_RAM(mr, addr1); + switch (endian) { + case DEVICE_LITTLE_ENDIAN: + val = ldq_le_p(ptr); + break; + case DEVICE_BIG_ENDIAN: + val = ldq_be_p(ptr); + break; + default: + val = ldq_p(ptr); + break; + } + r = MEMTX_OK; + } + if (result) { + *result = r; + } + if (release_lock) { + qemu_mutex_unlock_iothread(); + } + RCU_READ_UNLOCK(); + return val; +} + +uint64_t glue(address_space_ldq, SUFFIX)(ARG1_DECL, + hwaddr addr, MemTxAttrs attrs, MemTxResult *result) +{ + return glue(address_space_ldq_internal, SUFFIX)(ARG1, addr, attrs, result, + DEVICE_NATIVE_ENDIAN); +} + +uint64_t glue(address_space_ldq_le, SUFFIX)(ARG1_DECL, + hwaddr addr, MemTxAttrs attrs, MemTxResult *result) +{ + return glue(address_space_ldq_internal, SUFFIX)(ARG1, addr, attrs, result, + DEVICE_LITTLE_ENDIAN); +} + +uint64_t glue(address_space_ldq_be, SUFFIX)(ARG1_DECL, + hwaddr addr, MemTxAttrs attrs, MemTxResult *result) +{ + return glue(address_space_ldq_internal, SUFFIX)(ARG1, addr, attrs, result, + DEVICE_BIG_ENDIAN); +} + +uint64_t glue(ldq_phys, SUFFIX)(ARG1_DECL, hwaddr addr) +{ + return glue(address_space_ldq, SUFFIX)(ARG1, addr, + MEMTXATTRS_UNSPECIFIED, NULL); +} + +uint64_t glue(ldq_le_phys, SUFFIX)(ARG1_DECL, hwaddr addr) +{ + return glue(address_space_ldq_le, SUFFIX)(ARG1, addr, + MEMTXATTRS_UNSPECIFIED, NULL); +} + +uint64_t glue(ldq_be_phys, SUFFIX)(ARG1_DECL, hwaddr addr) +{ + return glue(address_space_ldq_be, SUFFIX)(ARG1, addr, + MEMTXATTRS_UNSPECIFIED, NULL); +} + +uint32_t glue(address_space_ldub, SUFFIX)(ARG1_DECL, + hwaddr addr, MemTxAttrs attrs, MemTxResult *result) +{ + uint8_t *ptr; + uint64_t val; + MemoryRegion *mr; + hwaddr l = 1; + hwaddr addr1; + MemTxResult r; + bool release_lock = false; + + RCU_READ_LOCK(); + mr = TRANSLATE(addr, &addr1, &l, false); + if (!IS_DIRECT(mr, false)) { + release_lock |= prepare_mmio_access(mr); + + /* I/O case */ + r = memory_region_dispatch_read(mr, addr1, &val, 1, attrs); + } else { + /* RAM case */ + ptr = MAP_RAM(mr, addr1); + val = ldub_p(ptr); + r = MEMTX_OK; + } + if (result) { + *result = r; + } + if (release_lock) { + qemu_mutex_unlock_iothread(); + } + RCU_READ_UNLOCK(); + return val; +} + +uint32_t glue(ldub_phys, SUFFIX)(ARG1_DECL, hwaddr addr) +{ + return glue(address_space_ldub, SUFFIX)(ARG1, addr, + MEMTXATTRS_UNSPECIFIED, NULL); +} + +/* warning: addr must be aligned */ +static inline uint32_t glue(address_space_lduw_internal, SUFFIX)(ARG1_DECL, + hwaddr addr, MemTxAttrs attrs, MemTxResult *result, + enum device_endian endian) +{ + uint8_t *ptr; + uint64_t val; + MemoryRegion *mr; + hwaddr l = 2; + hwaddr addr1; + MemTxResult r; + bool release_lock = false; + + RCU_READ_LOCK(); + mr = TRANSLATE(addr, &addr1, &l, false); + if (l < 2 || !IS_DIRECT(mr, false)) { + release_lock |= prepare_mmio_access(mr); + + /* I/O case */ + r = memory_region_dispatch_read(mr, addr1, &val, 2, attrs); +#if defined(TARGET_WORDS_BIGENDIAN) + if (endian == DEVICE_LITTLE_ENDIAN) { + val = bswap16(val); + } +#else + if (endian == DEVICE_BIG_ENDIAN) { + val = bswap16(val); + } +#endif + } else { + /* RAM case */ + ptr = MAP_RAM(mr, addr1); + switch (endian) { + case DEVICE_LITTLE_ENDIAN: + val = lduw_le_p(ptr); + break; + case DEVICE_BIG_ENDIAN: + val = lduw_be_p(ptr); + break; + default: + val = lduw_p(ptr); + break; + } + r = MEMTX_OK; + } + if (result) { + *result = r; + } + if (release_lock) { + qemu_mutex_unlock_iothread(); + } + RCU_READ_UNLOCK(); + return val; +} + +uint32_t glue(address_space_lduw, SUFFIX)(ARG1_DECL, + hwaddr addr, MemTxAttrs attrs, MemTxResult *result) +{ + return glue(address_space_lduw_internal, SUFFIX)(ARG1, addr, attrs, result, + DEVICE_NATIVE_ENDIAN); +} + +uint32_t glue(address_space_lduw_le, SUFFIX)(ARG1_DECL, + hwaddr addr, MemTxAttrs attrs, MemTxResult *result) +{ + return glue(address_space_lduw_internal, SUFFIX)(ARG1, addr, attrs, result, + DEVICE_LITTLE_ENDIAN); +} + +uint32_t glue(address_space_lduw_be, SUFFIX)(ARG1_DECL, + hwaddr addr, MemTxAttrs attrs, MemTxResult *result) +{ + return glue(address_space_lduw_internal, SUFFIX)(ARG1, addr, attrs, result, + DEVICE_BIG_ENDIAN); +} + +uint32_t glue(lduw_phys, SUFFIX)(ARG1_DECL, hwaddr addr) +{ + return glue(address_space_lduw, SUFFIX)(ARG1, addr, + MEMTXATTRS_UNSPECIFIED, NULL); +} + +uint32_t glue(lduw_le_phys, SUFFIX)(ARG1_DECL, hwaddr addr) +{ + return glue(address_space_lduw_le, SUFFIX)(ARG1, addr, + MEMTXATTRS_UNSPECIFIED, NULL); +} + +uint32_t glue(lduw_be_phys, SUFFIX)(ARG1_DECL, hwaddr addr) +{ + return glue(address_space_lduw_be, SUFFIX)(ARG1, addr, + MEMTXATTRS_UNSPECIFIED, NULL); +} + +/* warning: addr must be aligned. The ram page is not masked as dirty + and the code inside is not invalidated. It is useful if the dirty + bits are used to track modified PTEs */ +void glue(address_space_stl_notdirty, SUFFIX)(ARG1_DECL, + hwaddr addr, uint32_t val, MemTxAttrs attrs, MemTxResult *result) +{ + uint8_t *ptr; + MemoryRegion *mr; + hwaddr l = 4; + hwaddr addr1; + MemTxResult r; + uint8_t dirty_log_mask; + bool release_lock = false; + + RCU_READ_LOCK(); + mr = TRANSLATE(addr, &addr1, &l, true); + if (l < 4 || !IS_DIRECT(mr, true)) { + release_lock |= prepare_mmio_access(mr); + + r = memory_region_dispatch_write(mr, addr1, val, 4, attrs); + } else { + ptr = MAP_RAM(mr, addr1); + stl_p(ptr, val); + + dirty_log_mask = memory_region_get_dirty_log_mask(mr); + dirty_log_mask &= ~(1 << DIRTY_MEMORY_CODE); + cpu_physical_memory_set_dirty_range(memory_region_get_ram_addr(mr) + addr, + 4, dirty_log_mask); + r = MEMTX_OK; + } + if (result) { + *result = r; + } + if (release_lock) { + qemu_mutex_unlock_iothread(); + } + RCU_READ_UNLOCK(); +} + +void glue(stl_phys_notdirty, SUFFIX)(ARG1_DECL, hwaddr addr, uint32_t val) +{ + glue(address_space_stl_notdirty, SUFFIX)(ARG1, addr, val, + MEMTXATTRS_UNSPECIFIED, NULL); +} + +/* warning: addr must be aligned */ +static inline void glue(address_space_stl_internal, SUFFIX)(ARG1_DECL, + hwaddr addr, uint32_t val, MemTxAttrs attrs, + MemTxResult *result, enum device_endian endian) +{ + uint8_t *ptr; + MemoryRegion *mr; + hwaddr l = 4; + hwaddr addr1; + MemTxResult r; + bool release_lock = false; + + RCU_READ_LOCK(); + mr = TRANSLATE(addr, &addr1, &l, true); + if (l < 4 || !IS_DIRECT(mr, true)) { + release_lock |= prepare_mmio_access(mr); + +#if defined(TARGET_WORDS_BIGENDIAN) + if (endian == DEVICE_LITTLE_ENDIAN) { + val = bswap32(val); + } +#else + if (endian == DEVICE_BIG_ENDIAN) { + val = bswap32(val); + } +#endif + r = memory_region_dispatch_write(mr, addr1, val, 4, attrs); + } else { + /* RAM case */ + ptr = MAP_RAM(mr, addr1); + switch (endian) { + case DEVICE_LITTLE_ENDIAN: + stl_le_p(ptr, val); + break; + case DEVICE_BIG_ENDIAN: + stl_be_p(ptr, val); + break; + default: + stl_p(ptr, val); + break; + } + INVALIDATE(mr, addr1, 4); + r = MEMTX_OK; + } + if (result) { + *result = r; + } + if (release_lock) { + qemu_mutex_unlock_iothread(); + } + RCU_READ_UNLOCK(); +} + +void glue(address_space_stl, SUFFIX)(ARG1_DECL, + hwaddr addr, uint32_t val, MemTxAttrs attrs, MemTxResult *result) +{ + glue(address_space_stl_internal, SUFFIX)(ARG1, addr, val, attrs, + result, DEVICE_NATIVE_ENDIAN); +} + +void glue(address_space_stl_le, SUFFIX)(ARG1_DECL, + hwaddr addr, uint32_t val, MemTxAttrs attrs, MemTxResult *result) +{ + glue(address_space_stl_internal, SUFFIX)(ARG1, addr, val, attrs, + result, DEVICE_LITTLE_ENDIAN); +} + +void glue(address_space_stl_be, SUFFIX)(ARG1_DECL, + hwaddr addr, uint32_t val, MemTxAttrs attrs, MemTxResult *result) +{ + glue(address_space_stl_internal, SUFFIX)(ARG1, addr, val, attrs, + result, DEVICE_BIG_ENDIAN); +} + +void glue(stl_phys, SUFFIX)(ARG1_DECL, hwaddr addr, uint32_t val) +{ + glue(address_space_stl, SUFFIX)(ARG1, addr, val, + MEMTXATTRS_UNSPECIFIED, NULL); +} + +void glue(stl_le_phys, SUFFIX)(ARG1_DECL, hwaddr addr, uint32_t val) +{ + glue(address_space_stl_le, SUFFIX)(ARG1, addr, val, + MEMTXATTRS_UNSPECIFIED, NULL); +} + +void glue(stl_be_phys, SUFFIX)(ARG1_DECL, hwaddr addr, uint32_t val) +{ + glue(address_space_stl_be, SUFFIX)(ARG1, addr, val, + MEMTXATTRS_UNSPECIFIED, NULL); +} + +void glue(address_space_stb, SUFFIX)(ARG1_DECL, + hwaddr addr, uint32_t val, MemTxAttrs attrs, MemTxResult *result) +{ + uint8_t *ptr; + MemoryRegion *mr; + hwaddr l = 1; + hwaddr addr1; + MemTxResult r; + bool release_lock = false; + + RCU_READ_LOCK(); + mr = TRANSLATE(addr, &addr1, &l, true); + if (!IS_DIRECT(mr, true)) { + release_lock |= prepare_mmio_access(mr); + r = memory_region_dispatch_write(mr, addr1, val, 1, attrs); + } else { + /* RAM case */ + ptr = MAP_RAM(mr, addr1); + stb_p(ptr, val); + INVALIDATE(mr, addr1, 1); + r = MEMTX_OK; + } + if (result) { + *result = r; + } + if (release_lock) { + qemu_mutex_unlock_iothread(); + } + RCU_READ_UNLOCK(); +} + +void glue(stb_phys, SUFFIX)(ARG1_DECL, hwaddr addr, uint32_t val) +{ + glue(address_space_stb, SUFFIX)(ARG1, addr, val, + MEMTXATTRS_UNSPECIFIED, NULL); +} + +/* warning: addr must be aligned */ +static inline void glue(address_space_stw_internal, SUFFIX)(ARG1_DECL, + hwaddr addr, uint32_t val, MemTxAttrs attrs, + MemTxResult *result, enum device_endian endian) +{ + uint8_t *ptr; + MemoryRegion *mr; + hwaddr l = 2; + hwaddr addr1; + MemTxResult r; + bool release_lock = false; + + RCU_READ_LOCK(); + mr = TRANSLATE(addr, &addr1, &l, true); + if (l < 2 || !IS_DIRECT(mr, true)) { + release_lock |= prepare_mmio_access(mr); + +#if defined(TARGET_WORDS_BIGENDIAN) + if (endian == DEVICE_LITTLE_ENDIAN) { + val = bswap16(val); + } +#else + if (endian == DEVICE_BIG_ENDIAN) { + val = bswap16(val); + } +#endif + r = memory_region_dispatch_write(mr, addr1, val, 2, attrs); + } else { + /* RAM case */ + ptr = MAP_RAM(mr, addr1); + switch (endian) { + case DEVICE_LITTLE_ENDIAN: + stw_le_p(ptr, val); + break; + case DEVICE_BIG_ENDIAN: + stw_be_p(ptr, val); + break; + default: + stw_p(ptr, val); + break; + } + INVALIDATE(mr, addr1, 2); + r = MEMTX_OK; + } + if (result) { + *result = r; + } + if (release_lock) { + qemu_mutex_unlock_iothread(); + } + RCU_READ_UNLOCK(); +} + +void glue(address_space_stw, SUFFIX)(ARG1_DECL, + hwaddr addr, uint32_t val, MemTxAttrs attrs, MemTxResult *result) +{ + glue(address_space_stw_internal, SUFFIX)(ARG1, addr, val, attrs, result, + DEVICE_NATIVE_ENDIAN); +} + +void glue(address_space_stw_le, SUFFIX)(ARG1_DECL, + hwaddr addr, uint32_t val, MemTxAttrs attrs, MemTxResult *result) +{ + glue(address_space_stw_internal, SUFFIX)(ARG1, addr, val, attrs, result, + DEVICE_LITTLE_ENDIAN); +} + +void glue(address_space_stw_be, SUFFIX)(ARG1_DECL, + hwaddr addr, uint32_t val, MemTxAttrs attrs, MemTxResult *result) +{ + glue(address_space_stw_internal, SUFFIX)(ARG1, addr, val, attrs, result, + DEVICE_BIG_ENDIAN); +} + +void glue(stw_phys, SUFFIX)(ARG1_DECL, hwaddr addr, uint32_t val) +{ + glue(address_space_stw, SUFFIX)(ARG1, addr, val, + MEMTXATTRS_UNSPECIFIED, NULL); +} + +void glue(stw_le_phys, SUFFIX)(ARG1_DECL, hwaddr addr, uint32_t val) +{ + glue(address_space_stw_le, SUFFIX)(ARG1, addr, val, + MEMTXATTRS_UNSPECIFIED, NULL); +} + +void glue(stw_be_phys, SUFFIX)(ARG1_DECL, hwaddr addr, uint32_t val) +{ + glue(address_space_stw_be, SUFFIX)(ARG1, addr, val, + MEMTXATTRS_UNSPECIFIED, NULL); +} + +static void glue(address_space_stq_internal, SUFFIX)(ARG1_DECL, + hwaddr addr, uint64_t val, MemTxAttrs attrs, + MemTxResult *result, enum device_endian endian) +{ + uint8_t *ptr; + MemoryRegion *mr; + hwaddr l = 8; + hwaddr addr1; + MemTxResult r; + bool release_lock = false; + + RCU_READ_LOCK(); + mr = TRANSLATE(addr, &addr1, &l, true); + if (l < 8 || !IS_DIRECT(mr, true)) { + release_lock |= prepare_mmio_access(mr); + +#if defined(TARGET_WORDS_BIGENDIAN) + if (endian == DEVICE_LITTLE_ENDIAN) { + val = bswap64(val); + } +#else + if (endian == DEVICE_BIG_ENDIAN) { + val = bswap64(val); + } +#endif + r = memory_region_dispatch_write(mr, addr1, val, 8, attrs); + } else { + /* RAM case */ + ptr = MAP_RAM(mr, addr1); + switch (endian) { + case DEVICE_LITTLE_ENDIAN: + stq_le_p(ptr, val); + break; + case DEVICE_BIG_ENDIAN: + stq_be_p(ptr, val); + break; + default: + stq_p(ptr, val); + break; + } + INVALIDATE(mr, addr1, 8); + r = MEMTX_OK; + } + if (result) { + *result = r; + } + if (release_lock) { + qemu_mutex_unlock_iothread(); + } + RCU_READ_UNLOCK(); +} + +void glue(address_space_stq, SUFFIX)(ARG1_DECL, + hwaddr addr, uint64_t val, MemTxAttrs attrs, MemTxResult *result) +{ + glue(address_space_stq_internal, SUFFIX)(ARG1, addr, val, attrs, result, + DEVICE_NATIVE_ENDIAN); +} + +void glue(address_space_stq_le, SUFFIX)(ARG1_DECL, + hwaddr addr, uint64_t val, MemTxAttrs attrs, MemTxResult *result) +{ + glue(address_space_stq_internal, SUFFIX)(ARG1, addr, val, attrs, result, + DEVICE_LITTLE_ENDIAN); +} + +void glue(address_space_stq_be, SUFFIX)(ARG1_DECL, + hwaddr addr, uint64_t val, MemTxAttrs attrs, MemTxResult *result) +{ + glue(address_space_stq_internal, SUFFIX)(ARG1, addr, val, attrs, result, + DEVICE_BIG_ENDIAN); +} + +void glue(stq_phys, SUFFIX)(ARG1_DECL, hwaddr addr, uint64_t val) +{ + glue(address_space_stq, SUFFIX)(ARG1, addr, val, + MEMTXATTRS_UNSPECIFIED, NULL); +} + +void glue(stq_le_phys, SUFFIX)(ARG1_DECL, hwaddr addr, uint64_t val) +{ + glue(address_space_stq_le, SUFFIX)(ARG1, addr, val, + MEMTXATTRS_UNSPECIFIED, NULL); +} + +void glue(stq_be_phys, SUFFIX)(ARG1_DECL, hwaddr addr, uint64_t val) +{ + glue(address_space_stq_be, SUFFIX)(ARG1, addr, val, + MEMTXATTRS_UNSPECIFIED, NULL); +} + +#undef ARG1_DECL +#undef ARG1 +#undef SUFFIX +#undef TRANSLATE +#undef IS_DIRECT +#undef MAP_RAM +#undef INVALIDATE +#undef RCU_READ_LOCK +#undef RCU_READ_UNLOCK diff --git a/qapi/crypto.json b/qapi/crypto.json index 15d296e3c1..f4fd93b813 100644 --- a/qapi/crypto.json +++ b/qapi/crypto.json @@ -63,6 +63,7 @@ # @aes-192: AES with 192 bit / 24 byte keys # @aes-256: AES with 256 bit / 32 byte keys # @des-rfb: RFB specific variant of single DES. Do not use except in VNC. +# @3des: 3DES(EDE) with 192 bit / 24 byte keys (since 2.9) # @cast5-128: Cast5 with 128 bit / 16 byte keys # @serpent-128: Serpent with 128 bit / 16 byte keys # @serpent-192: Serpent with 192 bit / 24 byte keys @@ -75,7 +76,7 @@ { 'enum': 'QCryptoCipherAlgorithm', 'prefix': 'QCRYPTO_CIPHER_ALG', 'data': ['aes-128', 'aes-192', 'aes-256', - 'des-rfb', + 'des-rfb', '3des', 'cast5-128', 'serpent-128', 'serpent-192', 'serpent-256', 'twofish-128', 'twofish-192', 'twofish-256']} diff --git a/qemu-timer.c b/qemu-timer.c index 9299cdc5fb..ff620ecff7 100644 --- a/qemu-timer.c +++ b/qemu-timer.c @@ -174,7 +174,7 @@ void qemu_clock_enable(QEMUClockType type, bool enabled) bool timerlist_has_timers(QEMUTimerList *timer_list) { - return !!timer_list->active_timers; + return !!atomic_read(&timer_list->active_timers); } bool qemu_clock_has_timers(QEMUClockType type) @@ -187,6 +187,10 @@ bool timerlist_expired(QEMUTimerList *timer_list) { int64_t expire_time; + if (!atomic_read(&timer_list->active_timers)) { + return false; + } + qemu_mutex_lock(&timer_list->active_timers_lock); if (!timer_list->active_timers) { qemu_mutex_unlock(&timer_list->active_timers_lock); @@ -214,6 +218,10 @@ int64_t timerlist_deadline_ns(QEMUTimerList *timer_list) int64_t delta; int64_t expire_time; + if (!atomic_read(&timer_list->active_timers)) { + return -1; + } + if (!timer_list->clock->enabled) { return -1; } @@ -363,7 +371,7 @@ static void timer_del_locked(QEMUTimerList *timer_list, QEMUTimer *ts) if (!t) break; if (t == ts) { - *pt = t->next; + atomic_set(pt, t->next); break; } pt = &t->next; @@ -386,7 +394,7 @@ static bool timer_mod_ns_locked(QEMUTimerList *timer_list, } ts->expire_time = MAX(expire_time, 0); ts->next = *pt; - *pt = ts; + atomic_set(pt, ts); return pt == &timer_list->active_timers; } @@ -481,8 +489,12 @@ bool timerlist_run_timers(QEMUTimerList *timer_list) QEMUTimerCB *cb; void *opaque; + if (!atomic_read(&timer_list->active_timers)) { + return false; + } + qemu_event_reset(&timer_list->timers_done_ev); - if (!timer_list->clock->enabled || !timer_list->active_timers) { + if (!timer_list->clock->enabled) { goto out; } @@ -7,6 +7,10 @@ MAKEFLAGS += -rR # Files with this suffixes are final, don't try to generate them # using implicit rules +%/trace-events: +%.hx: +%.py: +%.objs: %.d: %.h: %.c: @@ -192,15 +196,15 @@ clean: clean-timestamp # save-vars # Usage: $(call save-vars, vars) # Save each variable $v in $vars as save-vars-$v, save their object's -# variables, then clear $v. +# variables, then clear $v. saved-vars-$v contains the variables that +# where saved for the objects, in order to speedup load-vars. define save-vars $(foreach v,$1, $(eval save-vars-$v := $(value $v)) - $(foreach o,$($v), - $(foreach k,cflags libs objs, - $(if $($o-$k), - $(eval save-vars-$o-$k := $($o-$k)) - $(eval $o-$k := )))) + $(eval saved-vars-$v := $(foreach o,$($v), \ + $(if $($o-cflags), $o-cflags $(eval save-vars-$o-cflags := $($o-cflags))$(eval $o-cflags := )) \ + $(if $($o-libs), $o-libs $(eval save-vars-$o-libs := $($o-libs))$(eval $o-libs := )) \ + $(if $($o-objs), $o-objs $(eval save-vars-$o-objs := $($o-objs))$(eval $o-objs := )))) $(eval $v := )) endef @@ -213,12 +217,10 @@ define load-vars $(eval $2-new-value := $(value $2)) $(foreach v,$1, $(eval $v := $(value save-vars-$v)) - $(foreach o,$($v), - $(foreach k,cflags libs objs, - $(if $(save-vars-$o-$k), - $(eval $o-$k := $(save-vars-$o-$k)) - $(eval save-vars-$o-$k := )))) - $(eval save-vars-$v := )) + $(foreach o,$(saved-vars-$v), + $(eval $o := $(save-vars-$o)) $(eval save-vars-$o := )) + $(eval save-vars-$v := ) + $(eval saved-vars-$v := )) $(eval $2 := $(value $2) $($2-new-value)) endef diff --git a/scripts/analyze-inclusions b/scripts/analyze-inclusions index a8108d9b88..14806e18c6 100644 --- a/scripts/analyze-inclusions +++ b/scripts/analyze-inclusions @@ -48,7 +48,7 @@ grep_include() { echo Found $(find . -name "*.d" | wc -l) object files echo $(grep_include -F 'include/qemu-common.h') files include qemu-common.h echo $(grep_include -F 'hw/hw.h') files include hw/hw.h -echo $(grep_include 'target-[a-z0-9]*/cpu\.h') files include cpu.h +echo $(grep_include 'target/[a-z0-9]*/cpu\.h') files include cpu.h echo $(grep_include -F 'qapi-types.h') files include qapi-types.h echo $(grep_include -F 'trace/generated-tracers.h') files include generated-tracers.h echo $(grep_include -F 'qapi/error.h') files include qapi/error.h @@ -95,8 +95,8 @@ analyze -include ../include/qemu/osdep.h ../include/hw/hw.h echo trace/generated-tracers.h: analyze -include ../include/qemu/osdep.h trace/generated-tracers.h -echo target-i386/cpu.h: -analyze -DNEED_CPU_H -I../target-i386 -Ii386-softmmu -include ../include/qemu/osdep.h ../target-i386/cpu.h +echo target/i386/cpu.h: +analyze -DNEED_CPU_H -I../target/i386 -Ii386-softmmu -include ../include/qemu/osdep.h ../target/i386/cpu.h echo hw/hw.h + NEED_CPU_H: -analyze -DNEED_CPU_H -I../target-i386 -Ii386-softmmu -include ../include/qemu/osdep.h ../include/hw/hw.h +analyze -DNEED_CPU_H -I../target/i386 -Ii386-softmmu -include ../include/qemu/osdep.h ../include/hw/hw.h diff --git a/slirp/dhcpv6.c b/slirp/dhcpv6.c index 02c51c7756..d266611e85 100644 --- a/slirp/dhcpv6.c +++ b/slirp/dhcpv6.c @@ -168,7 +168,7 @@ static void dhcpv6_info_request(Slirp *slirp, struct sockaddr_in6 *srcsas, sa[0], sa[1], sa[2], sa[3], sa[4], sa[5], sa[6], sa[7], sa[8], sa[9], sa[10], sa[11], sa[12], sa[13], sa[14], sa[15], slirp->bootp_filename); - slen = min(slen, smaxlen); + slen = MIN(slen, smaxlen); *resp++ = slen >> 8; /* option-len high byte */ *resp++ = slen; /* option-len low byte */ resp += slen; diff --git a/slirp/ip6_icmp.c b/slirp/ip6_icmp.c index 6d18e28985..298a48dd25 100644 --- a/slirp/ip6_icmp.c +++ b/slirp/ip6_icmp.c @@ -95,7 +95,7 @@ void icmp6_send_error(struct mbuf *m, uint8_t type, uint8_t code) #endif rip->ip_nh = IPPROTO_ICMPV6; - const int error_data_len = min(m->m_len, + const int error_data_len = MIN(m->m_len, IF_MTU - (sizeof(struct ip6) + ICMP6_ERROR_MINLEN)); rip->ip_pl = htons(ICMP6_ERROR_MINLEN + error_data_len); t->m_len = sizeof(struct ip6) + ntohs(rip->ip_pl); diff --git a/slirp/slirp.c b/slirp/slirp.c index 6e2b4e5a90..60539de7a3 100644 --- a/slirp/slirp.c +++ b/slirp/slirp.c @@ -774,7 +774,7 @@ void slirp_pollfds_poll(GArray *pollfds, int select_error) static void arp_input(Slirp *slirp, const uint8_t *pkt, int pkt_len) { struct slirp_arphdr *ah = (struct slirp_arphdr *)(pkt + ETH_HLEN); - uint8_t arp_reply[max(ETH_HLEN + sizeof(struct slirp_arphdr), 64)]; + uint8_t arp_reply[MAX(ETH_HLEN + sizeof(struct slirp_arphdr), 64)]; struct ethhdr *reh = (struct ethhdr *)arp_reply; struct slirp_arphdr *rah = (struct slirp_arphdr *)(arp_reply + ETH_HLEN); int ar_op; diff --git a/slirp/slirp.h b/slirp/slirp.h index a1f3139134..3877f667f0 100644 --- a/slirp/slirp.h +++ b/slirp/slirp.h @@ -292,9 +292,4 @@ int tcp_emu(struct socket *, struct mbuf *); int tcp_ctl(struct socket *); struct tcpcb *tcp_drop(struct tcpcb *tp, int err); -#ifndef _WIN32 -#define min(x,y) ((x) < (y) ? (x) : (y)) -#define max(x,y) ((x) > (y) ? (x) : (y)) -#endif - #endif diff --git a/slirp/tcp_input.c b/slirp/tcp_input.c index c5063a918d..edb98f06f3 100644 --- a/slirp/tcp_input.c +++ b/slirp/tcp_input.c @@ -596,7 +596,7 @@ findso: win = sbspace(&so->so_rcv); if (win < 0) win = 0; - tp->rcv_wnd = max(win, (int)(tp->rcv_adv - tp->rcv_nxt)); + tp->rcv_wnd = MAX(win, (int)(tp->rcv_adv - tp->rcv_nxt)); } switch (tp->t_state) { @@ -1065,8 +1065,8 @@ trimthenstep6: else if (++tp->t_dupacks == TCPREXMTTHRESH) { tcp_seq onxt = tp->snd_nxt; u_int win = - min(tp->snd_wnd, tp->snd_cwnd) / 2 / - tp->t_maxseg; + MIN(tp->snd_wnd, tp->snd_cwnd) / + 2 / tp->t_maxseg; if (win < 2) win = 2; @@ -1138,7 +1138,7 @@ trimthenstep6: if (cw > tp->snd_ssthresh) incr = incr * incr / cw; - tp->snd_cwnd = min(cw + incr, TCP_MAXWIN<<tp->snd_scale); + tp->snd_cwnd = MIN(cw + incr, TCP_MAXWIN << tp->snd_scale); } if (acked > so->so_snd.sb_cc) { tp->snd_wnd -= so->so_snd.sb_cc; @@ -1586,11 +1586,11 @@ tcp_mss(struct tcpcb *tp, u_int offer) switch (so->so_ffamily) { case AF_INET: - mss = min(IF_MTU, IF_MRU) - sizeof(struct tcphdr) + mss = MIN(IF_MTU, IF_MRU) - sizeof(struct tcphdr) + sizeof(struct ip); break; case AF_INET6: - mss = min(IF_MTU, IF_MRU) - sizeof(struct tcphdr) + mss = MIN(IF_MTU, IF_MRU) - sizeof(struct tcphdr) + sizeof(struct ip6); break; default: @@ -1598,8 +1598,8 @@ tcp_mss(struct tcpcb *tp, u_int offer) } if (offer) - mss = min(mss, offer); - mss = max(mss, 32); + mss = MIN(mss, offer); + mss = MAX(mss, 32); if (mss < tp->t_maxseg || offer != 0) tp->t_maxseg = mss; diff --git a/slirp/tcp_output.c b/slirp/tcp_output.c index 819db27348..90b5c376f7 100644 --- a/slirp/tcp_output.c +++ b/slirp/tcp_output.c @@ -88,7 +88,7 @@ tcp_output(struct tcpcb *tp) again: sendalot = 0; off = tp->snd_nxt - tp->snd_una; - win = min(tp->snd_wnd, tp->snd_cwnd); + win = MIN(tp->snd_wnd, tp->snd_cwnd); flags = tcp_outflags[tp->t_state]; @@ -127,7 +127,7 @@ again: } } - len = min(so->so_snd.sb_cc, win) - off; + len = MIN(so->so_snd.sb_cc, win) - off; if (len < 0) { /* @@ -193,7 +193,7 @@ again: * taking into account that we are limited by * TCP_MAXWIN << tp->rcv_scale. */ - long adv = min(win, (long)TCP_MAXWIN << tp->rcv_scale) - + long adv = MIN(win, (long)TCP_MAXWIN << tp->rcv_scale) - (tp->rcv_adv - tp->rcv_nxt); if (adv >= (long) (2 * tp->t_maxseg)) diff --git a/slirp/tcp_timer.c b/slirp/tcp_timer.c index f9060c7bf8..52ef5f9100 100644 --- a/slirp/tcp_timer.c +++ b/slirp/tcp_timer.c @@ -233,7 +233,7 @@ tcp_timers(register struct tcpcb *tp, int timer) * to go below this.) */ { - u_int win = min(tp->snd_wnd, tp->snd_cwnd) / 2 / tp->t_maxseg; + u_int win = MIN(tp->snd_wnd, tp->snd_cwnd) / 2 / tp->t_maxseg; if (win < 2) win = 2; tp->snd_cwnd = tp->t_maxseg; diff --git a/slirp/tcpip.h b/slirp/tcpip.h index 7bdb971c5d..07dbf2c432 100644 --- a/slirp/tcpip.h +++ b/slirp/tcpip.h @@ -85,7 +85,7 @@ struct tcpiphdr { /* This is the difference between the size of a tcpiphdr structure, and the * size of actual ip+tcp headers, rounded up since we need to align data. */ #define TCPIPHDR_DELTA\ - (max(0,\ + (MAX(0,\ (sizeof(struct tcpiphdr)\ - sizeof(struct ip) - sizeof(struct tcphdr) + 3) & ~3)) diff --git a/slirp/tftp.c b/slirp/tftp.c index c1859066cc..50e714807d 100644 --- a/slirp/tftp.c +++ b/slirp/tftp.c @@ -72,6 +72,7 @@ static int tftp_session_allocate(Slirp *slirp, struct sockaddr_storage *srcsas, memset(spt, 0, sizeof(*spt)); spt->client_addr = *srcsas; spt->fd = -1; + spt->block_size = 512; spt->client_port = tp->udp.uh_sport; spt->slirp = slirp; @@ -115,7 +116,7 @@ static int tftp_read_data(struct tftp_session *spt, uint32_t block_nr, } if (len) { - lseek(spt->fd, block_nr * 512, SEEK_SET); + lseek(spt->fd, block_nr * spt->block_size, SEEK_SET); bytes_read = read(spt->fd, buf, len); } @@ -189,7 +190,8 @@ static int tftp_send_oack(struct tftp_session *spt, values[i]) + 1; } - m->m_len = sizeof(struct tftp_t) - 514 + n - sizeof(struct udphdr); + m->m_len = sizeof(struct tftp_t) - (TFTP_BLOCKSIZE_MAX + 2) + n + - sizeof(struct udphdr); tftp_udp_output(spt, m, recv_tp); return 0; @@ -214,7 +216,7 @@ static void tftp_send_error(struct tftp_session *spt, tp->x.tp_error.tp_error_code = htons(errorcode); pstrcpy((char *)tp->x.tp_error.tp_msg, sizeof(tp->x.tp_error.tp_msg), msg); - m->m_len = sizeof(struct tftp_t) - 514 + 3 + strlen(msg) + m->m_len = sizeof(struct tftp_t) - (TFTP_BLOCKSIZE_MAX + 2) + 3 + strlen(msg) - sizeof(struct udphdr); tftp_udp_output(spt, m, recv_tp); @@ -240,7 +242,8 @@ static void tftp_send_next_block(struct tftp_session *spt, tp->tp_op = htons(TFTP_DATA); tp->x.tp_data.tp_block_nr = htons((spt->block_nr + 1) & 0xffff); - nobytes = tftp_read_data(spt, spt->block_nr, tp->x.tp_data.tp_buf, 512); + nobytes = tftp_read_data(spt, spt->block_nr, tp->x.tp_data.tp_buf, + spt->block_size); if (nobytes < 0) { m_free(m); @@ -252,10 +255,11 @@ static void tftp_send_next_block(struct tftp_session *spt, return; } - m->m_len = sizeof(struct tftp_t) - (512 - nobytes) - sizeof(struct udphdr); + m->m_len = sizeof(struct tftp_t) - (TFTP_BLOCKSIZE_MAX - nobytes) + - sizeof(struct udphdr); tftp_udp_output(spt, m, recv_tp); - if (nobytes == 512) { + if (nobytes == spt->block_size) { tftp_session_update(spt); } else { @@ -385,13 +389,11 @@ static void tftp_handle_rrq(Slirp *slirp, struct sockaddr_storage *srcsas, } else if (strcasecmp(key, "blksize") == 0) { int blksize = atoi(value); - /* If blksize option is bigger than what we will - * emit, accept the option with our packet size. - * Otherwise, simply do as we didn't see the option. - */ - if (blksize >= 512) { + /* Accept blksize up to our maximum size */ + if (blksize > 0) { + spt->block_size = MIN(blksize, TFTP_BLOCKSIZE_MAX); option_name[nb_options] = "blksize"; - option_value[nb_options] = 512; + option_value[nb_options] = spt->block_size; nb_options++; } } diff --git a/slirp/tftp.h b/slirp/tftp.h index 2cd276dec6..a4c4a64e64 100644 --- a/slirp/tftp.h +++ b/slirp/tftp.h @@ -15,6 +15,7 @@ #define TFTP_OACK 6 #define TFTP_FILENAME_MAX 512 +#define TFTP_BLOCKSIZE_MAX 1428 struct tftp_t { struct udphdr udp; @@ -22,13 +23,13 @@ struct tftp_t { union { struct { uint16_t tp_block_nr; - uint8_t tp_buf[512]; + uint8_t tp_buf[TFTP_BLOCKSIZE_MAX]; } tp_data; struct { uint16_t tp_error_code; - uint8_t tp_msg[512]; + uint8_t tp_msg[TFTP_BLOCKSIZE_MAX]; } tp_error; - char tp_buf[512 + 2]; + char tp_buf[TFTP_BLOCKSIZE_MAX + 2]; } x; } __attribute__((packed)); @@ -36,6 +37,7 @@ struct tftp_session { Slirp *slirp; char *filename; int fd; + uint16_t block_size; struct sockaddr_storage client_addr; uint16_t client_port; diff --git a/target-m68k/op_helper.c b/target-m68k/op_helper.c deleted file mode 100644 index 48e02e4062..0000000000 --- a/target-m68k/op_helper.c +++ /dev/null @@ -1,229 +0,0 @@ -/* - * M68K helper routines - * - * Copyright (c) 2007 CodeSourcery - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * 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 "qemu/osdep.h" -#include "cpu.h" -#include "exec/helper-proto.h" -#include "exec/exec-all.h" -#include "exec/cpu_ldst.h" -#include "exec/semihost.h" - -#if defined(CONFIG_USER_ONLY) - -void m68k_cpu_do_interrupt(CPUState *cs) -{ - cs->exception_index = -1; -} - -static inline void do_interrupt_m68k_hardirq(CPUM68KState *env) -{ -} - -#else - -/* Try to fill the TLB and return an exception if error. If retaddr is - NULL, it means that the function was called in C code (i.e. not - from generated code or from helper.c) */ -void tlb_fill(CPUState *cs, target_ulong addr, MMUAccessType access_type, - int mmu_idx, uintptr_t retaddr) -{ - int ret; - - ret = m68k_cpu_handle_mmu_fault(cs, addr, access_type, mmu_idx); - if (unlikely(ret)) { - if (retaddr) { - /* now we have a real cpu fault */ - cpu_restore_state(cs, retaddr); - } - cpu_loop_exit(cs); - } -} - -static void do_rte(CPUM68KState *env) -{ - uint32_t sp; - uint32_t fmt; - - sp = env->aregs[7]; - fmt = cpu_ldl_kernel(env, sp); - env->pc = cpu_ldl_kernel(env, sp + 4); - sp |= (fmt >> 28) & 3; - env->aregs[7] = sp + 8; - - helper_set_sr(env, fmt); -} - -static void do_interrupt_all(CPUM68KState *env, int is_hw) -{ - CPUState *cs = CPU(m68k_env_get_cpu(env)); - uint32_t sp; - uint32_t fmt; - uint32_t retaddr; - uint32_t vector; - - fmt = 0; - retaddr = env->pc; - - if (!is_hw) { - switch (cs->exception_index) { - case EXCP_RTE: - /* Return from an exception. */ - do_rte(env); - return; - case EXCP_HALT_INSN: - if (semihosting_enabled() - && (env->sr & SR_S) != 0 - && (env->pc & 3) == 0 - && cpu_lduw_code(env, env->pc - 4) == 0x4e71 - && cpu_ldl_code(env, env->pc) == 0x4e7bf000) { - env->pc += 4; - do_m68k_semihosting(env, env->dregs[0]); - return; - } - cs->halted = 1; - cs->exception_index = EXCP_HLT; - cpu_loop_exit(cs); - return; - } - if (cs->exception_index >= EXCP_TRAP0 - && cs->exception_index <= EXCP_TRAP15) { - /* Move the PC after the trap instruction. */ - retaddr += 2; - } - } - - vector = cs->exception_index << 2; - - fmt |= 0x40000000; - fmt |= vector << 16; - fmt |= env->sr; - fmt |= cpu_m68k_get_ccr(env); - - env->sr |= SR_S; - if (is_hw) { - env->sr = (env->sr & ~SR_I) | (env->pending_level << SR_I_SHIFT); - env->sr &= ~SR_M; - } - m68k_switch_sp(env); - sp = env->aregs[7]; - fmt |= (sp & 3) << 28; - - /* ??? This could cause MMU faults. */ - sp &= ~3; - sp -= 4; - cpu_stl_kernel(env, sp, retaddr); - sp -= 4; - cpu_stl_kernel(env, sp, fmt); - env->aregs[7] = sp; - /* Jump to vector. */ - env->pc = cpu_ldl_kernel(env, env->vbr + vector); -} - -void m68k_cpu_do_interrupt(CPUState *cs) -{ - M68kCPU *cpu = M68K_CPU(cs); - CPUM68KState *env = &cpu->env; - - do_interrupt_all(env, 0); -} - -static inline void do_interrupt_m68k_hardirq(CPUM68KState *env) -{ - do_interrupt_all(env, 1); -} -#endif - -bool m68k_cpu_exec_interrupt(CPUState *cs, int interrupt_request) -{ - M68kCPU *cpu = M68K_CPU(cs); - CPUM68KState *env = &cpu->env; - - if (interrupt_request & CPU_INTERRUPT_HARD - && ((env->sr & SR_I) >> SR_I_SHIFT) < env->pending_level) { - /* Real hardware gets the interrupt vector via an IACK cycle - at this point. Current emulated hardware doesn't rely on - this, so we provide/save the vector when the interrupt is - first signalled. */ - cs->exception_index = env->pending_vector; - do_interrupt_m68k_hardirq(env); - return true; - } - return false; -} - -static void raise_exception(CPUM68KState *env, int tt) -{ - CPUState *cs = CPU(m68k_env_get_cpu(env)); - - cs->exception_index = tt; - cpu_loop_exit(cs); -} - -void HELPER(raise_exception)(CPUM68KState *env, uint32_t tt) -{ - raise_exception(env, tt); -} - -void HELPER(divu)(CPUM68KState *env, uint32_t word) -{ - uint32_t num; - uint32_t den; - uint32_t quot; - uint32_t rem; - - num = env->div1; - den = env->div2; - /* ??? This needs to make sure the throwing location is accurate. */ - if (den == 0) { - raise_exception(env, EXCP_DIV0); - } - quot = num / den; - rem = num % den; - - env->cc_v = (word && quot > 0xffff ? -1 : 0); - env->cc_z = quot; - env->cc_n = quot; - env->cc_c = 0; - - env->div1 = quot; - env->div2 = rem; -} - -void HELPER(divs)(CPUM68KState *env, uint32_t word) -{ - int32_t num; - int32_t den; - int32_t quot; - int32_t rem; - - num = env->div1; - den = env->div2; - if (den == 0) { - raise_exception(env, EXCP_DIV0); - } - quot = num / den; - rem = num % den; - - env->cc_v = (word && quot != (int16_t)quot ? -1 : 0); - env->cc_z = quot; - env->cc_n = quot; - env->cc_c = 0; - - env->div1 = quot; - env->div2 = rem; -} diff --git a/target-alpha/Makefile.objs b/target/alpha/Makefile.objs index 63664629f6..63664629f6 100644 --- a/target-alpha/Makefile.objs +++ b/target/alpha/Makefile.objs diff --git a/target-alpha/STATUS b/target/alpha/STATUS index 6c9744569e..6c9744569e 100644 --- a/target-alpha/STATUS +++ b/target/alpha/STATUS diff --git a/target-alpha/cpu-qom.h b/target/alpha/cpu-qom.h index bae4945344..bae4945344 100644 --- a/target-alpha/cpu-qom.h +++ b/target/alpha/cpu-qom.h diff --git a/target-alpha/cpu.c b/target/alpha/cpu.c index 30d77ce71c..30d77ce71c 100644 --- a/target-alpha/cpu.c +++ b/target/alpha/cpu.c diff --git a/target-alpha/cpu.h b/target/alpha/cpu.h index b08d1601d1..b08d1601d1 100644 --- a/target-alpha/cpu.h +++ b/target/alpha/cpu.h diff --git a/target-alpha/fpu_helper.c b/target/alpha/fpu_helper.c index 9645978aaa..9645978aaa 100644 --- a/target-alpha/fpu_helper.c +++ b/target/alpha/fpu_helper.c diff --git a/target-alpha/gdbstub.c b/target/alpha/gdbstub.c index d64bcccfa0..d64bcccfa0 100644 --- a/target-alpha/gdbstub.c +++ b/target/alpha/gdbstub.c diff --git a/target-alpha/helper.c b/target/alpha/helper.c index a5c308859b..a5c308859b 100644 --- a/target-alpha/helper.c +++ b/target/alpha/helper.c diff --git a/target-alpha/helper.h b/target/alpha/helper.h index 004221df8c..004221df8c 100644 --- a/target-alpha/helper.h +++ b/target/alpha/helper.h diff --git a/target-alpha/int_helper.c b/target/alpha/int_helper.c index 19bebfe742..19bebfe742 100644 --- a/target-alpha/int_helper.c +++ b/target/alpha/int_helper.c diff --git a/target-alpha/machine.c b/target/alpha/machine.c index b99a123a39..b99a123a39 100644 --- a/target-alpha/machine.c +++ b/target/alpha/machine.c diff --git a/target-alpha/mem_helper.c b/target/alpha/mem_helper.c index 78a7d45590..78a7d45590 100644 --- a/target-alpha/mem_helper.c +++ b/target/alpha/mem_helper.c diff --git a/target-alpha/sys_helper.c b/target/alpha/sys_helper.c index bec1e178be..bec1e178be 100644 --- a/target-alpha/sys_helper.c +++ b/target/alpha/sys_helper.c diff --git a/target-alpha/translate.c b/target/alpha/translate.c index 114927b751..114927b751 100644 --- a/target-alpha/translate.c +++ b/target/alpha/translate.c diff --git a/target-alpha/vax_helper.c b/target/alpha/vax_helper.c index 2b0c178274..2b0c178274 100644 --- a/target-alpha/vax_helper.c +++ b/target/alpha/vax_helper.c diff --git a/target-arm/Makefile.objs b/target/arm/Makefile.objs index 847fb52ee0..847fb52ee0 100644 --- a/target-arm/Makefile.objs +++ b/target/arm/Makefile.objs diff --git a/target-arm/arch_dump.c b/target/arm/arch_dump.c index 1a9861f69b..1a9861f69b 100644 --- a/target-arm/arch_dump.c +++ b/target/arm/arch_dump.c diff --git a/target-arm/arm-powerctl.c b/target/arm/arm-powerctl.c index fbb7a15daa..fbb7a15daa 100644 --- a/target-arm/arm-powerctl.c +++ b/target/arm/arm-powerctl.c diff --git a/target-arm/arm-powerctl.h b/target/arm/arm-powerctl.h index 98ee04989b..98ee04989b 100644 --- a/target-arm/arm-powerctl.h +++ b/target/arm/arm-powerctl.h diff --git a/target-arm/arm-semi.c b/target/arm/arm-semi.c index 7cac8734c7..7cac8734c7 100644 --- a/target-arm/arm-semi.c +++ b/target/arm/arm-semi.c diff --git a/target-arm/arm_ldst.h b/target/arm/arm_ldst.h index a76d89f62c..a76d89f62c 100644 --- a/target-arm/arm_ldst.h +++ b/target/arm/arm_ldst.h diff --git a/target-arm/cpu-qom.h b/target/arm/cpu-qom.h index a42495bac9..a42495bac9 100644 --- a/target-arm/cpu-qom.h +++ b/target/arm/cpu-qom.h diff --git a/target-arm/cpu.c b/target/arm/cpu.c index 99f0dbebb9..f5cb30af6c 100644 --- a/target-arm/cpu.c +++ b/target/arm/cpu.c @@ -597,6 +597,11 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp) } else { set_feature(env, ARM_FEATURE_V6); } + + /* Always define VBAR for V7 CPUs even if it doesn't exist in + * non-EL3 configs. This is needed by some legacy boards. + */ + set_feature(env, ARM_FEATURE_VBAR); } if (arm_feature(env, ARM_FEATURE_V6K)) { set_feature(env, ARM_FEATURE_V6); @@ -721,6 +726,10 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp) } } + if (arm_feature(env, ARM_FEATURE_EL3)) { + set_feature(env, ARM_FEATURE_VBAR); + } + register_cp_regs_for_features(cpu); arm_cpu_register_gdb_regs_for_features(cpu); @@ -1055,7 +1064,7 @@ static void cortex_a8_initfn(Object *obj) cpu->midr = 0x410fc080; cpu->reset_fpsid = 0x410330c0; cpu->mvfr0 = 0x11110222; - cpu->mvfr1 = 0x00011100; + cpu->mvfr1 = 0x00011111; cpu->ctr = 0x82048004; cpu->reset_sctlr = 0x00c50078; cpu->id_pfr0 = 0x1031; diff --git a/target-arm/cpu.h b/target/arm/cpu.h index ca5c849ed6..ab119e62ab 100644 --- a/target-arm/cpu.h +++ b/target/arm/cpu.h @@ -1125,6 +1125,7 @@ enum arm_features { ARM_FEATURE_V8_PMULL, /* implements PMULL part of v8 Crypto Extensions */ ARM_FEATURE_THUMB_DSP, /* DSP insns supported in the Thumb encodings */ ARM_FEATURE_PMU, /* has PMU support */ + ARM_FEATURE_VBAR, /* has cp15 VBAR */ }; static inline int arm_feature(CPUARMState *env, int feature) diff --git a/target-arm/cpu64.c b/target/arm/cpu64.c index 549cb1ee93..549cb1ee93 100644 --- a/target-arm/cpu64.c +++ b/target/arm/cpu64.c diff --git a/target-arm/crypto_helper.c b/target/arm/crypto_helper.c index 3b6df3f41a..3b6df3f41a 100644 --- a/target-arm/crypto_helper.c +++ b/target/arm/crypto_helper.c diff --git a/target-arm/gdbstub.c b/target/arm/gdbstub.c index 04c1208d03..04c1208d03 100644 --- a/target-arm/gdbstub.c +++ b/target/arm/gdbstub.c diff --git a/target-arm/gdbstub64.c b/target/arm/gdbstub64.c index 49bc3fc521..49bc3fc521 100644 --- a/target-arm/gdbstub64.c +++ b/target/arm/gdbstub64.c diff --git a/target-arm/helper-a64.c b/target/arm/helper-a64.c index 98b97df461..98b97df461 100644 --- a/target-arm/helper-a64.c +++ b/target/arm/helper-a64.c diff --git a/target-arm/helper-a64.h b/target/arm/helper-a64.h index dd32000e63..dd32000e63 100644 --- a/target-arm/helper-a64.h +++ b/target/arm/helper-a64.h diff --git a/target-arm/helper.c b/target/arm/helper.c index b5b65caadf..8dcabbf576 100644 --- a/target-arm/helper.c +++ b/target/arm/helper.c @@ -1252,12 +1252,6 @@ static const ARMCPRegInfo v7_cp_reginfo[] = { .access = PL1_RW, .accessfn = access_tpm, .type = ARM_CP_ALIAS, .fieldoffset = offsetof(CPUARMState, cp15.c9_pminten), .writefn = pmintenclr_write }, - { .name = "VBAR", .state = ARM_CP_STATE_BOTH, - .opc0 = 3, .crn = 12, .crm = 0, .opc1 = 0, .opc2 = 0, - .access = PL1_RW, .writefn = vbar_write, - .bank_fieldoffsets = { offsetof(CPUARMState, cp15.vbar_s), - offsetof(CPUARMState, cp15.vbar_ns) }, - .resetvalue = 0 }, { .name = "CCSIDR", .state = ARM_CP_STATE_BOTH, .opc0 = 3, .crn = 0, .crm = 0, .opc1 = 1, .opc2 = 0, .access = PL1_R, .readfn = ccsidr_read, .type = ARM_CP_NO_RAW }, @@ -5094,6 +5088,19 @@ void register_cp_regs_for_features(ARMCPU *cpu) } } + if (arm_feature(env, ARM_FEATURE_VBAR)) { + ARMCPRegInfo vbar_cp_reginfo[] = { + { .name = "VBAR", .state = ARM_CP_STATE_BOTH, + .opc0 = 3, .crn = 12, .crm = 0, .opc1 = 0, .opc2 = 0, + .access = PL1_RW, .writefn = vbar_write, + .bank_fieldoffsets = { offsetof(CPUARMState, cp15.vbar_s), + offsetof(CPUARMState, cp15.vbar_ns) }, + .resetvalue = 0 }, + REGINFO_SENTINEL + }; + define_arm_cp_regs(cpu, vbar_cp_reginfo); + } + /* Generic registers whose values depend on the implementation */ { ARMCPRegInfo sctlr = { diff --git a/target-arm/helper.h b/target/arm/helper.h index 84aa637629..84aa637629 100644 --- a/target-arm/helper.h +++ b/target/arm/helper.h diff --git a/target-arm/internals.h b/target/arm/internals.h index 3edccd2529..3cae5ff3b5 100644 --- a/target-arm/internals.h +++ b/target/arm/internals.h @@ -18,7 +18,7 @@ * <http://www.gnu.org/licenses/gpl-2.0.html> * * This header defines functions, types, etc which need to be shared - * between different source files within target-arm/ but which are + * between different source files within target/arm/ but which are * private to it and not required by the rest of QEMU. */ diff --git a/target-arm/iwmmxt_helper.c b/target/arm/iwmmxt_helper.c index 7d87e1a0a8..7d87e1a0a8 100644 --- a/target-arm/iwmmxt_helper.c +++ b/target/arm/iwmmxt_helper.c diff --git a/target-arm/kvm-consts.h b/target/arm/kvm-consts.h index a2c9518592..a2c9518592 100644 --- a/target-arm/kvm-consts.h +++ b/target/arm/kvm-consts.h diff --git a/target-arm/kvm-stub.c b/target/arm/kvm-stub.c index b2c66df532..b2c66df532 100644 --- a/target-arm/kvm-stub.c +++ b/target/arm/kvm-stub.c diff --git a/target-arm/kvm.c b/target/arm/kvm.c index c00b94e42a..c00b94e42a 100644 --- a/target-arm/kvm.c +++ b/target/arm/kvm.c diff --git a/target-arm/kvm32.c b/target/arm/kvm32.c index 069da0c5fd..069da0c5fd 100644 --- a/target-arm/kvm32.c +++ b/target/arm/kvm32.c diff --git a/target-arm/kvm64.c b/target/arm/kvm64.c index 61111091ad..61111091ad 100644 --- a/target-arm/kvm64.c +++ b/target/arm/kvm64.c diff --git a/target-arm/kvm_arm.h b/target/arm/kvm_arm.h index 633d08828a..633d08828a 100644 --- a/target-arm/kvm_arm.h +++ b/target/arm/kvm_arm.h diff --git a/target-arm/machine.c b/target/arm/machine.c index d90943b6db..d90943b6db 100644 --- a/target-arm/machine.c +++ b/target/arm/machine.c diff --git a/target-arm/monitor.c b/target/arm/monitor.c index 299cb80ae7..299cb80ae7 100644 --- a/target-arm/monitor.c +++ b/target/arm/monitor.c diff --git a/target-arm/neon_helper.c b/target/arm/neon_helper.c index ebdf7c9b10..ebdf7c9b10 100644 --- a/target-arm/neon_helper.c +++ b/target/arm/neon_helper.c diff --git a/target-arm/op_addsub.h b/target/arm/op_addsub.h index ca4a1893c3..ca4a1893c3 100644 --- a/target-arm/op_addsub.h +++ b/target/arm/op_addsub.h diff --git a/target-arm/op_helper.c b/target/arm/op_helper.c index cd94216591..ba796d898e 100644 --- a/target-arm/op_helper.c +++ b/target/arm/op_helper.c @@ -17,6 +17,7 @@ * License along with this library; if not, see <http://www.gnu.org/licenses/>. */ #include "qemu/osdep.h" +#include "qemu/log.h" #include "cpu.h" #include "exec/helper-proto.h" #include "internals.h" @@ -972,6 +973,9 @@ void HELPER(exception_return)(CPUARMState *env) } else { env->regs[15] = env->elr_el[cur_el] & ~0x3; } + qemu_log_mask(CPU_LOG_INT, "Exception return from AArch64 EL%d to " + "AArch32 EL%d PC 0x%" PRIx32 "\n", + cur_el, new_el, env->regs[15]); } else { env->aarch64 = 1; pstate_write(env, spsr); @@ -980,6 +984,9 @@ void HELPER(exception_return)(CPUARMState *env) } aarch64_restore_sp(env, new_el); env->pc = env->elr_el[cur_el]; + qemu_log_mask(CPU_LOG_INT, "Exception return from AArch64 EL%d to " + "AArch64 EL%d PC 0x%" PRIx64 "\n", + cur_el, new_el, env->pc); } arm_call_el_change_hook(arm_env_get_cpu(env)); @@ -1002,6 +1009,8 @@ illegal_return: if (!arm_singlestep_active(env)) { env->pstate &= ~PSTATE_SS; } + qemu_log_mask(LOG_GUEST_ERROR, "Illegal exception return at EL%d: " + "resuming execution at 0x%" PRIx64 "\n", cur_el, env->pc); } /* Return true if the linked breakpoint entry lbn passes its checks */ diff --git a/target-arm/psci.c b/target/arm/psci.c index 14316eb0ae..14316eb0ae 100644 --- a/target-arm/psci.c +++ b/target/arm/psci.c diff --git a/target-arm/trace-events b/target/arm/trace-events index 9f726bdae3..e21c84fc6f 100644 --- a/target-arm/trace-events +++ b/target/arm/trace-events @@ -1,6 +1,6 @@ # See docs/tracing.txt for syntax documentation. -# target-arm/helper.c +# target/arm/helper.c arm_gt_recalc(int timer, int irqstate, uint64_t nexttick) "gt recalc: timer %d irqstate %d next tick %" PRIx64 arm_gt_recalc_disabled(int timer) "gt recalc: timer %d irqstate 0 timer disabled" arm_gt_cval_write(int timer, uint64_t value) "gt_cval_write: timer %d value %" PRIx64 diff --git a/target-arm/translate-a64.c b/target/arm/translate-a64.c index 6dc27a6115..f673d939e1 100644 --- a/target-arm/translate-a64.c +++ b/target/arm/translate-a64.c @@ -527,7 +527,7 @@ static inline void assert_fp_access_checked(DisasContext *s) static inline int vec_reg_offset(DisasContext *s, int regno, int element, TCGMemOp size) { - int offs = offsetof(CPUARMState, vfp.regs[regno * 2]); + int offs = 0; #ifdef HOST_WORDS_BIGENDIAN /* This is complicated slightly because vfp.regs[2n] is * still the low half and vfp.regs[2n+1] the high half @@ -540,6 +540,7 @@ static inline int vec_reg_offset(DisasContext *s, int regno, #else offs += element * (1 << size); #endif + offs += offsetof(CPUARMState, vfp.regs[regno * 2]); assert_fp_access_checked(s); return offs; } @@ -2829,9 +2830,9 @@ static void disas_ldst_single_struct(DisasContext *s, uint32_t insn) } else { /* Load/store one element per register */ if (is_load) { - do_vec_ld(s, rt, index, tcg_addr, s->be_data + scale); + do_vec_ld(s, rt, index, tcg_addr, scale); } else { - do_vec_st(s, rt, index, tcg_addr, s->be_data + scale); + do_vec_st(s, rt, index, tcg_addr, scale); } } tcg_gen_addi_i64(tcg_addr, tcg_addr, ebytes); diff --git a/target-arm/translate.c b/target/arm/translate.c index 0ad9070b45..0ad9070b45 100644 --- a/target-arm/translate.c +++ b/target/arm/translate.c diff --git a/target-arm/translate.h b/target/arm/translate.h index 285e96f087..285e96f087 100644 --- a/target-arm/translate.h +++ b/target/arm/translate.h diff --git a/target-cris/Makefile.objs b/target/cris/Makefile.objs index 7779227fc4..7779227fc4 100644 --- a/target-cris/Makefile.objs +++ b/target/cris/Makefile.objs diff --git a/target-cris/cpu-qom.h b/target/cris/cpu-qom.h index 7556e9f97e..7556e9f97e 100644 --- a/target-cris/cpu-qom.h +++ b/target/cris/cpu-qom.h diff --git a/target-cris/cpu.c b/target/cris/cpu.c index 2e9ab9700e..2e9ab9700e 100644 --- a/target-cris/cpu.c +++ b/target/cris/cpu.c diff --git a/target-cris/cpu.h b/target/cris/cpu.h index 43d5f9d1da..43d5f9d1da 100644 --- a/target-cris/cpu.h +++ b/target/cris/cpu.h diff --git a/target-cris/crisv10-decode.h b/target/cris/crisv10-decode.h index bdb4b6d318..bdb4b6d318 100644 --- a/target-cris/crisv10-decode.h +++ b/target/cris/crisv10-decode.h diff --git a/target-cris/crisv32-decode.h b/target/cris/crisv32-decode.h index cdc2f8cbe6..cdc2f8cbe6 100644 --- a/target-cris/crisv32-decode.h +++ b/target/cris/crisv32-decode.h diff --git a/target-cris/gdbstub.c b/target/cris/gdbstub.c index 3a72ee2a98..3a72ee2a98 100644 --- a/target-cris/gdbstub.c +++ b/target/cris/gdbstub.c diff --git a/target-cris/helper.c b/target/cris/helper.c index af78cca8b9..af78cca8b9 100644 --- a/target-cris/helper.c +++ b/target/cris/helper.c diff --git a/target-cris/helper.h b/target/cris/helper.h index ff3595641a..ff3595641a 100644 --- a/target-cris/helper.h +++ b/target/cris/helper.h diff --git a/target-cris/machine.c b/target/cris/machine.c index 6b797e8c1d..6b797e8c1d 100644 --- a/target-cris/machine.c +++ b/target/cris/machine.c diff --git a/target-cris/mmu.c b/target/cris/mmu.c index b8db908823..b8db908823 100644 --- a/target-cris/mmu.c +++ b/target/cris/mmu.c diff --git a/target-cris/mmu.h b/target/cris/mmu.h index 8e249e812b..8e249e812b 100644 --- a/target-cris/mmu.h +++ b/target/cris/mmu.h diff --git a/target-cris/op_helper.c b/target/cris/op_helper.c index 504303913c..504303913c 100644 --- a/target-cris/op_helper.c +++ b/target/cris/op_helper.c diff --git a/target-cris/opcode-cris.h b/target/cris/opcode-cris.h index e7ebb98cd0..e7ebb98cd0 100644 --- a/target-cris/opcode-cris.h +++ b/target/cris/opcode-cris.h diff --git a/target-cris/translate.c b/target/cris/translate.c index b91042743f..b91042743f 100644 --- a/target-cris/translate.c +++ b/target/cris/translate.c diff --git a/target-cris/translate_v10.c b/target/cris/translate_v10.c index 4a0b485d8e..4a0b485d8e 100644 --- a/target-cris/translate_v10.c +++ b/target/cris/translate_v10.c diff --git a/target-i386/Makefile.objs b/target/i386/Makefile.objs index b223d7932b..b223d7932b 100644 --- a/target-i386/Makefile.objs +++ b/target/i386/Makefile.objs diff --git a/target-i386/TODO b/target/i386/TODO index a8d69cf87f..a8d69cf87f 100644 --- a/target-i386/TODO +++ b/target/i386/TODO diff --git a/target-i386/arch_dump.c b/target/i386/arch_dump.c index 5a2e4be5d0..5a2e4be5d0 100644 --- a/target-i386/arch_dump.c +++ b/target/i386/arch_dump.c diff --git a/target-i386/arch_memory_mapping.c b/target/i386/arch_memory_mapping.c index 88f341e1bb..826aee597b 100644 --- a/target-i386/arch_memory_mapping.c +++ b/target/i386/arch_memory_mapping.c @@ -220,7 +220,8 @@ static void walk_pdpe(MemoryMappingList *list, AddressSpace *as, /* IA-32e Paging */ static void walk_pml4e(MemoryMappingList *list, AddressSpace *as, - hwaddr pml4e_start_addr, int32_t a20_mask) + hwaddr pml4e_start_addr, int32_t a20_mask, + target_ulong start_line_addr) { hwaddr pml4e_addr, pdpe_start_addr; uint64_t pml4e; @@ -236,11 +237,34 @@ static void walk_pml4e(MemoryMappingList *list, AddressSpace *as, continue; } - line_addr = ((i & 0x1ffULL) << 39) | (0xffffULL << 48); + line_addr = start_line_addr | ((i & 0x1ffULL) << 39); pdpe_start_addr = (pml4e & PLM4_ADDR_MASK) & a20_mask; walk_pdpe(list, as, pdpe_start_addr, a20_mask, line_addr); } } + +static void walk_pml5e(MemoryMappingList *list, AddressSpace *as, + hwaddr pml5e_start_addr, int32_t a20_mask) +{ + hwaddr pml5e_addr, pml4e_start_addr; + uint64_t pml5e; + target_ulong line_addr; + int i; + + for (i = 0; i < 512; i++) { + pml5e_addr = (pml5e_start_addr + i * 8) & a20_mask; + pml5e = address_space_ldq(as, pml5e_addr, MEMTXATTRS_UNSPECIFIED, + NULL); + if (!(pml5e & PG_PRESENT_MASK)) { + /* not present */ + continue; + } + + line_addr = (0x7fULL << 57) | ((i & 0x1ffULL) << 48); + pml4e_start_addr = (pml5e & PLM4_ADDR_MASK) & a20_mask; + walk_pml4e(list, as, pml4e_start_addr, a20_mask, line_addr); + } +} #endif void x86_cpu_get_memory_mapping(CPUState *cs, MemoryMappingList *list, @@ -257,10 +281,18 @@ void x86_cpu_get_memory_mapping(CPUState *cs, MemoryMappingList *list, if (env->cr[4] & CR4_PAE_MASK) { #ifdef TARGET_X86_64 if (env->hflags & HF_LMA_MASK) { - hwaddr pml4e_addr; + if (env->cr[4] & CR4_LA57_MASK) { + hwaddr pml5e_addr; + + pml5e_addr = (env->cr[3] & PLM4_ADDR_MASK) & env->a20_mask; + walk_pml5e(list, cs->as, pml5e_addr, env->a20_mask); + } else { + hwaddr pml4e_addr; - pml4e_addr = (env->cr[3] & PLM4_ADDR_MASK) & env->a20_mask; - walk_pml4e(list, cs->as, pml4e_addr, env->a20_mask); + pml4e_addr = (env->cr[3] & PLM4_ADDR_MASK) & env->a20_mask; + walk_pml4e(list, cs->as, pml4e_addr, env->a20_mask, + 0xffffULL << 48); + } } else #endif { diff --git a/target-i386/bpt_helper.c b/target/i386/bpt_helper.c index 6fd7fe04a0..b3efdc77ec 100644 --- a/target-i386/bpt_helper.c +++ b/target/i386/bpt_helper.c @@ -244,6 +244,13 @@ void helper_single_step(CPUX86State *env) raise_exception(env, EXCP01_DB); } +void helper_rechecking_single_step(CPUX86State *env) +{ + if ((env->eflags & TF_MASK) != 0) { + helper_single_step(env); + } +} + void helper_set_dr(CPUX86State *env, int reg, target_ulong t0) { #ifndef CONFIG_USER_ONLY diff --git a/target-i386/cc_helper.c b/target/i386/cc_helper.c index 83af223c9f..83af223c9f 100644 --- a/target-i386/cc_helper.c +++ b/target/i386/cc_helper.c diff --git a/target-i386/cc_helper_template.h b/target/i386/cc_helper_template.h index 607311f195..607311f195 100644 --- a/target-i386/cc_helper_template.h +++ b/target/i386/cc_helper_template.h diff --git a/target-i386/cpu-qom.h b/target/i386/cpu-qom.h index 7c9a07ae65..7c9a07ae65 100644 --- a/target-i386/cpu-qom.h +++ b/target/i386/cpu-qom.h diff --git a/target-i386/cpu.c b/target/i386/cpu.c index de1f30eeda..b0640f1e38 100644 --- a/target-i386/cpu.c +++ b/target/i386/cpu.c @@ -238,7 +238,8 @@ static void x86_cpu_vendor_words2str(char *dst, uint32_t vendor1, CPUID_7_0_EBX_HLE, CPUID_7_0_EBX_AVX2, CPUID_7_0_EBX_INVPCID, CPUID_7_0_EBX_RTM, CPUID_7_0_EBX_RDSEED */ -#define TCG_7_0_ECX_FEATURES (CPUID_7_0_ECX_PKU | CPUID_7_0_ECX_OSPKE) +#define TCG_7_0_ECX_FEATURES (CPUID_7_0_ECX_PKU | CPUID_7_0_ECX_OSPKE | \ + CPUID_7_0_ECX_LA57) #define TCG_7_0_EDX_FEATURES 0 #define TCG_APM_FEATURES 0 #define TCG_6_EAX_FEATURES CPUID_6_EAX_ARAT @@ -422,7 +423,7 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] = { "avx512f", "avx512dq", "rdseed", "adx", "smap", "avx512ifma", "pcommit", "clflushopt", "clwb", NULL, "avx512pf", "avx512er", - "avx512cd", NULL, "avx512bw", "avx512vl", + "avx512cd", "sha-ni", "avx512bw", "avx512vl", }, .cpuid_eax = 7, .cpuid_needs_ecx = true, .cpuid_ecx = 0, @@ -435,7 +436,7 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] = { "ospke", NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, + "la57", NULL, NULL, NULL, NULL, NULL, "rdpid", NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, @@ -2742,10 +2743,13 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count, case 0x80000008: /* virtual & phys address size in low 2 bytes. */ if (env->features[FEAT_8000_0001_EDX] & CPUID_EXT2_LM) { - /* 64 bit processor, 48 bits virtual, configurable - * physical bits. - */ - *eax = 0x00003000 + cpu->phys_bits; + /* 64 bit processor */ + *eax = cpu->phys_bits; /* configurable physical bits */ + if (env->features[FEAT_7_0_ECX] & CPUID_7_0_ECX_LA57) { + *eax |= 0x00003900; /* 57 bits virtual */ + } else { + *eax |= 0x00003000; /* 48 bits virtual */ + } } else { *eax = cpu->phys_bits; } diff --git a/target-i386/cpu.h b/target/i386/cpu.h index c605724022..a7f2f6099d 100644 --- a/target-i386/cpu.h +++ b/target/i386/cpu.h @@ -224,6 +224,7 @@ #define CR4_OSFXSR_SHIFT 9 #define CR4_OSFXSR_MASK (1U << CR4_OSFXSR_SHIFT) #define CR4_OSXMMEXCPT_MASK (1U << 10) +#define CR4_LA57_MASK (1U << 12) #define CR4_VMXE_MASK (1U << 13) #define CR4_SMXE_MASK (1U << 14) #define CR4_FSGSBASE_MASK (1U << 16) @@ -621,6 +622,7 @@ typedef uint32_t FeatureWordArray[FEATURE_WORDS]; #define CPUID_7_0_EBX_AVX512PF (1U << 26) /* AVX-512 Prefetch */ #define CPUID_7_0_EBX_AVX512ER (1U << 27) /* AVX-512 Exponential and Reciprocal */ #define CPUID_7_0_EBX_AVX512CD (1U << 28) /* AVX-512 Conflict Detection */ +#define CPUID_7_0_EBX_SHA_NI (1U << 29) /* SHA1/SHA256 Instruction Extensions */ #define CPUID_7_0_EBX_AVX512BW (1U << 30) /* AVX-512 Byte and Word Instructions */ #define CPUID_7_0_EBX_AVX512VL (1U << 31) /* AVX-512 Vector Length Extensions */ @@ -628,6 +630,7 @@ typedef uint32_t FeatureWordArray[FEATURE_WORDS]; #define CPUID_7_0_ECX_UMIP (1U << 2) #define CPUID_7_0_ECX_PKU (1U << 3) #define CPUID_7_0_ECX_OSPKE (1U << 4) +#define CPUID_7_0_ECX_LA57 (1U << 16) #define CPUID_7_0_ECX_RDPID (1U << 22) #define CPUID_7_0_EDX_AVX512_4VNNIW (1U << 2) /* AVX512 Neural Network Instructions */ diff --git a/target-i386/excp_helper.c b/target/i386/excp_helper.c index f0dc4996c1..f0dc4996c1 100644 --- a/target-i386/excp_helper.c +++ b/target/i386/excp_helper.c diff --git a/target-i386/fpu_helper.c b/target/i386/fpu_helper.c index 2049a8c01d..2049a8c01d 100644 --- a/target-i386/fpu_helper.c +++ b/target/i386/fpu_helper.c diff --git a/target-i386/gdbstub.c b/target/i386/gdbstub.c index c494535df1..9b94ab852c 100644 --- a/target-i386/gdbstub.c +++ b/target/i386/gdbstub.c @@ -44,10 +44,22 @@ int x86_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n) X86CPU *cpu = X86_CPU(cs); CPUX86State *env = &cpu->env; + /* N.B. GDB can't deal with changes in registers or sizes in the middle + of a session. So if we're in 32-bit mode on a 64-bit cpu, still act + as if we're on a 64-bit cpu. */ + if (n < CPU_NB_REGS) { - if (TARGET_LONG_BITS == 64 && env->hflags & HF_CS64_MASK) { - return gdb_get_reg64(mem_buf, env->regs[gpr_map[n]]); - } else if (n < CPU_NB_REGS32) { + if (TARGET_LONG_BITS == 64) { + if (env->hflags & HF_CS64_MASK) { + return gdb_get_reg64(mem_buf, env->regs[gpr_map[n]]); + } else if (n < CPU_NB_REGS32) { + return gdb_get_reg64(mem_buf, + env->regs[gpr_map[n]] & 0xffffffffUL); + } else { + memset(mem_buf, 0, sizeof(target_ulong)); + return sizeof(target_ulong); + } + } else { return gdb_get_reg32(mem_buf, env->regs[gpr_map32[n]]); } } else if (n >= IDX_FP_REGS && n < IDX_FP_REGS + 8) { @@ -60,8 +72,7 @@ int x86_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n) return 10; } else if (n >= IDX_XMM_REGS && n < IDX_XMM_REGS + CPU_NB_REGS) { n -= IDX_XMM_REGS; - if (n < CPU_NB_REGS32 || - (TARGET_LONG_BITS == 64 && env->hflags & HF_CS64_MASK)) { + if (n < CPU_NB_REGS32 || TARGET_LONG_BITS == 64) { stq_p(mem_buf, env->xmm_regs[n].ZMM_Q(0)); stq_p(mem_buf + 8, env->xmm_regs[n].ZMM_Q(1)); return 16; @@ -69,8 +80,12 @@ int x86_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n) } else { switch (n) { case IDX_IP_REG: - if (TARGET_LONG_BITS == 64 && env->hflags & HF_CS64_MASK) { - return gdb_get_reg64(mem_buf, env->eip); + if (TARGET_LONG_BITS == 64) { + if (env->hflags & HF_CS64_MASK) { + return gdb_get_reg64(mem_buf, env->eip); + } else { + return gdb_get_reg64(mem_buf, env->eip & 0xffffffffUL); + } } else { return gdb_get_reg32(mem_buf, env->eip); } @@ -151,9 +166,17 @@ int x86_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n) CPUX86State *env = &cpu->env; uint32_t tmp; + /* N.B. GDB can't deal with changes in registers or sizes in the middle + of a session. So if we're in 32-bit mode on a 64-bit cpu, still act + as if we're on a 64-bit cpu. */ + if (n < CPU_NB_REGS) { - if (TARGET_LONG_BITS == 64 && env->hflags & HF_CS64_MASK) { - env->regs[gpr_map[n]] = ldtul_p(mem_buf); + if (TARGET_LONG_BITS == 64) { + if (env->hflags & HF_CS64_MASK) { + env->regs[gpr_map[n]] = ldtul_p(mem_buf); + } else if (n < CPU_NB_REGS32) { + env->regs[gpr_map[n]] = ldtul_p(mem_buf) & 0xffffffffUL; + } return sizeof(target_ulong); } else if (n < CPU_NB_REGS32) { n = gpr_map32[n]; @@ -169,8 +192,7 @@ int x86_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n) return 10; } else if (n >= IDX_XMM_REGS && n < IDX_XMM_REGS + CPU_NB_REGS) { n -= IDX_XMM_REGS; - if (n < CPU_NB_REGS32 || - (TARGET_LONG_BITS == 64 && env->hflags & HF_CS64_MASK)) { + if (n < CPU_NB_REGS32 || TARGET_LONG_BITS == 64) { env->xmm_regs[n].ZMM_Q(0) = ldq_p(mem_buf); env->xmm_regs[n].ZMM_Q(1) = ldq_p(mem_buf + 8); return 16; @@ -178,8 +200,12 @@ int x86_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n) } else { switch (n) { case IDX_IP_REG: - if (TARGET_LONG_BITS == 64 && env->hflags & HF_CS64_MASK) { - env->eip = ldq_p(mem_buf); + if (TARGET_LONG_BITS == 64) { + if (env->hflags & HF_CS64_MASK) { + env->eip = ldq_p(mem_buf); + } else { + env->eip = ldq_p(mem_buf) & 0xffffffffUL; + } return 8; } else { env->eip &= ~0xffffffffUL; diff --git a/target-i386/helper.c b/target/i386/helper.c index 4ecc0912a4..43e87ddba0 100644 --- a/target-i386/helper.c +++ b/target/i386/helper.c @@ -651,11 +651,11 @@ void cpu_x86_update_cr4(CPUX86State *env, uint32_t new_cr4) uint32_t hflags; #if defined(DEBUG_MMU) - printf("CR4 update: CR4=%08x\n", (uint32_t)env->cr[4]); + printf("CR4 update: %08x -> %08x\n", (uint32_t)env->cr[4], new_cr4); #endif if ((new_cr4 ^ env->cr[4]) & (CR4_PGE_MASK | CR4_PAE_MASK | CR4_PSE_MASK | - CR4_SMEP_MASK | CR4_SMAP_MASK)) { + CR4_SMEP_MASK | CR4_SMAP_MASK | CR4_LA57_MASK)) { tlb_flush(CPU(cpu), 1); } @@ -757,19 +757,41 @@ int x86_cpu_handle_mmu_fault(CPUState *cs, vaddr addr, #ifdef TARGET_X86_64 if (env->hflags & HF_LMA_MASK) { + bool la57 = env->cr[4] & CR4_LA57_MASK; + uint64_t pml5e_addr, pml5e; uint64_t pml4e_addr, pml4e; int32_t sext; /* test virtual address sign extension */ - sext = (int64_t)addr >> 47; + sext = la57 ? (int64_t)addr >> 56 : (int64_t)addr >> 47; if (sext != 0 && sext != -1) { env->error_code = 0; cs->exception_index = EXCP0D_GPF; return 1; } - pml4e_addr = ((env->cr[3] & ~0xfff) + (((addr >> 39) & 0x1ff) << 3)) & - env->a20_mask; + if (la57) { + pml5e_addr = ((env->cr[3] & ~0xfff) + + (((addr >> 48) & 0x1ff) << 3)) & env->a20_mask; + pml5e = x86_ldq_phys(cs, pml5e_addr); + if (!(pml5e & PG_PRESENT_MASK)) { + goto do_fault; + } + if (pml5e & (rsvd_mask | PG_PSE_MASK)) { + goto do_fault_rsvd; + } + if (!(pml5e & PG_ACCESSED_MASK)) { + pml5e |= PG_ACCESSED_MASK; + x86_stl_phys_notdirty(cs, pml5e_addr, pml5e); + } + ptep = pml5e ^ PG_NX_MASK; + } else { + pml5e = env->cr[3]; + ptep = PG_NX_MASK | PG_USER_MASK | PG_RW_MASK; + } + + pml4e_addr = ((pml5e & PG_ADDRESS_MASK) + + (((addr >> 39) & 0x1ff) << 3)) & env->a20_mask; pml4e = x86_ldq_phys(cs, pml4e_addr); if (!(pml4e & PG_PRESENT_MASK)) { goto do_fault; @@ -781,7 +803,7 @@ int x86_cpu_handle_mmu_fault(CPUState *cs, vaddr addr, pml4e |= PG_ACCESSED_MASK; x86_stl_phys_notdirty(cs, pml4e_addr, pml4e); } - ptep = pml4e ^ PG_NX_MASK; + ptep &= pml4e ^ PG_NX_MASK; pdpe_addr = ((pml4e & PG_ADDRESS_MASK) + (((addr >> 30) & 0x1ff) << 3)) & env->a20_mask; pdpe = x86_ldq_phys(cs, pdpe_addr); @@ -1024,16 +1046,30 @@ hwaddr x86_cpu_get_phys_page_debug(CPUState *cs, vaddr addr) #ifdef TARGET_X86_64 if (env->hflags & HF_LMA_MASK) { + bool la57 = env->cr[4] & CR4_LA57_MASK; + uint64_t pml5e_addr, pml5e; uint64_t pml4e_addr, pml4e; int32_t sext; /* test virtual address sign extension */ - sext = (int64_t)addr >> 47; + sext = la57 ? (int64_t)addr >> 56 : (int64_t)addr >> 47; if (sext != 0 && sext != -1) { return -1; } - pml4e_addr = ((env->cr[3] & ~0xfff) + (((addr >> 39) & 0x1ff) << 3)) & - env->a20_mask; + + if (la57) { + pml5e_addr = ((env->cr[3] & ~0xfff) + + (((addr >> 48) & 0x1ff) << 3)) & env->a20_mask; + pml5e = x86_ldq_phys(cs, pml5e_addr); + if (!(pml5e & PG_PRESENT_MASK)) { + return -1; + } + } else { + pml5e = env->cr[3]; + } + + pml4e_addr = ((pml5e & PG_ADDRESS_MASK) + + (((addr >> 39) & 0x1ff) << 3)) & env->a20_mask; pml4e = x86_ldq_phys(cs, pml4e_addr); if (!(pml4e & PG_PRESENT_MASK)) { return -1; diff --git a/target-i386/helper.h b/target/i386/helper.h index 4e859eba9d..bd9b2cf677 100644 --- a/target-i386/helper.h +++ b/target/i386/helper.h @@ -79,6 +79,7 @@ DEF_HELPER_2(cmpxchg16b_unlocked, void, env, tl) DEF_HELPER_2(cmpxchg16b, void, env, tl) #endif DEF_HELPER_1(single_step, void, env) +DEF_HELPER_1(rechecking_single_step, void, env) DEF_HELPER_1(cpuid, void, env) DEF_HELPER_1(rdtsc, void, env) DEF_HELPER_1(rdtscp, void, env) diff --git a/target-i386/hyperv.c b/target/i386/hyperv.c index 39a230f119..39a230f119 100644 --- a/target-i386/hyperv.c +++ b/target/i386/hyperv.c diff --git a/target-i386/hyperv.h b/target/i386/hyperv.h index 0c3b562018..0c3b562018 100644 --- a/target-i386/hyperv.h +++ b/target/i386/hyperv.h diff --git a/target-i386/int_helper.c b/target/i386/int_helper.c index 9e873ac150..9e873ac150 100644 --- a/target-i386/int_helper.c +++ b/target/i386/int_helper.c diff --git a/target-i386/kvm-stub.c b/target/i386/kvm-stub.c index bda4dc2f0c..bda4dc2f0c 100644 --- a/target-i386/kvm-stub.c +++ b/target/i386/kvm-stub.c diff --git a/target-i386/kvm.c b/target/i386/kvm.c index f62264a7a8..10a9cd8f7f 100644 --- a/target-i386/kvm.c +++ b/target/i386/kvm.c @@ -117,6 +117,13 @@ bool kvm_has_smm(void) return kvm_check_extension(kvm_state, KVM_CAP_X86_SMM); } +bool kvm_has_adjust_clock_stable(void) +{ + int ret = kvm_check_extension(kvm_state, KVM_CAP_ADJUST_CLOCK); + + return (ret == KVM_CLOCK_TSC_STABLE); +} + bool kvm_allows_irq0_override(void) { return !kvm_irqchip_in_kernel() || kvm_has_gsi_routing(); diff --git a/target-i386/kvm_i386.h b/target/i386/kvm_i386.h index 76079295b2..bfce427f86 100644 --- a/target-i386/kvm_i386.h +++ b/target/i386/kvm_i386.h @@ -17,6 +17,7 @@ bool kvm_allows_irq0_override(void); bool kvm_has_smm(void); +bool kvm_has_adjust_clock_stable(void); void kvm_synchronize_all_tsc(void); void kvm_arch_reset_vcpu(X86CPU *cs); void kvm_arch_do_init_vcpu(X86CPU *cs); diff --git a/target-i386/machine.c b/target/i386/machine.c index 760f82b6c7..760f82b6c7 100644 --- a/target-i386/machine.c +++ b/target/i386/machine.c diff --git a/target-i386/mem_helper.c b/target/i386/mem_helper.c index 70f67668ab..70f67668ab 100644 --- a/target-i386/mem_helper.c +++ b/target/i386/mem_helper.c diff --git a/target-i386/misc_helper.c b/target/i386/misc_helper.c index 3f666b4b87..3f666b4b87 100644 --- a/target-i386/misc_helper.c +++ b/target/i386/misc_helper.c diff --git a/target-i386/monitor.c b/target/i386/monitor.c index 9a3b4d746e..468aa073bc 100644 --- a/target-i386/monitor.c +++ b/target/i386/monitor.c @@ -30,13 +30,18 @@ #include "hmp.h" -static void print_pte(Monitor *mon, hwaddr addr, - hwaddr pte, - hwaddr mask) +static void print_pte(Monitor *mon, CPUArchState *env, hwaddr addr, + hwaddr pte, hwaddr mask) { #ifdef TARGET_X86_64 - if (addr & (1ULL << 47)) { - addr |= -1LL << 48; + if (env->cr[4] & CR4_LA57_MASK) { + if (addr & (1ULL << 56)) { + addr |= -1LL << 57; + } + } else { + if (addr & (1ULL << 47)) { + addr |= -1LL << 48; + } } #endif monitor_printf(mon, TARGET_FMT_plx ": " TARGET_FMT_plx @@ -66,13 +71,13 @@ static void tlb_info_32(Monitor *mon, CPUArchState *env) if (pde & PG_PRESENT_MASK) { if ((pde & PG_PSE_MASK) && (env->cr[4] & CR4_PSE_MASK)) { /* 4M pages */ - print_pte(mon, (l1 << 22), pde, ~((1 << 21) - 1)); + print_pte(mon, env, (l1 << 22), pde, ~((1 << 21) - 1)); } else { for(l2 = 0; l2 < 1024; l2++) { cpu_physical_memory_read((pde & ~0xfff) + l2 * 4, &pte, 4); pte = le32_to_cpu(pte); if (pte & PG_PRESENT_MASK) { - print_pte(mon, (l1 << 22) + (l2 << 12), + print_pte(mon, env, (l1 << 22) + (l2 << 12), pte & ~PG_PSE_MASK, ~0xfff); } @@ -100,7 +105,7 @@ static void tlb_info_pae32(Monitor *mon, CPUArchState *env) if (pde & PG_PRESENT_MASK) { if (pde & PG_PSE_MASK) { /* 2M pages with PAE, CR4.PSE is ignored */ - print_pte(mon, (l1 << 30 ) + (l2 << 21), pde, + print_pte(mon, env, (l1 << 30) + (l2 << 21), pde, ~((hwaddr)(1 << 20) - 1)); } else { pt_addr = pde & 0x3fffffffff000ULL; @@ -108,7 +113,7 @@ static void tlb_info_pae32(Monitor *mon, CPUArchState *env) cpu_physical_memory_read(pt_addr + l3 * 8, &pte, 8); pte = le64_to_cpu(pte); if (pte & PG_PRESENT_MASK) { - print_pte(mon, (l1 << 30 ) + (l2 << 21) + print_pte(mon, env, (l1 << 30) + (l2 << 21) + (l3 << 12), pte & ~PG_PSE_MASK, ~(hwaddr)0xfff); @@ -122,61 +127,82 @@ static void tlb_info_pae32(Monitor *mon, CPUArchState *env) } #ifdef TARGET_X86_64 -static void tlb_info_64(Monitor *mon, CPUArchState *env) +static void tlb_info_la48(Monitor *mon, CPUArchState *env, + uint64_t l0, uint64_t pml4_addr) { uint64_t l1, l2, l3, l4; uint64_t pml4e, pdpe, pde, pte; - uint64_t pml4_addr, pdp_addr, pd_addr, pt_addr; + uint64_t pdp_addr, pd_addr, pt_addr; - pml4_addr = env->cr[3] & 0x3fffffffff000ULL; for (l1 = 0; l1 < 512; l1++) { cpu_physical_memory_read(pml4_addr + l1 * 8, &pml4e, 8); pml4e = le64_to_cpu(pml4e); - if (pml4e & PG_PRESENT_MASK) { - pdp_addr = pml4e & 0x3fffffffff000ULL; - for (l2 = 0; l2 < 512; l2++) { - cpu_physical_memory_read(pdp_addr + l2 * 8, &pdpe, 8); - pdpe = le64_to_cpu(pdpe); - if (pdpe & PG_PRESENT_MASK) { - if (pdpe & PG_PSE_MASK) { - /* 1G pages, CR4.PSE is ignored */ - print_pte(mon, (l1 << 39) + (l2 << 30), pdpe, - 0x3ffffc0000000ULL); - } else { - pd_addr = pdpe & 0x3fffffffff000ULL; - for (l3 = 0; l3 < 512; l3++) { - cpu_physical_memory_read(pd_addr + l3 * 8, &pde, 8); - pde = le64_to_cpu(pde); - if (pde & PG_PRESENT_MASK) { - if (pde & PG_PSE_MASK) { - /* 2M pages, CR4.PSE is ignored */ - print_pte(mon, (l1 << 39) + (l2 << 30) + - (l3 << 21), pde, - 0x3ffffffe00000ULL); - } else { - pt_addr = pde & 0x3fffffffff000ULL; - for (l4 = 0; l4 < 512; l4++) { - cpu_physical_memory_read(pt_addr - + l4 * 8, - &pte, 8); - pte = le64_to_cpu(pte); - if (pte & PG_PRESENT_MASK) { - print_pte(mon, (l1 << 39) + - (l2 << 30) + - (l3 << 21) + (l4 << 12), - pte & ~PG_PSE_MASK, - 0x3fffffffff000ULL); - } - } - } - } - } + if (!(pml4e & PG_PRESENT_MASK)) { + continue; + } + + pdp_addr = pml4e & 0x3fffffffff000ULL; + for (l2 = 0; l2 < 512; l2++) { + cpu_physical_memory_read(pdp_addr + l2 * 8, &pdpe, 8); + pdpe = le64_to_cpu(pdpe); + if (!(pdpe & PG_PRESENT_MASK)) { + continue; + } + + if (pdpe & PG_PSE_MASK) { + /* 1G pages, CR4.PSE is ignored */ + print_pte(mon, env, (l0 << 48) + (l1 << 39) + (l2 << 30), + pdpe, 0x3ffffc0000000ULL); + continue; + } + + pd_addr = pdpe & 0x3fffffffff000ULL; + for (l3 = 0; l3 < 512; l3++) { + cpu_physical_memory_read(pd_addr + l3 * 8, &pde, 8); + pde = le64_to_cpu(pde); + if (!(pde & PG_PRESENT_MASK)) { + continue; + } + + if (pde & PG_PSE_MASK) { + /* 2M pages, CR4.PSE is ignored */ + print_pte(mon, env, (l0 << 48) + (l1 << 39) + (l2 << 30) + + (l3 << 21), pde, 0x3ffffffe00000ULL); + continue; + } + + pt_addr = pde & 0x3fffffffff000ULL; + for (l4 = 0; l4 < 512; l4++) { + cpu_physical_memory_read(pt_addr + + l4 * 8, + &pte, 8); + pte = le64_to_cpu(pte); + if (pte & PG_PRESENT_MASK) { + print_pte(mon, env, (l0 << 48) + (l1 << 39) + + (l2 << 30) + (l3 << 21) + (l4 << 12), + pte & ~PG_PSE_MASK, 0x3fffffffff000ULL); } } } } } } + +static void tlb_info_la57(Monitor *mon, CPUArchState *env) +{ + uint64_t l0; + uint64_t pml5e; + uint64_t pml5_addr; + + pml5_addr = env->cr[3] & 0x3fffffffff000ULL; + for (l0 = 0; l0 < 512; l0++) { + cpu_physical_memory_read(pml5_addr + l0 * 8, &pml5e, 8); + pml5e = le64_to_cpu(pml5e); + if (pml5e & PG_PRESENT_MASK) { + tlb_info_la48(mon, env, l0, pml5e & 0x3fffffffff000ULL); + } + } +} #endif /* TARGET_X86_64 */ void hmp_info_tlb(Monitor *mon, const QDict *qdict) @@ -192,7 +218,11 @@ void hmp_info_tlb(Monitor *mon, const QDict *qdict) if (env->cr[4] & CR4_PAE_MASK) { #ifdef TARGET_X86_64 if (env->hflags & HF_LMA_MASK) { - tlb_info_64(mon, env); + if (env->cr[4] & CR4_LA57_MASK) { + tlb_info_la57(mon, env); + } else { + tlb_info_la48(mon, env, 0, env->cr[3] & 0x3fffffffff000ULL); + } } else #endif { @@ -324,7 +354,7 @@ static void mem_info_pae32(Monitor *mon, CPUArchState *env) #ifdef TARGET_X86_64 -static void mem_info_64(Monitor *mon, CPUArchState *env) +static void mem_info_la48(Monitor *mon, CPUArchState *env) { int prot, last_prot; uint64_t l1, l2, l3, l4; @@ -400,6 +430,98 @@ static void mem_info_64(Monitor *mon, CPUArchState *env) /* Flush last range */ mem_print(mon, &start, &last_prot, (hwaddr)1 << 48, 0); } + +static void mem_info_la57(Monitor *mon, CPUArchState *env) +{ + int prot, last_prot; + uint64_t l0, l1, l2, l3, l4; + uint64_t pml5e, pml4e, pdpe, pde, pte; + uint64_t pml5_addr, pml4_addr, pdp_addr, pd_addr, pt_addr, start, end; + + pml5_addr = env->cr[3] & 0x3fffffffff000ULL; + last_prot = 0; + start = -1; + for (l0 = 0; l0 < 512; l0++) { + cpu_physical_memory_read(pml5_addr + l0 * 8, &pml5e, 8); + pml4e = le64_to_cpu(pml5e); + end = l0 << 48; + if (!(pml5e & PG_PRESENT_MASK)) { + prot = 0; + mem_print(mon, &start, &last_prot, end, prot); + continue; + } + + pml4_addr = pml5e & 0x3fffffffff000ULL; + for (l1 = 0; l1 < 512; l1++) { + cpu_physical_memory_read(pml4_addr + l1 * 8, &pml4e, 8); + pml4e = le64_to_cpu(pml4e); + end = (l0 << 48) + (l1 << 39); + if (!(pml4e & PG_PRESENT_MASK)) { + prot = 0; + mem_print(mon, &start, &last_prot, end, prot); + continue; + } + + pdp_addr = pml4e & 0x3fffffffff000ULL; + for (l2 = 0; l2 < 512; l2++) { + cpu_physical_memory_read(pdp_addr + l2 * 8, &pdpe, 8); + pdpe = le64_to_cpu(pdpe); + end = (l0 << 48) + (l1 << 39) + (l2 << 30); + if (pdpe & PG_PRESENT_MASK) { + prot = 0; + mem_print(mon, &start, &last_prot, end, prot); + continue; + } + + if (pdpe & PG_PSE_MASK) { + prot = pdpe & (PG_USER_MASK | PG_RW_MASK | + PG_PRESENT_MASK); + prot &= pml4e; + mem_print(mon, &start, &last_prot, end, prot); + continue; + } + + pd_addr = pdpe & 0x3fffffffff000ULL; + for (l3 = 0; l3 < 512; l3++) { + cpu_physical_memory_read(pd_addr + l3 * 8, &pde, 8); + pde = le64_to_cpu(pde); + end = (l0 << 48) + (l1 << 39) + (l2 << 30) + (l3 << 21); + if (pde & PG_PRESENT_MASK) { + prot = 0; + mem_print(mon, &start, &last_prot, end, prot); + continue; + } + + if (pde & PG_PSE_MASK) { + prot = pde & (PG_USER_MASK | PG_RW_MASK | + PG_PRESENT_MASK); + prot &= pml4e & pdpe; + mem_print(mon, &start, &last_prot, end, prot); + continue; + } + + pt_addr = pde & 0x3fffffffff000ULL; + for (l4 = 0; l4 < 512; l4++) { + cpu_physical_memory_read(pt_addr + l4 * 8, &pte, 8); + pte = le64_to_cpu(pte); + end = (l0 << 48) + (l1 << 39) + (l2 << 30) + + (l3 << 21) + (l4 << 12); + if (pte & PG_PRESENT_MASK) { + prot = pte & (PG_USER_MASK | PG_RW_MASK | + PG_PRESENT_MASK); + prot &= pml4e & pdpe & pde; + } else { + prot = 0; + } + mem_print(mon, &start, &last_prot, end, prot); + } + } + } + } + } + /* Flush last range */ + mem_print(mon, &start, &last_prot, (hwaddr)1 << 57, 0); +} #endif /* TARGET_X86_64 */ void hmp_info_mem(Monitor *mon, const QDict *qdict) @@ -415,7 +537,11 @@ void hmp_info_mem(Monitor *mon, const QDict *qdict) if (env->cr[4] & CR4_PAE_MASK) { #ifdef TARGET_X86_64 if (env->hflags & HF_LMA_MASK) { - mem_info_64(mon, env); + if (env->cr[4] & CR4_LA57_MASK) { + mem_info_la57(mon, env); + } else { + mem_info_la48(mon, env); + } } else #endif { diff --git a/target-i386/mpx_helper.c b/target/i386/mpx_helper.c index 7e44820659..7e44820659 100644 --- a/target-i386/mpx_helper.c +++ b/target/i386/mpx_helper.c diff --git a/target-i386/ops_sse.h b/target/i386/ops_sse.h index 7a98f53864..7a98f53864 100644 --- a/target-i386/ops_sse.h +++ b/target/i386/ops_sse.h diff --git a/target-i386/ops_sse_header.h b/target/i386/ops_sse_header.h index 64c5857cf4..64c5857cf4 100644 --- a/target-i386/ops_sse_header.h +++ b/target/i386/ops_sse_header.h diff --git a/target-i386/seg_helper.c b/target/i386/seg_helper.c index fb79f3180d..fb79f3180d 100644 --- a/target-i386/seg_helper.c +++ b/target/i386/seg_helper.c diff --git a/target-i386/shift_helper_template.h b/target/i386/shift_helper_template.h index cf91a2d284..cf91a2d284 100644 --- a/target-i386/shift_helper_template.h +++ b/target/i386/shift_helper_template.h diff --git a/target-i386/smm_helper.c b/target/i386/smm_helper.c index 4dd6a2c544..4dd6a2c544 100644 --- a/target-i386/smm_helper.c +++ b/target/i386/smm_helper.c diff --git a/target-i386/svm.h b/target/i386/svm.h index 922c8fd39c..922c8fd39c 100644 --- a/target-i386/svm.h +++ b/target/i386/svm.h diff --git a/target-i386/svm_helper.c b/target/i386/svm_helper.c index 782b3f12f0..782b3f12f0 100644 --- a/target-i386/svm_helper.c +++ b/target/i386/svm_helper.c diff --git a/target-i386/trace-events b/target/i386/trace-events index 05c5453d35..de6a1cf0cb 100644 --- a/target-i386/trace-events +++ b/target/i386/trace-events @@ -1,6 +1,6 @@ # See docs/tracing.txt for syntax documentation. -# target-i386/kvm.c +# target/i386/kvm.c kvm_x86_fixup_msi_error(uint32_t gsi) "VT-d failed to remap interrupt for GSI %" PRIu32 kvm_x86_add_msi_route(int virq) "Adding route entry for virq %d" kvm_x86_remove_msi_route(int virq) "Removing route entry for virq %d" diff --git a/target-i386/translate.c b/target/i386/translate.c index 324103c885..59e11fcd1f 100644 --- a/target-i386/translate.c +++ b/target/i386/translate.c @@ -2500,8 +2500,10 @@ static void gen_bnd_jmp(DisasContext *s) } /* Generate an end of block. Trace exception is also generated if needed. - If IIM, set HF_INHIBIT_IRQ_MASK if it isn't already set. */ -static void gen_eob_inhibit_irq(DisasContext *s, bool inhibit) + If INHIBIT, set HF_INHIBIT_IRQ_MASK if it isn't already set. + If RECHECK_TF, emit a rechecking helper for #DB, ignoring the state of + S->TF. This is used by the syscall/sysret insns. */ +static void gen_eob_worker(DisasContext *s, bool inhibit, bool recheck_tf) { gen_update_cc_op(s); @@ -2517,6 +2519,9 @@ static void gen_eob_inhibit_irq(DisasContext *s, bool inhibit) } if (s->singlestep_enabled) { gen_helper_debug(cpu_env); + } else if (recheck_tf) { + gen_helper_rechecking_single_step(cpu_env); + tcg_gen_exit_tb(0); } else if (s->tf) { gen_helper_single_step(cpu_env); } else { @@ -2525,10 +2530,17 @@ static void gen_eob_inhibit_irq(DisasContext *s, bool inhibit) s->is_jmp = DISAS_TB_JUMP; } +/* End of block. + If INHIBIT, set HF_INHIBIT_IRQ_MASK if it isn't already set. */ +static void gen_eob_inhibit_irq(DisasContext *s, bool inhibit) +{ + gen_eob_worker(s, inhibit, false); +} + /* End of block, resetting the inhibit irq flag. */ static void gen_eob(DisasContext *s) { - gen_eob_inhibit_irq(s, false); + gen_eob_worker(s, false, false); } /* generate a jump to eip. No segment change must happen before as a @@ -6423,7 +6435,10 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, tcg_const_i32(s->pc - s->cs_base)); set_cc_op(s, CC_OP_EFLAGS); } - gen_eob(s); + /* TF handling for the syscall insn is different. The TF bit is checked + after the syscall insn completes. This allows #DB to not be + generated after one has entered CPL0 if TF is set in FMASK. */ + gen_eob_worker(s, false, true); break; case 0xe8: /* call im */ { @@ -7115,7 +7130,11 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, if (s->lma) { set_cc_op(s, CC_OP_EFLAGS); } - gen_eob(s); + /* TF handling for the sysret insn is different. The TF bit is + checked after the sysret insn completes. This allows #DB to be + generated "as if" the syscall insn in userspace has just + completed. */ + gen_eob_worker(s, false, true); } break; #endif diff --git a/target-lm32/Makefile.objs b/target/lm32/Makefile.objs index c3e1bd6bd6..c3e1bd6bd6 100644 --- a/target-lm32/Makefile.objs +++ b/target/lm32/Makefile.objs diff --git a/target-lm32/README b/target/lm32/README index ba3508a711..ba3508a711 100644 --- a/target-lm32/README +++ b/target/lm32/README diff --git a/target-lm32/TODO b/target/lm32/TODO index e163c42ebe..e163c42ebe 100644 --- a/target-lm32/TODO +++ b/target/lm32/TODO diff --git a/target-lm32/cpu-qom.h b/target/lm32/cpu-qom.h index b423d2564b..b423d2564b 100644 --- a/target-lm32/cpu-qom.h +++ b/target/lm32/cpu-qom.h diff --git a/target-lm32/cpu.c b/target/lm32/cpu.c index 8d939a7779..8d939a7779 100644 --- a/target-lm32/cpu.c +++ b/target/lm32/cpu.c diff --git a/target-lm32/cpu.h b/target/lm32/cpu.h index d8a3515244..d8a3515244 100644 --- a/target-lm32/cpu.h +++ b/target/lm32/cpu.h diff --git a/target-lm32/gdbstub.c b/target/lm32/gdbstub.c index cf929dd392..cf929dd392 100644 --- a/target-lm32/gdbstub.c +++ b/target/lm32/gdbstub.c diff --git a/target-lm32/helper.c b/target/lm32/helper.c index 891da18c30..891da18c30 100644 --- a/target-lm32/helper.c +++ b/target/lm32/helper.c diff --git a/target-lm32/helper.h b/target/lm32/helper.h index 445578c439..445578c439 100644 --- a/target-lm32/helper.h +++ b/target/lm32/helper.h diff --git a/target-lm32/lm32-semi.c b/target/lm32/lm32-semi.c index 20f1a1cd48..6a11a6299a 100644 --- a/target-lm32/lm32-semi.c +++ b/target/lm32/lm32-semi.c @@ -3,7 +3,7 @@ * * Copyright (c) 2014 Michael Walle <michael@walle.cc> * - * Based on target-m68k/m68k-semi.c, which is + * Based on target/m68k/m68k-semi.c, which is * Copyright (c) 2005-2007 CodeSourcery. * * This work is licensed under the terms of the GNU GPL, version 2 or later. diff --git a/target-lm32/machine.c b/target/lm32/machine.c index 3c258a4bcc..3c258a4bcc 100644 --- a/target-lm32/machine.c +++ b/target/lm32/machine.c diff --git a/target-lm32/op_helper.c b/target/lm32/op_helper.c index 2177c8ad12..2177c8ad12 100644 --- a/target-lm32/op_helper.c +++ b/target/lm32/op_helper.c diff --git a/target-lm32/translate.c b/target/lm32/translate.c index 692882f447..692882f447 100644 --- a/target-lm32/translate.c +++ b/target/lm32/translate.c diff --git a/target-m68k/Makefile.objs b/target/m68k/Makefile.objs index 02cf616a78..02cf616a78 100644 --- a/target-m68k/Makefile.objs +++ b/target/m68k/Makefile.objs diff --git a/target-m68k/cpu-qom.h b/target/m68k/cpu-qom.h index 9885bba317..9885bba317 100644 --- a/target-m68k/cpu-qom.h +++ b/target/m68k/cpu-qom.h diff --git a/target-m68k/cpu.c b/target/m68k/cpu.c index ba17480098..ba17480098 100644 --- a/target-m68k/cpu.c +++ b/target/m68k/cpu.c diff --git a/target-m68k/cpu.h b/target/m68k/cpu.h index 6dfb54eb70..0b4ed7b8a6 100644 --- a/target-m68k/cpu.h +++ b/target/m68k/cpu.h @@ -95,10 +95,6 @@ typedef struct CPUM68KState { uint32_t macsr; uint32_t mac_mask; - /* Temporary storage for DIV helpers. */ - uint32_t div1; - uint32_t div2; - /* MMU status. */ struct { uint32_t ar; diff --git a/target-m68k/gdbstub.c b/target/m68k/gdbstub.c index c7f44c9bb3..c7f44c9bb3 100644 --- a/target-m68k/gdbstub.c +++ b/target/m68k/gdbstub.c diff --git a/target-m68k/helper.c b/target/m68k/helper.c index 7aed9ffd2f..f750d3dbaa 100644 --- a/target-m68k/helper.c +++ b/target/m68k/helper.c @@ -284,58 +284,6 @@ void HELPER(set_sr)(CPUM68KState *env, uint32_t val) m68k_switch_sp(env); } -uint32_t HELPER(shl_cc)(CPUM68KState *env, uint32_t val, uint32_t shift) -{ - uint64_t result; - - shift &= 63; - result = (uint64_t)val << shift; - - env->cc_c = (result >> 32) & 1; - env->cc_n = result; - env->cc_z = result; - env->cc_v = 0; - env->cc_x = shift ? env->cc_c : env->cc_x; - - return result; -} - -uint32_t HELPER(shr_cc)(CPUM68KState *env, uint32_t val, uint32_t shift) -{ - uint64_t temp; - uint32_t result; - - shift &= 63; - temp = (uint64_t)val << 32 >> shift; - result = temp >> 32; - - env->cc_c = (temp >> 31) & 1; - env->cc_n = result; - env->cc_z = result; - env->cc_v = 0; - env->cc_x = shift ? env->cc_c : env->cc_x; - - return result; -} - -uint32_t HELPER(sar_cc)(CPUM68KState *env, uint32_t val, uint32_t shift) -{ - uint64_t temp; - uint32_t result; - - shift &= 63; - temp = (int64_t)val << 32 >> shift; - result = temp >> 32; - - env->cc_c = (temp >> 31) & 1; - env->cc_n = result; - env->cc_z = result; - env->cc_v = result ^ val; - env->cc_x = shift ? env->cc_c : env->cc_x; - - return result; -} - /* FPU helpers. */ uint32_t HELPER(f64_to_i32)(CPUM68KState *env, float64 val) { diff --git a/target-m68k/helper.h b/target/m68k/helper.h index 2697e32d0b..17ec342346 100644 --- a/target-m68k/helper.h +++ b/target/m68k/helper.h @@ -1,13 +1,16 @@ DEF_HELPER_1(bitrev, i32, i32) DEF_HELPER_1(ff1, i32, i32) DEF_HELPER_FLAGS_2(sats, TCG_CALL_NO_RWG_SE, i32, i32, i32) -DEF_HELPER_2(divu, void, env, i32) -DEF_HELPER_2(divs, void, env, i32) -DEF_HELPER_3(shl_cc, i32, env, i32, i32) -DEF_HELPER_3(shr_cc, i32, env, i32, i32) -DEF_HELPER_3(sar_cc, i32, env, i32, i32) +DEF_HELPER_3(divuw, void, env, int, i32) +DEF_HELPER_3(divsw, void, env, int, s32) +DEF_HELPER_4(divul, void, env, int, int, i32) +DEF_HELPER_4(divsl, void, env, int, int, s32) +DEF_HELPER_4(divull, void, env, int, int, i32) +DEF_HELPER_4(divsll, void, env, int, int, s32) DEF_HELPER_2(set_sr, void, env, i32) DEF_HELPER_3(movec, void, env, i32, i32) +DEF_HELPER_4(cas2w, void, env, i32, i32, i32) +DEF_HELPER_4(cas2l, void, env, i32, i32, i32) DEF_HELPER_2(f64_to_i32, f32, env, f64) DEF_HELPER_2(f64_to_f32, f32, env, f64) diff --git a/target-m68k/m68k-semi.c b/target/m68k/m68k-semi.c index 1402145c8f..1402145c8f 100644 --- a/target-m68k/m68k-semi.c +++ b/target/m68k/m68k-semi.c diff --git a/target/m68k/op_helper.c b/target/m68k/op_helper.c new file mode 100644 index 0000000000..e56b815d73 --- /dev/null +++ b/target/m68k/op_helper.c @@ -0,0 +1,471 @@ +/* + * M68K helper routines + * + * Copyright (c) 2007 CodeSourcery + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * 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 "qemu/osdep.h" +#include "cpu.h" +#include "exec/helper-proto.h" +#include "exec/exec-all.h" +#include "exec/cpu_ldst.h" +#include "exec/semihost.h" + +#if defined(CONFIG_USER_ONLY) + +void m68k_cpu_do_interrupt(CPUState *cs) +{ + cs->exception_index = -1; +} + +static inline void do_interrupt_m68k_hardirq(CPUM68KState *env) +{ +} + +#else + +/* Try to fill the TLB and return an exception if error. If retaddr is + NULL, it means that the function was called in C code (i.e. not + from generated code or from helper.c) */ +void tlb_fill(CPUState *cs, target_ulong addr, MMUAccessType access_type, + int mmu_idx, uintptr_t retaddr) +{ + int ret; + + ret = m68k_cpu_handle_mmu_fault(cs, addr, access_type, mmu_idx); + if (unlikely(ret)) { + if (retaddr) { + /* now we have a real cpu fault */ + cpu_restore_state(cs, retaddr); + } + cpu_loop_exit(cs); + } +} + +static void do_rte(CPUM68KState *env) +{ + uint32_t sp; + uint32_t fmt; + + sp = env->aregs[7]; + fmt = cpu_ldl_kernel(env, sp); + env->pc = cpu_ldl_kernel(env, sp + 4); + sp |= (fmt >> 28) & 3; + env->aregs[7] = sp + 8; + + helper_set_sr(env, fmt); +} + +static void do_interrupt_all(CPUM68KState *env, int is_hw) +{ + CPUState *cs = CPU(m68k_env_get_cpu(env)); + uint32_t sp; + uint32_t fmt; + uint32_t retaddr; + uint32_t vector; + + fmt = 0; + retaddr = env->pc; + + if (!is_hw) { + switch (cs->exception_index) { + case EXCP_RTE: + /* Return from an exception. */ + do_rte(env); + return; + case EXCP_HALT_INSN: + if (semihosting_enabled() + && (env->sr & SR_S) != 0 + && (env->pc & 3) == 0 + && cpu_lduw_code(env, env->pc - 4) == 0x4e71 + && cpu_ldl_code(env, env->pc) == 0x4e7bf000) { + env->pc += 4; + do_m68k_semihosting(env, env->dregs[0]); + return; + } + cs->halted = 1; + cs->exception_index = EXCP_HLT; + cpu_loop_exit(cs); + return; + } + if (cs->exception_index >= EXCP_TRAP0 + && cs->exception_index <= EXCP_TRAP15) { + /* Move the PC after the trap instruction. */ + retaddr += 2; + } + } + + vector = cs->exception_index << 2; + + fmt |= 0x40000000; + fmt |= vector << 16; + fmt |= env->sr; + fmt |= cpu_m68k_get_ccr(env); + + env->sr |= SR_S; + if (is_hw) { + env->sr = (env->sr & ~SR_I) | (env->pending_level << SR_I_SHIFT); + env->sr &= ~SR_M; + } + m68k_switch_sp(env); + sp = env->aregs[7]; + fmt |= (sp & 3) << 28; + + /* ??? This could cause MMU faults. */ + sp &= ~3; + sp -= 4; + cpu_stl_kernel(env, sp, retaddr); + sp -= 4; + cpu_stl_kernel(env, sp, fmt); + env->aregs[7] = sp; + /* Jump to vector. */ + env->pc = cpu_ldl_kernel(env, env->vbr + vector); +} + +void m68k_cpu_do_interrupt(CPUState *cs) +{ + M68kCPU *cpu = M68K_CPU(cs); + CPUM68KState *env = &cpu->env; + + do_interrupt_all(env, 0); +} + +static inline void do_interrupt_m68k_hardirq(CPUM68KState *env) +{ + do_interrupt_all(env, 1); +} +#endif + +bool m68k_cpu_exec_interrupt(CPUState *cs, int interrupt_request) +{ + M68kCPU *cpu = M68K_CPU(cs); + CPUM68KState *env = &cpu->env; + + if (interrupt_request & CPU_INTERRUPT_HARD + && ((env->sr & SR_I) >> SR_I_SHIFT) < env->pending_level) { + /* Real hardware gets the interrupt vector via an IACK cycle + at this point. Current emulated hardware doesn't rely on + this, so we provide/save the vector when the interrupt is + first signalled. */ + cs->exception_index = env->pending_vector; + do_interrupt_m68k_hardirq(env); + return true; + } + return false; +} + +static void raise_exception_ra(CPUM68KState *env, int tt, uintptr_t raddr) +{ + CPUState *cs = CPU(m68k_env_get_cpu(env)); + + cs->exception_index = tt; + cpu_loop_exit_restore(cs, raddr); +} + +static void raise_exception(CPUM68KState *env, int tt) +{ + raise_exception_ra(env, tt, 0); +} + +void HELPER(raise_exception)(CPUM68KState *env, uint32_t tt) +{ + raise_exception(env, tt); +} + +void HELPER(divuw)(CPUM68KState *env, int destr, uint32_t den) +{ + uint32_t num = env->dregs[destr]; + uint32_t quot, rem; + + if (den == 0) { + raise_exception_ra(env, EXCP_DIV0, GETPC()); + } + quot = num / den; + rem = num % den; + + env->cc_c = 0; /* always cleared, even if overflow */ + if (quot > 0xffff) { + env->cc_v = -1; + /* real 68040 keeps N and unset Z on overflow, + * whereas documentation says "undefined" + */ + env->cc_z = 1; + return; + } + env->dregs[destr] = deposit32(quot, 16, 16, rem); + env->cc_z = (int16_t)quot; + env->cc_n = (int16_t)quot; + env->cc_v = 0; +} + +void HELPER(divsw)(CPUM68KState *env, int destr, int32_t den) +{ + int32_t num = env->dregs[destr]; + uint32_t quot, rem; + + if (den == 0) { + raise_exception_ra(env, EXCP_DIV0, GETPC()); + } + quot = num / den; + rem = num % den; + + env->cc_c = 0; /* always cleared, even if overflow */ + if (quot != (int16_t)quot) { + env->cc_v = -1; + /* nothing else is modified */ + /* real 68040 keeps N and unset Z on overflow, + * whereas documentation says "undefined" + */ + env->cc_z = 1; + return; + } + env->dregs[destr] = deposit32(quot, 16, 16, rem); + env->cc_z = (int16_t)quot; + env->cc_n = (int16_t)quot; + env->cc_v = 0; +} + +void HELPER(divul)(CPUM68KState *env, int numr, int regr, uint32_t den) +{ + uint32_t num = env->dregs[numr]; + uint32_t quot, rem; + + if (den == 0) { + raise_exception_ra(env, EXCP_DIV0, GETPC()); + } + quot = num / den; + rem = num % den; + + env->cc_c = 0; + env->cc_z = quot; + env->cc_n = quot; + env->cc_v = 0; + + if (m68k_feature(env, M68K_FEATURE_CF_ISA_A)) { + if (numr == regr) { + env->dregs[numr] = quot; + } else { + env->dregs[regr] = rem; + } + } else { + env->dregs[regr] = rem; + env->dregs[numr] = quot; + } +} + +void HELPER(divsl)(CPUM68KState *env, int numr, int regr, int32_t den) +{ + int32_t num = env->dregs[numr]; + int32_t quot, rem; + + if (den == 0) { + raise_exception_ra(env, EXCP_DIV0, GETPC()); + } + quot = num / den; + rem = num % den; + + env->cc_c = 0; + env->cc_z = quot; + env->cc_n = quot; + env->cc_v = 0; + + if (m68k_feature(env, M68K_FEATURE_CF_ISA_A)) { + if (numr == regr) { + env->dregs[numr] = quot; + } else { + env->dregs[regr] = rem; + } + } else { + env->dregs[regr] = rem; + env->dregs[numr] = quot; + } +} + +void HELPER(divull)(CPUM68KState *env, int numr, int regr, uint32_t den) +{ + uint64_t num = deposit64(env->dregs[numr], 32, 32, env->dregs[regr]); + uint64_t quot; + uint32_t rem; + + if (den == 0) { + raise_exception_ra(env, EXCP_DIV0, GETPC()); + } + quot = num / den; + rem = num % den; + + env->cc_c = 0; /* always cleared, even if overflow */ + if (quot > 0xffffffffULL) { + env->cc_v = -1; + /* real 68040 keeps N and unset Z on overflow, + * whereas documentation says "undefined" + */ + env->cc_z = 1; + return; + } + env->cc_z = quot; + env->cc_n = quot; + env->cc_v = 0; + + /* + * If Dq and Dr are the same, the quotient is returned. + * therefore we set Dq last. + */ + + env->dregs[regr] = rem; + env->dregs[numr] = quot; +} + +void HELPER(divsll)(CPUM68KState *env, int numr, int regr, int32_t den) +{ + int64_t num = deposit64(env->dregs[numr], 32, 32, env->dregs[regr]); + int64_t quot; + int32_t rem; + + if (den == 0) { + raise_exception_ra(env, EXCP_DIV0, GETPC()); + } + quot = num / den; + rem = num % den; + + env->cc_c = 0; /* always cleared, even if overflow */ + if (quot != (int32_t)quot) { + env->cc_v = -1; + /* real 68040 keeps N and unset Z on overflow, + * whereas documentation says "undefined" + */ + env->cc_z = 1; + return; + } + env->cc_z = quot; + env->cc_n = quot; + env->cc_v = 0; + + /* + * If Dq and Dr are the same, the quotient is returned. + * therefore we set Dq last. + */ + + env->dregs[regr] = rem; + env->dregs[numr] = quot; +} + +void HELPER(cas2w)(CPUM68KState *env, uint32_t regs, uint32_t a1, uint32_t a2) +{ + uint32_t Dc1 = extract32(regs, 9, 3); + uint32_t Dc2 = extract32(regs, 6, 3); + uint32_t Du1 = extract32(regs, 3, 3); + uint32_t Du2 = extract32(regs, 0, 3); + int16_t c1 = env->dregs[Dc1]; + int16_t c2 = env->dregs[Dc2]; + int16_t u1 = env->dregs[Du1]; + int16_t u2 = env->dregs[Du2]; + int16_t l1, l2; + uintptr_t ra = GETPC(); + + if (parallel_cpus) { + /* Tell the main loop we need to serialize this insn. */ + cpu_loop_exit_atomic(ENV_GET_CPU(env), ra); + } else { + /* We're executing in a serial context -- no need to be atomic. */ + l1 = cpu_lduw_data_ra(env, a1, ra); + l2 = cpu_lduw_data_ra(env, a2, ra); + if (l1 == c1 && l2 == c2) { + cpu_stw_data_ra(env, a1, u1, ra); + cpu_stw_data_ra(env, a2, u2, ra); + } + } + + if (c1 != l1) { + env->cc_n = l1; + env->cc_v = c1; + } else { + env->cc_n = l2; + env->cc_v = c2; + } + env->cc_op = CC_OP_CMPW; + env->dregs[Dc1] = deposit32(env->dregs[Dc1], 0, 16, l1); + env->dregs[Dc2] = deposit32(env->dregs[Dc2], 0, 16, l2); +} + +void HELPER(cas2l)(CPUM68KState *env, uint32_t regs, uint32_t a1, uint32_t a2) +{ + uint32_t Dc1 = extract32(regs, 9, 3); + uint32_t Dc2 = extract32(regs, 6, 3); + uint32_t Du1 = extract32(regs, 3, 3); + uint32_t Du2 = extract32(regs, 0, 3); + uint32_t c1 = env->dregs[Dc1]; + uint32_t c2 = env->dregs[Dc2]; + uint32_t u1 = env->dregs[Du1]; + uint32_t u2 = env->dregs[Du2]; + uint32_t l1, l2; + uintptr_t ra = GETPC(); +#if defined(CONFIG_ATOMIC64) && !defined(CONFIG_USER_ONLY) + int mmu_idx = cpu_mmu_index(env, 0); + TCGMemOpIdx oi; +#endif + + if (parallel_cpus) { + /* We're executing in a parallel context -- must be atomic. */ +#ifdef CONFIG_ATOMIC64 + uint64_t c, u, l; + if ((a1 & 7) == 0 && a2 == a1 + 4) { + c = deposit64(c2, 32, 32, c1); + u = deposit64(u2, 32, 32, u1); +#ifdef CONFIG_USER_ONLY + l = helper_atomic_cmpxchgq_be(env, a1, c, u); +#else + oi = make_memop_idx(MO_BEQ, mmu_idx); + l = helper_atomic_cmpxchgq_be_mmu(env, a1, c, u, oi, ra); +#endif + l1 = l >> 32; + l2 = l; + } else if ((a2 & 7) == 0 && a1 == a2 + 4) { + c = deposit64(c1, 32, 32, c2); + u = deposit64(u1, 32, 32, u2); +#ifdef CONFIG_USER_ONLY + l = helper_atomic_cmpxchgq_be(env, a2, c, u); +#else + oi = make_memop_idx(MO_BEQ, mmu_idx); + l = helper_atomic_cmpxchgq_be_mmu(env, a2, c, u, oi, ra); +#endif + l2 = l >> 32; + l1 = l; + } else +#endif + { + /* Tell the main loop we need to serialize this insn. */ + cpu_loop_exit_atomic(ENV_GET_CPU(env), ra); + } + } else { + /* We're executing in a serial context -- no need to be atomic. */ + l1 = cpu_ldl_data_ra(env, a1, ra); + l2 = cpu_ldl_data_ra(env, a2, ra); + if (l1 == c1 && l2 == c2) { + cpu_stl_data_ra(env, a1, u1, ra); + cpu_stl_data_ra(env, a2, u2, ra); + } + } + + if (c1 != l1) { + env->cc_n = l1; + env->cc_v = c1; + } else { + env->cc_n = l2; + env->cc_v = c2; + } + env->cc_op = CC_OP_CMPL; + env->dregs[Dc1] = l1; + env->dregs[Dc2] = l2; +} diff --git a/target-m68k/qregs.def b/target/m68k/qregs.def index 156c0f558f..51ff43bf33 100644 --- a/target-m68k/qregs.def +++ b/target/m68k/qregs.def @@ -7,7 +7,5 @@ DEFO32(CC_C, cc_c) DEFO32(CC_N, cc_n) DEFO32(CC_V, cc_v) DEFO32(CC_Z, cc_z) -DEFO32(DIV1, div1) -DEFO32(DIV2, div2) DEFO32(MACSR, macsr) DEFO32(MAC_MASK, mac_mask) diff --git a/target-m68k/translate.c b/target/m68k/translate.c index d6ed883882..53293173c5 100644 --- a/target-m68k/translate.c +++ b/target/m68k/translate.c @@ -59,12 +59,12 @@ static TCGv cpu_aregs[8]; static TCGv_i64 cpu_fregs[8]; static TCGv_i64 cpu_macc[4]; -#define REG(insn, pos) (((insn) >> (pos)) & 7) +#define REG(insn, pos) (((insn) >> (pos)) & 7) #define DREG(insn, pos) cpu_dregs[REG(insn, pos)] -#define AREG(insn, pos) cpu_aregs[REG(insn, pos)] +#define AREG(insn, pos) get_areg(s, REG(insn, pos)) #define FREG(insn, pos) cpu_fregs[REG(insn, pos)] -#define MACREG(acc) cpu_macc[acc] -#define QREG_SP cpu_aregs[7] +#define MACREG(acc) cpu_macc[acc] +#define QREG_SP get_areg(s, 7) static TCGv NULL_QREG; #define IS_NULL_QREG(t) (TCGV_EQUAL(t, NULL_QREG)) @@ -141,8 +141,55 @@ typedef struct DisasContext { int singlestep_enabled; TCGv_i64 mactmp; int done_mac; + int writeback_mask; + TCGv writeback[8]; } DisasContext; +static TCGv get_areg(DisasContext *s, unsigned regno) +{ + if (s->writeback_mask & (1 << regno)) { + return s->writeback[regno]; + } else { + return cpu_aregs[regno]; + } +} + +static void delay_set_areg(DisasContext *s, unsigned regno, + TCGv val, bool give_temp) +{ + if (s->writeback_mask & (1 << regno)) { + if (give_temp) { + tcg_temp_free(s->writeback[regno]); + s->writeback[regno] = val; + } else { + tcg_gen_mov_i32(s->writeback[regno], val); + } + } else { + s->writeback_mask |= 1 << regno; + if (give_temp) { + s->writeback[regno] = val; + } else { + TCGv tmp = tcg_temp_new(); + s->writeback[regno] = tmp; + tcg_gen_mov_i32(tmp, val); + } + } +} + +static void do_writebacks(DisasContext *s) +{ + unsigned mask = s->writeback_mask; + if (mask) { + s->writeback_mask = 0; + do { + unsigned regno = ctz32(mask); + tcg_gen_mov_i32(cpu_aregs[regno], s->writeback[regno]); + tcg_temp_free(s->writeback[regno]); + mask &= mask - 1; + } while (mask); + } +} + #define DISAS_JUMP_NEXT 4 #if defined(CONFIG_USER_ONLY) @@ -331,7 +378,7 @@ static inline uint32_t read_im32(CPUM68KState *env, DisasContext *s) } /* Calculate and address index. */ -static TCGv gen_addr_index(uint16_t ext, TCGv tmp) +static TCGv gen_addr_index(DisasContext *s, uint16_t ext, TCGv tmp) { TCGv add; int scale; @@ -388,7 +435,7 @@ static TCGv gen_lea_indexed(CPUM68KState *env, DisasContext *s, TCGv base) tmp = tcg_temp_new(); if ((ext & 0x44) == 0) { /* pre-index */ - add = gen_addr_index(ext, tmp); + add = gen_addr_index(s, ext, tmp); } else { add = NULL_QREG; } @@ -417,7 +464,7 @@ static TCGv gen_lea_indexed(CPUM68KState *env, DisasContext *s, TCGv base) /* memory indirect */ base = gen_load(s, OS_LONG, add, 0); if ((ext & 0x44) == 4) { - add = gen_addr_index(ext, tmp); + add = gen_addr_index(s, ext, tmp); tcg_gen_add_i32(tmp, add, base); add = tmp; } else { @@ -441,7 +488,7 @@ static TCGv gen_lea_indexed(CPUM68KState *env, DisasContext *s, TCGv base) } else { /* brief extension word format */ tmp = tcg_temp_new(); - add = gen_addr_index(ext, tmp); + add = gen_addr_index(s, ext, tmp); if (!IS_NULL_QREG(base)) { tcg_gen_add_i32(tmp, add, base); if ((int8_t)ext) @@ -632,12 +679,14 @@ static void gen_partset_reg(int opsize, TCGv reg, TCGv val) tmp = tcg_temp_new(); tcg_gen_ext8u_i32(tmp, val); tcg_gen_or_i32(reg, reg, tmp); + tcg_temp_free(tmp); break; case OS_WORD: tcg_gen_andi_i32(reg, reg, 0xffff0000); tmp = tcg_temp_new(); tcg_gen_ext16u_i32(tmp, val); tcg_gen_or_i32(reg, reg, tmp); + tcg_temp_free(tmp); break; case OS_LONG: case OS_SINGLE: @@ -650,37 +699,37 @@ static void gen_partset_reg(int opsize, TCGv reg, TCGv val) /* Generate code for an "effective address". Does not adjust the base register for autoincrement addressing modes. */ -static TCGv gen_lea(CPUM68KState *env, DisasContext *s, uint16_t insn, - int opsize) +static TCGv gen_lea_mode(CPUM68KState *env, DisasContext *s, + int mode, int reg0, int opsize) { TCGv reg; TCGv tmp; uint16_t ext; uint32_t offset; - switch ((insn >> 3) & 7) { + switch (mode) { case 0: /* Data register direct. */ case 1: /* Address register direct. */ return NULL_QREG; case 2: /* Indirect register */ case 3: /* Indirect postincrement. */ - return AREG(insn, 0); + return get_areg(s, reg0); case 4: /* Indirect predecrememnt. */ - reg = AREG(insn, 0); + reg = get_areg(s, reg0); tmp = tcg_temp_new(); tcg_gen_subi_i32(tmp, reg, opsize_bytes(opsize)); return tmp; case 5: /* Indirect displacement. */ - reg = AREG(insn, 0); + reg = get_areg(s, reg0); tmp = tcg_temp_new(); ext = read_im16(env, s); tcg_gen_addi_i32(tmp, reg, (int16_t)ext); return tmp; case 6: /* Indirect index + displacement. */ - reg = AREG(insn, 0); + reg = get_areg(s, reg0); return gen_lea_indexed(env, s, reg); case 7: /* Other */ - switch (insn & 7) { + switch (reg0) { case 0: /* Absolute short. */ offset = (int16_t)read_im16(env, s); return tcg_const_i32(offset); @@ -702,39 +751,26 @@ static TCGv gen_lea(CPUM68KState *env, DisasContext *s, uint16_t insn, return NULL_QREG; } -/* Helper function for gen_ea. Reuse the computed address between the - for read/write operands. */ -static inline TCGv gen_ea_once(CPUM68KState *env, DisasContext *s, - uint16_t insn, int opsize, TCGv val, - TCGv *addrp, ea_what what) +static TCGv gen_lea(CPUM68KState *env, DisasContext *s, uint16_t insn, + int opsize) { - TCGv tmp; - - if (addrp && what == EA_STORE) { - tmp = *addrp; - } else { - tmp = gen_lea(env, s, insn, opsize); - if (IS_NULL_QREG(tmp)) - return tmp; - if (addrp) - *addrp = tmp; - } - return gen_ldst(s, opsize, tmp, val, what); + int mode = extract32(insn, 3, 3); + int reg0 = REG(insn, 0); + return gen_lea_mode(env, s, mode, reg0, opsize); } -/* Generate code to load/store a value from/into an EA. If VAL > 0 this is +/* Generate code to load/store a value from/into an EA. If WHAT > 0 this is a write otherwise it is a read (0 == sign extend, -1 == zero extend). ADDRP is non-null for readwrite operands. */ -static TCGv gen_ea(CPUM68KState *env, DisasContext *s, uint16_t insn, - int opsize, TCGv val, TCGv *addrp, ea_what what) +static TCGv gen_ea_mode(CPUM68KState *env, DisasContext *s, int mode, int reg0, + int opsize, TCGv val, TCGv *addrp, ea_what what) { - TCGv reg; - TCGv result; - uint32_t offset; + TCGv reg, tmp, result; + int32_t offset; - switch ((insn >> 3) & 7) { + switch (mode) { case 0: /* Data register direct. */ - reg = DREG(insn, 0); + reg = cpu_dregs[reg0]; if (what == EA_STORE) { gen_partset_reg(opsize, reg, val); return store_dummy; @@ -742,7 +778,7 @@ static TCGv gen_ea(CPUM68KState *env, DisasContext *s, uint16_t insn, return gen_extend(reg, opsize, what == EA_LOADS); } case 1: /* Address register direct. */ - reg = AREG(insn, 0); + reg = get_areg(s, reg0); if (what == EA_STORE) { tcg_gen_mov_i32(reg, val); return store_dummy; @@ -750,47 +786,56 @@ static TCGv gen_ea(CPUM68KState *env, DisasContext *s, uint16_t insn, return gen_extend(reg, opsize, what == EA_LOADS); } case 2: /* Indirect register */ - reg = AREG(insn, 0); + reg = get_areg(s, reg0); return gen_ldst(s, opsize, reg, val, what); case 3: /* Indirect postincrement. */ - reg = AREG(insn, 0); + reg = get_areg(s, reg0); result = gen_ldst(s, opsize, reg, val, what); - /* ??? This is not exception safe. The instruction may still - fault after this point. */ - if (what == EA_STORE || !addrp) - tcg_gen_addi_i32(reg, reg, opsize_bytes(opsize)); + if (what == EA_STORE || !addrp) { + TCGv tmp = tcg_temp_new(); + tcg_gen_addi_i32(tmp, reg, opsize_bytes(opsize)); + delay_set_areg(s, reg0, tmp, true); + } return result; case 4: /* Indirect predecrememnt. */ - { - TCGv tmp; - if (addrp && what == EA_STORE) { - tmp = *addrp; - } else { - tmp = gen_lea(env, s, insn, opsize); - if (IS_NULL_QREG(tmp)) - return tmp; - if (addrp) - *addrp = tmp; + if (addrp && what == EA_STORE) { + tmp = *addrp; + } else { + tmp = gen_lea_mode(env, s, mode, reg0, opsize); + if (IS_NULL_QREG(tmp)) { + return tmp; } - result = gen_ldst(s, opsize, tmp, val, what); - /* ??? This is not exception safe. The instruction may still - fault after this point. */ - if (what == EA_STORE || !addrp) { - reg = AREG(insn, 0); - tcg_gen_mov_i32(reg, tmp); + if (addrp) { + *addrp = tmp; } } + result = gen_ldst(s, opsize, tmp, val, what); + if (what == EA_STORE || !addrp) { + delay_set_areg(s, reg0, tmp, false); + } return result; case 5: /* Indirect displacement. */ case 6: /* Indirect index + displacement. */ - return gen_ea_once(env, s, insn, opsize, val, addrp, what); + do_indirect: + if (addrp && what == EA_STORE) { + tmp = *addrp; + } else { + tmp = gen_lea_mode(env, s, mode, reg0, opsize); + if (IS_NULL_QREG(tmp)) { + return tmp; + } + if (addrp) { + *addrp = tmp; + } + } + return gen_ldst(s, opsize, tmp, val, what); case 7: /* Other */ - switch (insn & 7) { + switch (reg0) { case 0: /* Absolute short. */ case 1: /* Absolute long. */ case 2: /* pc displacement */ case 3: /* pc index+displacement. */ - return gen_ea_once(env, s, insn, opsize, val, addrp, what); + goto do_indirect; case 4: /* Immediate. */ /* Sign extend values for consistency. */ switch (opsize) { @@ -823,6 +868,14 @@ static TCGv gen_ea(CPUM68KState *env, DisasContext *s, uint16_t insn, return NULL_QREG; } +static TCGv gen_ea(CPUM68KState *env, DisasContext *s, uint16_t insn, + int opsize, TCGv val, TCGv *addrp, ea_what what) +{ + int mode = extract32(insn, 3, 3); + int reg0 = REG(insn, 0); + return gen_ea_mode(env, s, mode, reg0, opsize, val, addrp, what); +} + typedef struct { TCGCond tcond; bool g1; @@ -1054,11 +1107,19 @@ static void gen_jmp(DisasContext *s, TCGv dest) s->is_jmp = DISAS_JUMP; } +static void gen_raise_exception(int nr) +{ + TCGv_i32 tmp = tcg_const_i32(nr); + + gen_helper_raise_exception(cpu_env, tmp); + tcg_temp_free_i32(tmp); +} + static void gen_exception(DisasContext *s, uint32_t where, int nr) { update_cc_op(s); gen_jmp_im(s, where); - gen_helper_raise_exception(cpu_env, tcg_const_i32(nr)); + gen_raise_exception(nr); } static inline void gen_addr_fault(DisasContext *s) @@ -1163,10 +1224,12 @@ DISAS_INSN(undef_fpu) DISAS_INSN(undef) { - M68kCPU *cpu = m68k_env_get_cpu(env); - + /* ??? This is both instructions that are as yet unimplemented + for the 680x0 series, as well as those that are implemented + but actually illegal for CPU32 or pre-68020. */ + qemu_log_mask(LOG_UNIMP, "Illegal instruction: %04x @ %08x", + insn, s->pc - 2); gen_exception(s, s->pc - 2, EXCP_UNSUPPORTED); - cpu_abort(CPU(cpu), "Illegal instruction: %04x @ %08x", insn, s->pc - 2); } DISAS_INSN(mulw) @@ -1187,71 +1250,297 @@ DISAS_INSN(mulw) tcg_gen_mul_i32(tmp, tmp, src); tcg_gen_mov_i32(reg, tmp); gen_logic_cc(s, tmp, OS_LONG); + tcg_temp_free(tmp); } DISAS_INSN(divw) { - TCGv reg; - TCGv tmp; - TCGv src; int sign; + TCGv src; + TCGv destr; + + /* divX.w <EA>,Dn 32/16 -> 16r:16q */ sign = (insn & 0x100) != 0; - reg = DREG(insn, 9); - if (sign) { - tcg_gen_ext16s_i32(QREG_DIV1, reg); - } else { - tcg_gen_ext16u_i32(QREG_DIV1, reg); - } + + /* dest.l / src.w */ + SRC_EA(env, src, OS_WORD, sign, NULL); - tcg_gen_mov_i32(QREG_DIV2, src); + destr = tcg_const_i32(REG(insn, 9)); if (sign) { - gen_helper_divs(cpu_env, tcg_const_i32(1)); + gen_helper_divsw(cpu_env, destr, src); } else { - gen_helper_divu(cpu_env, tcg_const_i32(1)); + gen_helper_divuw(cpu_env, destr, src); } - - tmp = tcg_temp_new(); - src = tcg_temp_new(); - tcg_gen_ext16u_i32(tmp, QREG_DIV1); - tcg_gen_shli_i32(src, QREG_DIV2, 16); - tcg_gen_or_i32(reg, tmp, src); + tcg_temp_free(destr); set_cc_op(s, CC_OP_FLAGS); } DISAS_INSN(divl) { - TCGv num; - TCGv den; - TCGv reg; + TCGv num, reg, den; + int sign; uint16_t ext; ext = read_im16(env, s); - if (ext & 0x87f8) { - gen_exception(s, s->pc - 4, EXCP_UNSUPPORTED); + + sign = (ext & 0x0800) != 0; + + if (ext & 0x400) { + if (!m68k_feature(s->env, M68K_FEATURE_QUAD_MULDIV)) { + gen_exception(s, s->insn_pc, EXCP_ILLEGAL); + return; + } + + /* divX.l <EA>, Dr:Dq 64/32 -> 32r:32q */ + + SRC_EA(env, den, OS_LONG, 0, NULL); + num = tcg_const_i32(REG(ext, 12)); + reg = tcg_const_i32(REG(ext, 0)); + if (sign) { + gen_helper_divsll(cpu_env, num, reg, den); + } else { + gen_helper_divull(cpu_env, num, reg, den); + } + tcg_temp_free(reg); + tcg_temp_free(num); + set_cc_op(s, CC_OP_FLAGS); return; } - num = DREG(ext, 12); - reg = DREG(ext, 0); - tcg_gen_mov_i32(QREG_DIV1, num); + + /* divX.l <EA>, Dq 32/32 -> 32q */ + /* divXl.l <EA>, Dr:Dq 32/32 -> 32r:32q */ + SRC_EA(env, den, OS_LONG, 0, NULL); - tcg_gen_mov_i32(QREG_DIV2, den); - if (ext & 0x0800) { - gen_helper_divs(cpu_env, tcg_const_i32(0)); - } else { - gen_helper_divu(cpu_env, tcg_const_i32(0)); - } - if ((ext & 7) == ((ext >> 12) & 7)) { - /* div */ - tcg_gen_mov_i32 (reg, QREG_DIV1); + num = tcg_const_i32(REG(ext, 12)); + reg = tcg_const_i32(REG(ext, 0)); + if (sign) { + gen_helper_divsl(cpu_env, num, reg, den); } else { - /* rem */ - tcg_gen_mov_i32 (reg, QREG_DIV2); + gen_helper_divul(cpu_env, num, reg, den); } + tcg_temp_free(reg); + tcg_temp_free(num); + set_cc_op(s, CC_OP_FLAGS); } +static void bcd_add(TCGv dest, TCGv src) +{ + TCGv t0, t1; + + /* dest10 = dest10 + src10 + X + * + * t1 = src + * t2 = t1 + 0x066 + * t3 = t2 + dest + X + * t4 = t2 ^ dest + * t5 = t3 ^ t4 + * t6 = ~t5 & 0x110 + * t7 = (t6 >> 2) | (t6 >> 3) + * return t3 - t7 + */ + + /* t1 = (src + 0x066) + dest + X + * = result with some possible exceding 0x6 + */ + + t0 = tcg_const_i32(0x066); + tcg_gen_add_i32(t0, t0, src); + + t1 = tcg_temp_new(); + tcg_gen_add_i32(t1, t0, dest); + tcg_gen_add_i32(t1, t1, QREG_CC_X); + + /* we will remove exceding 0x6 where there is no carry */ + + /* t0 = (src + 0x0066) ^ dest + * = t1 without carries + */ + + tcg_gen_xor_i32(t0, t0, dest); + + /* extract the carries + * t0 = t0 ^ t1 + * = only the carries + */ + + tcg_gen_xor_i32(t0, t0, t1); + + /* generate 0x1 where there is no carry + * and for each 0x10, generate a 0x6 + */ + + tcg_gen_shri_i32(t0, t0, 3); + tcg_gen_not_i32(t0, t0); + tcg_gen_andi_i32(t0, t0, 0x22); + tcg_gen_add_i32(dest, t0, t0); + tcg_gen_add_i32(dest, dest, t0); + tcg_temp_free(t0); + + /* remove the exceding 0x6 + * for digits that have not generated a carry + */ + + tcg_gen_sub_i32(dest, t1, dest); + tcg_temp_free(t1); +} + +static void bcd_sub(TCGv dest, TCGv src) +{ + TCGv t0, t1, t2; + + /* dest10 = dest10 - src10 - X + * = bcd_add(dest + 1 - X, 0x199 - src) + */ + + /* t0 = 0x066 + (0x199 - src) */ + + t0 = tcg_temp_new(); + tcg_gen_subfi_i32(t0, 0x1ff, src); + + /* t1 = t0 + dest + 1 - X*/ + + t1 = tcg_temp_new(); + tcg_gen_add_i32(t1, t0, dest); + tcg_gen_addi_i32(t1, t1, 1); + tcg_gen_sub_i32(t1, t1, QREG_CC_X); + + /* t2 = t0 ^ dest */ + + t2 = tcg_temp_new(); + tcg_gen_xor_i32(t2, t0, dest); + + /* t0 = t1 ^ t2 */ + + tcg_gen_xor_i32(t0, t1, t2); + + /* t2 = ~t0 & 0x110 + * t0 = (t2 >> 2) | (t2 >> 3) + * + * to fit on 8bit operands, changed in: + * + * t2 = ~(t0 >> 3) & 0x22 + * t0 = t2 + t2 + * t0 = t0 + t2 + */ + + tcg_gen_shri_i32(t2, t0, 3); + tcg_gen_not_i32(t2, t2); + tcg_gen_andi_i32(t2, t2, 0x22); + tcg_gen_add_i32(t0, t2, t2); + tcg_gen_add_i32(t0, t0, t2); + tcg_temp_free(t2); + + /* return t1 - t0 */ + + tcg_gen_sub_i32(dest, t1, t0); + tcg_temp_free(t0); + tcg_temp_free(t1); +} + +static void bcd_flags(TCGv val) +{ + tcg_gen_andi_i32(QREG_CC_C, val, 0x0ff); + tcg_gen_or_i32(QREG_CC_Z, QREG_CC_Z, QREG_CC_C); + + tcg_gen_shri_i32(QREG_CC_C, val, 8); + tcg_gen_andi_i32(QREG_CC_C, QREG_CC_C, 1); + + tcg_gen_mov_i32(QREG_CC_X, QREG_CC_C); +} + +DISAS_INSN(abcd_reg) +{ + TCGv src; + TCGv dest; + + gen_flush_flags(s); /* !Z is sticky */ + + src = gen_extend(DREG(insn, 0), OS_BYTE, 0); + dest = gen_extend(DREG(insn, 9), OS_BYTE, 0); + bcd_add(dest, src); + gen_partset_reg(OS_BYTE, DREG(insn, 9), dest); + + bcd_flags(dest); +} + +DISAS_INSN(abcd_mem) +{ + TCGv src, dest, addr; + + gen_flush_flags(s); /* !Z is sticky */ + + /* Indirect pre-decrement load (mode 4) */ + + src = gen_ea_mode(env, s, 4, REG(insn, 0), OS_BYTE, + NULL_QREG, NULL, EA_LOADU); + dest = gen_ea_mode(env, s, 4, REG(insn, 9), OS_BYTE, + NULL_QREG, &addr, EA_LOADU); + + bcd_add(dest, src); + + gen_ea_mode(env, s, 4, REG(insn, 9), OS_BYTE, dest, &addr, EA_STORE); + + bcd_flags(dest); +} + +DISAS_INSN(sbcd_reg) +{ + TCGv src, dest; + + gen_flush_flags(s); /* !Z is sticky */ + + src = gen_extend(DREG(insn, 0), OS_BYTE, 0); + dest = gen_extend(DREG(insn, 9), OS_BYTE, 0); + + bcd_sub(dest, src); + + gen_partset_reg(OS_BYTE, DREG(insn, 9), dest); + + bcd_flags(dest); +} + +DISAS_INSN(sbcd_mem) +{ + TCGv src, dest, addr; + + gen_flush_flags(s); /* !Z is sticky */ + + /* Indirect pre-decrement load (mode 4) */ + + src = gen_ea_mode(env, s, 4, REG(insn, 0), OS_BYTE, + NULL_QREG, NULL, EA_LOADU); + dest = gen_ea_mode(env, s, 4, REG(insn, 9), OS_BYTE, + NULL_QREG, &addr, EA_LOADU); + + bcd_sub(dest, src); + + gen_ea_mode(env, s, 4, REG(insn, 9), OS_BYTE, dest, &addr, EA_STORE); + + bcd_flags(dest); +} + +DISAS_INSN(nbcd) +{ + TCGv src, dest; + TCGv addr; + + gen_flush_flags(s); /* !Z is sticky */ + + SRC_EA(env, src, OS_BYTE, 0, &addr); + + dest = tcg_const_i32(0); + bcd_sub(dest, src); + + DEST_EA(env, insn, OS_BYTE, dest, &addr); + + bcd_flags(dest); + + tcg_temp_free(dest); +} + DISAS_INSN(addsub) { TCGv reg; @@ -1367,42 +1656,125 @@ static void gen_push(DisasContext *s, TCGv val) tcg_gen_subi_i32(tmp, QREG_SP, 4); gen_store(s, OS_LONG, tmp, val); tcg_gen_mov_i32(QREG_SP, tmp); + tcg_temp_free(tmp); +} + +static TCGv mreg(int reg) +{ + if (reg < 8) { + /* Dx */ + return cpu_dregs[reg]; + } + /* Ax */ + return cpu_aregs[reg & 7]; } DISAS_INSN(movem) { - TCGv addr; + TCGv addr, incr, tmp, r[16]; + int is_load = (insn & 0x0400) != 0; + int opsize = (insn & 0x40) != 0 ? OS_LONG : OS_WORD; + uint16_t mask = read_im16(env, s); + int mode = extract32(insn, 3, 3); + int reg0 = REG(insn, 0); int i; - uint16_t mask; - TCGv reg; - TCGv tmp; - int is_load; - mask = read_im16(env, s); - tmp = gen_lea(env, s, insn, OS_LONG); - if (IS_NULL_QREG(tmp)) { + tmp = cpu_aregs[reg0]; + + switch (mode) { + case 0: /* data register direct */ + case 1: /* addr register direct */ + do_addr_fault: gen_addr_fault(s); return; + + case 2: /* indirect */ + break; + + case 3: /* indirect post-increment */ + if (!is_load) { + /* post-increment is not allowed */ + goto do_addr_fault; + } + break; + + case 4: /* indirect pre-decrement */ + if (is_load) { + /* pre-decrement is not allowed */ + goto do_addr_fault; + } + /* We want a bare copy of the address reg, without any pre-decrement + adjustment, as gen_lea would provide. */ + break; + + default: + tmp = gen_lea_mode(env, s, mode, reg0, opsize); + if (IS_NULL_QREG(tmp)) { + goto do_addr_fault; + } + break; } + addr = tcg_temp_new(); tcg_gen_mov_i32(addr, tmp); - is_load = ((insn & 0x0400) != 0); - for (i = 0; i < 16; i++, mask >>= 1) { - if (mask & 1) { - if (i < 8) - reg = DREG(i, 0); - else - reg = AREG(i, 0); - if (is_load) { - tmp = gen_load(s, OS_LONG, addr, 0); - tcg_gen_mov_i32(reg, tmp); - } else { - gen_store(s, OS_LONG, addr, reg); + incr = tcg_const_i32(opsize_bytes(opsize)); + + if (is_load) { + /* memory to register */ + for (i = 0; i < 16; i++) { + if (mask & (1 << i)) { + r[i] = gen_load(s, opsize, addr, 1); + tcg_gen_add_i32(addr, addr, incr); + } + } + for (i = 0; i < 16; i++) { + if (mask & (1 << i)) { + tcg_gen_mov_i32(mreg(i), r[i]); + tcg_temp_free(r[i]); + } + } + if (mode == 3) { + /* post-increment: movem (An)+,X */ + tcg_gen_mov_i32(cpu_aregs[reg0], addr); + } + } else { + /* register to memory */ + if (mode == 4) { + /* pre-decrement: movem X,-(An) */ + for (i = 15; i >= 0; i--) { + if ((mask << i) & 0x8000) { + tcg_gen_sub_i32(addr, addr, incr); + if (reg0 + 8 == i && + m68k_feature(s->env, M68K_FEATURE_EXT_FULL)) { + /* M68020+: if the addressing register is the + * register moved to memory, the value written + * is the initial value decremented by the size of + * the operation, regardless of how many actual + * stores have been performed until this point. + * M68000/M68010: the value is the initial value. + */ + tmp = tcg_temp_new(); + tcg_gen_sub_i32(tmp, cpu_aregs[reg0], incr); + gen_store(s, opsize, addr, tmp); + tcg_temp_free(tmp); + } else { + gen_store(s, opsize, addr, mreg(i)); + } + } + } + tcg_gen_mov_i32(cpu_aregs[reg0], addr); + } else { + for (i = 0; i < 16; i++) { + if (mask & (1 << i)) { + gen_store(s, opsize, addr, mreg(i)); + tcg_gen_add_i32(addr, addr, incr); + } } - if (mask != 1) - tcg_gen_addi_i32(addr, addr, 4); } } + + tcg_temp_free(incr); + tcg_temp_free(addr); } DISAS_INSN(bitop_im) @@ -1522,6 +1894,155 @@ DISAS_INSN(arith_im) tcg_temp_free(dest); } +DISAS_INSN(cas) +{ + int opsize; + TCGv addr; + uint16_t ext; + TCGv load; + TCGv cmp; + TCGMemOp opc; + + switch ((insn >> 9) & 3) { + case 1: + opsize = OS_BYTE; + opc = MO_SB; + break; + case 2: + opsize = OS_WORD; + opc = MO_TESW; + break; + case 3: + opsize = OS_LONG; + opc = MO_TESL; + break; + default: + g_assert_not_reached(); + } + opc |= MO_ALIGN; + + ext = read_im16(env, s); + + /* cas Dc,Du,<EA> */ + + addr = gen_lea(env, s, insn, opsize); + if (IS_NULL_QREG(addr)) { + gen_addr_fault(s); + return; + } + + cmp = gen_extend(DREG(ext, 0), opsize, 1); + + /* if <EA> == Dc then + * <EA> = Du + * Dc = <EA> (because <EA> == Dc) + * else + * Dc = <EA> + */ + + load = tcg_temp_new(); + tcg_gen_atomic_cmpxchg_i32(load, addr, cmp, DREG(ext, 6), + IS_USER(s), opc); + /* update flags before setting cmp to load */ + gen_update_cc_cmp(s, load, cmp, opsize); + gen_partset_reg(opsize, DREG(ext, 0), load); + + tcg_temp_free(load); +} + +DISAS_INSN(cas2w) +{ + uint16_t ext1, ext2; + TCGv addr1, addr2; + TCGv regs; + + /* cas2 Dc1:Dc2,Du1:Du2,(Rn1):(Rn2) */ + + ext1 = read_im16(env, s); + + if (ext1 & 0x8000) { + /* Address Register */ + addr1 = AREG(ext1, 12); + } else { + /* Data Register */ + addr1 = DREG(ext1, 12); + } + + ext2 = read_im16(env, s); + if (ext2 & 0x8000) { + /* Address Register */ + addr2 = AREG(ext2, 12); + } else { + /* Data Register */ + addr2 = DREG(ext2, 12); + } + + /* if (R1) == Dc1 && (R2) == Dc2 then + * (R1) = Du1 + * (R2) = Du2 + * else + * Dc1 = (R1) + * Dc2 = (R2) + */ + + regs = tcg_const_i32(REG(ext2, 6) | + (REG(ext1, 6) << 3) | + (REG(ext2, 0) << 6) | + (REG(ext1, 0) << 9)); + gen_helper_cas2w(cpu_env, regs, addr1, addr2); + tcg_temp_free(regs); + + /* Note that cas2w also assigned to env->cc_op. */ + s->cc_op = CC_OP_CMPW; + s->cc_op_synced = 1; +} + +DISAS_INSN(cas2l) +{ + uint16_t ext1, ext2; + TCGv addr1, addr2, regs; + + /* cas2 Dc1:Dc2,Du1:Du2,(Rn1):(Rn2) */ + + ext1 = read_im16(env, s); + + if (ext1 & 0x8000) { + /* Address Register */ + addr1 = AREG(ext1, 12); + } else { + /* Data Register */ + addr1 = DREG(ext1, 12); + } + + ext2 = read_im16(env, s); + if (ext2 & 0x8000) { + /* Address Register */ + addr2 = AREG(ext2, 12); + } else { + /* Data Register */ + addr2 = DREG(ext2, 12); + } + + /* if (R1) == Dc1 && (R2) == Dc2 then + * (R1) = Du1 + * (R2) = Du2 + * else + * Dc1 = (R1) + * Dc2 = (R2) + */ + + regs = tcg_const_i32(REG(ext2, 6) | + (REG(ext1, 6) << 3) | + (REG(ext2, 0) << 6) | + (REG(ext1, 0) << 9)); + gen_helper_cas2l(cpu_env, regs, addr1, addr2); + tcg_temp_free(regs); + + /* Note that cas2l also assigned to env->cc_op. */ + s->cc_op = CC_OP_CMPL; + s->cc_op_synced = 1; +} + DISAS_INSN(byterev) { TCGv reg; @@ -1626,10 +2147,14 @@ DISAS_INSN(lea) DISAS_INSN(clr) { int opsize; + TCGv zero; + + zero = tcg_const_i32(0); opsize = insn_opsize(insn); - DEST_EA(env, insn, opsize, tcg_const_i32(0), NULL); - gen_logic_cc(s, tcg_const_i32(0), opsize); + DEST_EA(env, insn, opsize, zero, NULL); + gen_logic_cc(s, zero, opsize); + tcg_temp_free(zero); } static TCGv gen_get_ccr(DisasContext *s) @@ -1735,6 +2260,8 @@ DISAS_INSN(swap) tcg_gen_shli_i32(src1, reg, 16); tcg_gen_shri_i32(src2, reg, 16); tcg_gen_or_i32(reg, src1, src2); + tcg_temp_free(src2); + tcg_temp_free(src1); gen_logic_cc(s, reg, OS_LONG); } @@ -1773,6 +2300,7 @@ DISAS_INSN(ext) else tcg_gen_mov_i32(reg, tmp); gen_logic_cc(s, tmp, OS_LONG); + tcg_temp_free(tmp); } DISAS_INSN(tst) @@ -1807,29 +2335,68 @@ DISAS_INSN(tas) gen_logic_cc(s, src1, OS_BYTE); tcg_gen_ori_i32(dest, src1, 0x80); DEST_EA(env, insn, OS_BYTE, dest, &addr); + tcg_temp_free(dest); } DISAS_INSN(mull) { uint16_t ext; - TCGv reg; TCGv src1; - TCGv dest; + int sign; - /* The upper 32 bits of the product are discarded, so - muls.l and mulu.l are functionally equivalent. */ ext = read_im16(env, s); - if (ext & 0x87ff) { - gen_exception(s, s->pc - 4, EXCP_UNSUPPORTED); + + sign = ext & 0x800; + + if (ext & 0x400) { + if (!m68k_feature(s->env, M68K_FEATURE_QUAD_MULDIV)) { + gen_exception(s, s->pc - 4, EXCP_UNSUPPORTED); + return; + } + + SRC_EA(env, src1, OS_LONG, 0, NULL); + + if (sign) { + tcg_gen_muls2_i32(QREG_CC_Z, QREG_CC_N, src1, DREG(ext, 12)); + } else { + tcg_gen_mulu2_i32(QREG_CC_Z, QREG_CC_N, src1, DREG(ext, 12)); + } + /* if Dl == Dh, 68040 returns low word */ + tcg_gen_mov_i32(DREG(ext, 0), QREG_CC_N); + tcg_gen_mov_i32(DREG(ext, 12), QREG_CC_Z); + tcg_gen_or_i32(QREG_CC_Z, QREG_CC_Z, QREG_CC_N); + + tcg_gen_movi_i32(QREG_CC_V, 0); + tcg_gen_movi_i32(QREG_CC_C, 0); + + set_cc_op(s, CC_OP_FLAGS); return; } - reg = DREG(ext, 12); SRC_EA(env, src1, OS_LONG, 0, NULL); - dest = tcg_temp_new(); - tcg_gen_mul_i32(dest, src1, reg); - tcg_gen_mov_i32(reg, dest); - /* Unlike m68k, coldfire always clears the overflow bit. */ - gen_logic_cc(s, dest, OS_LONG); + if (m68k_feature(s->env, M68K_FEATURE_M68000)) { + tcg_gen_movi_i32(QREG_CC_C, 0); + if (sign) { + tcg_gen_muls2_i32(QREG_CC_N, QREG_CC_V, src1, DREG(ext, 12)); + /* QREG_CC_V is -(QREG_CC_V != (QREG_CC_N >> 31)) */ + tcg_gen_sari_i32(QREG_CC_Z, QREG_CC_N, 31); + tcg_gen_setcond_i32(TCG_COND_NE, QREG_CC_V, QREG_CC_V, QREG_CC_Z); + } else { + tcg_gen_mulu2_i32(QREG_CC_N, QREG_CC_V, src1, DREG(ext, 12)); + /* QREG_CC_V is -(QREG_CC_V != 0), use QREG_CC_C as 0 */ + tcg_gen_setcond_i32(TCG_COND_NE, QREG_CC_V, QREG_CC_V, QREG_CC_C); + } + tcg_gen_neg_i32(QREG_CC_V, QREG_CC_V); + tcg_gen_mov_i32(DREG(ext, 12), QREG_CC_N); + + tcg_gen_mov_i32(QREG_CC_Z, QREG_CC_N); + + set_cc_op(s, CC_OP_FLAGS); + } else { + /* The upper 32 bits of the product are discarded, so + muls.l and mulu.l are functionally equivalent. */ + tcg_gen_mul_i32(DREG(ext, 12), src1, DREG(ext, 12)); + gen_logic_cc(s, DREG(ext, 12), OS_LONG); + } } static void gen_link(DisasContext *s, uint16_t insn, int32_t offset) @@ -1876,6 +2443,7 @@ DISAS_INSN(unlk) tmp = gen_load(s, OS_LONG, src, 0); tcg_gen_mov_i32(reg, tmp); tcg_gen_addi_i32(QREG_SP, src, 4); + tcg_temp_free(src); } DISAS_INSN(nop) @@ -1952,7 +2520,9 @@ DISAS_INSN(addsubq) } gen_update_cc_add(dest, val, opsize); } + tcg_temp_free(val); DEST_EA(env, insn, opsize, dest, &addr); + tcg_temp_free(dest); } DISAS_INSN(tpf) @@ -2005,11 +2575,8 @@ DISAS_INSN(branch) DISAS_INSN(moveq) { - uint32_t val; - - val = (int8_t)insn; - tcg_gen_movi_i32(DREG(insn, 9), val); - gen_logic_cc(s, tcg_const_i32(val), OS_LONG); + tcg_gen_movi_i32(DREG(insn, 9), (int8_t)insn); + gen_logic_cc(s, DREG(insn, 9), OS_LONG); } DISAS_INSN(mvzs) @@ -2049,6 +2616,7 @@ DISAS_INSN(or) gen_partset_reg(opsize, DREG(insn, 9), dest); } gen_logic_cc(s, dest, opsize); + tcg_temp_free(dest); } DISAS_INSN(suba) @@ -2143,6 +2711,7 @@ DISAS_INSN(mov3q) src = tcg_const_i32(val); gen_logic_cc(s, src, OS_LONG); DEST_EA(env, insn, OS_LONG, src, NULL); + tcg_temp_free(src); } DISAS_INSN(cmp) @@ -2173,6 +2742,21 @@ DISAS_INSN(cmpa) gen_update_cc_cmp(s, reg, src, OS_LONG); } +DISAS_INSN(cmpm) +{ + int opsize = insn_opsize(insn); + TCGv src, dst; + + /* Post-increment load (mode 3) from Ay. */ + src = gen_ea_mode(env, s, 3, REG(insn, 0), opsize, + NULL_QREG, NULL, EA_LOADS); + /* Post-increment load (mode 3) from Ax. */ + dst = gen_ea_mode(env, s, 3, REG(insn, 9), opsize, + NULL_QREG, NULL, EA_LOADS); + + gen_update_cc_cmp(s, dst, src, opsize); +} + DISAS_INSN(eor) { TCGv src; @@ -2187,6 +2771,7 @@ DISAS_INSN(eor) tcg_gen_xor_i32(dest, src, DREG(insn, 9)); gen_logic_cc(s, dest, opsize); DEST_EA(env, insn, opsize, dest, &addr); + tcg_temp_free(dest); } static void do_exg(TCGv reg1, TCGv reg2) @@ -2237,8 +2822,8 @@ DISAS_INSN(and) tcg_gen_and_i32(dest, src, reg); gen_partset_reg(opsize, reg, dest); } - tcg_temp_free(dest); gen_logic_cc(s, dest, opsize); + tcg_temp_free(dest); } DISAS_INSN(adda) @@ -2321,48 +2906,601 @@ DISAS_INSN(addx_mem) gen_store(s, opsize, addr_dest, QREG_CC_N); } -/* TODO: This could be implemented without helper functions. */ +static inline void shift_im(DisasContext *s, uint16_t insn, int opsize) +{ + int count = (insn >> 9) & 7; + int logical = insn & 8; + int left = insn & 0x100; + int bits = opsize_bytes(opsize) * 8; + TCGv reg = gen_extend(DREG(insn, 0), opsize, !logical); + + if (count == 0) { + count = 8; + } + + tcg_gen_movi_i32(QREG_CC_V, 0); + if (left) { + tcg_gen_shri_i32(QREG_CC_C, reg, bits - count); + tcg_gen_shli_i32(QREG_CC_N, reg, count); + + /* Note that ColdFire always clears V (done above), + while M68000 sets if the most significant bit is changed at + any time during the shift operation */ + if (!logical && m68k_feature(s->env, M68K_FEATURE_M68000)) { + /* if shift count >= bits, V is (reg != 0) */ + if (count >= bits) { + tcg_gen_setcond_i32(TCG_COND_NE, QREG_CC_V, reg, QREG_CC_V); + } else { + TCGv t0 = tcg_temp_new(); + tcg_gen_sari_i32(QREG_CC_V, reg, bits - 1); + tcg_gen_sari_i32(t0, reg, bits - count - 1); + tcg_gen_setcond_i32(TCG_COND_NE, QREG_CC_V, QREG_CC_V, t0); + tcg_temp_free(t0); + } + tcg_gen_neg_i32(QREG_CC_V, QREG_CC_V); + } + } else { + tcg_gen_shri_i32(QREG_CC_C, reg, count - 1); + if (logical) { + tcg_gen_shri_i32(QREG_CC_N, reg, count); + } else { + tcg_gen_sari_i32(QREG_CC_N, reg, count); + } + } + + gen_ext(QREG_CC_N, QREG_CC_N, opsize, 1); + tcg_gen_andi_i32(QREG_CC_C, QREG_CC_C, 1); + tcg_gen_mov_i32(QREG_CC_Z, QREG_CC_N); + tcg_gen_mov_i32(QREG_CC_X, QREG_CC_C); + + gen_partset_reg(opsize, DREG(insn, 0), QREG_CC_N); + set_cc_op(s, CC_OP_FLAGS); +} + +static inline void shift_reg(DisasContext *s, uint16_t insn, int opsize) +{ + int logical = insn & 8; + int left = insn & 0x100; + int bits = opsize_bytes(opsize) * 8; + TCGv reg = gen_extend(DREG(insn, 0), opsize, !logical); + TCGv s32; + TCGv_i64 t64, s64; + + t64 = tcg_temp_new_i64(); + s64 = tcg_temp_new_i64(); + s32 = tcg_temp_new(); + + /* Note that m68k truncates the shift count modulo 64, not 32. + In addition, a 64-bit shift makes it easy to find "the last + bit shifted out", for the carry flag. */ + tcg_gen_andi_i32(s32, DREG(insn, 9), 63); + tcg_gen_extu_i32_i64(s64, s32); + tcg_gen_extu_i32_i64(t64, reg); + + /* Optimistically set V=0. Also used as a zero source below. */ + tcg_gen_movi_i32(QREG_CC_V, 0); + if (left) { + tcg_gen_shl_i64(t64, t64, s64); + + if (opsize == OS_LONG) { + tcg_gen_extr_i64_i32(QREG_CC_N, QREG_CC_C, t64); + /* Note that C=0 if shift count is 0, and we get that for free. */ + } else { + TCGv zero = tcg_const_i32(0); + tcg_gen_extrl_i64_i32(QREG_CC_N, t64); + tcg_gen_shri_i32(QREG_CC_C, QREG_CC_N, bits); + tcg_gen_movcond_i32(TCG_COND_EQ, QREG_CC_C, + s32, zero, zero, QREG_CC_C); + tcg_temp_free(zero); + } + tcg_gen_andi_i32(QREG_CC_C, QREG_CC_C, 1); + + /* X = C, but only if the shift count was non-zero. */ + tcg_gen_movcond_i32(TCG_COND_NE, QREG_CC_X, s32, QREG_CC_V, + QREG_CC_C, QREG_CC_X); + + /* M68000 sets V if the most significant bit is changed at + * any time during the shift operation. Do this via creating + * an extension of the sign bit, comparing, and discarding + * the bits below the sign bit. I.e. + * int64_t s = (intN_t)reg; + * int64_t t = (int64_t)(intN_t)reg << count; + * V = ((s ^ t) & (-1 << (bits - 1))) != 0 + */ + if (!logical && m68k_feature(s->env, M68K_FEATURE_M68000)) { + TCGv_i64 tt = tcg_const_i64(32); + /* if shift is greater than 32, use 32 */ + tcg_gen_movcond_i64(TCG_COND_GT, s64, s64, tt, tt, s64); + tcg_temp_free_i64(tt); + /* Sign extend the input to 64 bits; re-do the shift. */ + tcg_gen_ext_i32_i64(t64, reg); + tcg_gen_shl_i64(s64, t64, s64); + /* Clear all bits that are unchanged. */ + tcg_gen_xor_i64(t64, t64, s64); + /* Ignore the bits below the sign bit. */ + tcg_gen_andi_i64(t64, t64, -1ULL << (bits - 1)); + /* If any bits remain set, we have overflow. */ + tcg_gen_setcondi_i64(TCG_COND_NE, t64, t64, 0); + tcg_gen_extrl_i64_i32(QREG_CC_V, t64); + tcg_gen_neg_i32(QREG_CC_V, QREG_CC_V); + } + } else { + tcg_gen_shli_i64(t64, t64, 32); + if (logical) { + tcg_gen_shr_i64(t64, t64, s64); + } else { + tcg_gen_sar_i64(t64, t64, s64); + } + tcg_gen_extr_i64_i32(QREG_CC_C, QREG_CC_N, t64); + + /* Note that C=0 if shift count is 0, and we get that for free. */ + tcg_gen_shri_i32(QREG_CC_C, QREG_CC_C, 31); + + /* X = C, but only if the shift count was non-zero. */ + tcg_gen_movcond_i32(TCG_COND_NE, QREG_CC_X, s32, QREG_CC_V, + QREG_CC_C, QREG_CC_X); + } + gen_ext(QREG_CC_N, QREG_CC_N, opsize, 1); + tcg_gen_mov_i32(QREG_CC_Z, QREG_CC_N); + + tcg_temp_free(s32); + tcg_temp_free_i64(s64); + tcg_temp_free_i64(t64); + + /* Write back the result. */ + gen_partset_reg(opsize, DREG(insn, 0), QREG_CC_N); + set_cc_op(s, CC_OP_FLAGS); +} + +DISAS_INSN(shift8_im) +{ + shift_im(s, insn, OS_BYTE); +} + +DISAS_INSN(shift16_im) +{ + shift_im(s, insn, OS_WORD); +} + DISAS_INSN(shift_im) { - TCGv reg; - int tmp; + shift_im(s, insn, OS_LONG); +} + +DISAS_INSN(shift8_reg) +{ + shift_reg(s, insn, OS_BYTE); +} + +DISAS_INSN(shift16_reg) +{ + shift_reg(s, insn, OS_WORD); +} + +DISAS_INSN(shift_reg) +{ + shift_reg(s, insn, OS_LONG); +} + +DISAS_INSN(shift_mem) +{ + int logical = insn & 8; + int left = insn & 0x100; + TCGv src; + TCGv addr; + + SRC_EA(env, src, OS_WORD, !logical, &addr); + tcg_gen_movi_i32(QREG_CC_V, 0); + if (left) { + tcg_gen_shri_i32(QREG_CC_C, src, 15); + tcg_gen_shli_i32(QREG_CC_N, src, 1); + + /* Note that ColdFire always clears V, + while M68000 sets if the most significant bit is changed at + any time during the shift operation */ + if (!logical && m68k_feature(s->env, M68K_FEATURE_M68000)) { + src = gen_extend(src, OS_WORD, 1); + tcg_gen_xor_i32(QREG_CC_V, QREG_CC_N, src); + } + } else { + tcg_gen_mov_i32(QREG_CC_C, src); + if (logical) { + tcg_gen_shri_i32(QREG_CC_N, src, 1); + } else { + tcg_gen_sari_i32(QREG_CC_N, src, 1); + } + } + + gen_ext(QREG_CC_N, QREG_CC_N, OS_WORD, 1); + tcg_gen_andi_i32(QREG_CC_C, QREG_CC_C, 1); + tcg_gen_mov_i32(QREG_CC_Z, QREG_CC_N); + tcg_gen_mov_i32(QREG_CC_X, QREG_CC_C); + + DEST_EA(env, insn, OS_WORD, QREG_CC_N, &addr); + set_cc_op(s, CC_OP_FLAGS); +} + +static void rotate(TCGv reg, TCGv shift, int left, int size) +{ + switch (size) { + case 8: + /* Replicate the 8-bit input so that a 32-bit rotate works. */ + tcg_gen_ext8u_i32(reg, reg); + tcg_gen_muli_i32(reg, reg, 0x01010101); + goto do_long; + case 16: + /* Replicate the 16-bit input so that a 32-bit rotate works. */ + tcg_gen_deposit_i32(reg, reg, reg, 16, 16); + goto do_long; + do_long: + default: + if (left) { + tcg_gen_rotl_i32(reg, reg, shift); + } else { + tcg_gen_rotr_i32(reg, reg, shift); + } + } + + /* compute flags */ + + switch (size) { + case 8: + tcg_gen_ext8s_i32(reg, reg); + break; + case 16: + tcg_gen_ext16s_i32(reg, reg); + break; + default: + break; + } + + /* QREG_CC_X is not affected */ + + tcg_gen_mov_i32(QREG_CC_N, reg); + tcg_gen_mov_i32(QREG_CC_Z, reg); + + if (left) { + tcg_gen_andi_i32(QREG_CC_C, reg, 1); + } else { + tcg_gen_shri_i32(QREG_CC_C, reg, 31); + } + + tcg_gen_movi_i32(QREG_CC_V, 0); /* always cleared */ +} + +static void rotate_x_flags(TCGv reg, TCGv X, int size) +{ + switch (size) { + case 8: + tcg_gen_ext8s_i32(reg, reg); + break; + case 16: + tcg_gen_ext16s_i32(reg, reg); + break; + default: + break; + } + tcg_gen_mov_i32(QREG_CC_N, reg); + tcg_gen_mov_i32(QREG_CC_Z, reg); + tcg_gen_mov_i32(QREG_CC_X, X); + tcg_gen_mov_i32(QREG_CC_C, X); + tcg_gen_movi_i32(QREG_CC_V, 0); +} + +/* Result of rotate_x() is valid if 0 <= shift <= size */ +static TCGv rotate_x(TCGv reg, TCGv shift, int left, int size) +{ + TCGv X, shl, shr, shx, sz, zero; + + sz = tcg_const_i32(size); + + shr = tcg_temp_new(); + shl = tcg_temp_new(); + shx = tcg_temp_new(); + if (left) { + tcg_gen_mov_i32(shl, shift); /* shl = shift */ + tcg_gen_movi_i32(shr, size + 1); + tcg_gen_sub_i32(shr, shr, shift); /* shr = size + 1 - shift */ + tcg_gen_subi_i32(shx, shift, 1); /* shx = shift - 1 */ + /* shx = shx < 0 ? size : shx; */ + zero = tcg_const_i32(0); + tcg_gen_movcond_i32(TCG_COND_LT, shx, shx, zero, sz, shx); + tcg_temp_free(zero); + } else { + tcg_gen_mov_i32(shr, shift); /* shr = shift */ + tcg_gen_movi_i32(shl, size + 1); + tcg_gen_sub_i32(shl, shl, shift); /* shl = size + 1 - shift */ + tcg_gen_sub_i32(shx, sz, shift); /* shx = size - shift */ + } + + /* reg = (reg << shl) | (reg >> shr) | (x << shx); */ + + tcg_gen_shl_i32(shl, reg, shl); + tcg_gen_shr_i32(shr, reg, shr); + tcg_gen_or_i32(reg, shl, shr); + tcg_temp_free(shl); + tcg_temp_free(shr); + tcg_gen_shl_i32(shx, QREG_CC_X, shx); + tcg_gen_or_i32(reg, reg, shx); + tcg_temp_free(shx); + + /* X = (reg >> size) & 1 */ + + X = tcg_temp_new(); + tcg_gen_shr_i32(X, reg, sz); + tcg_gen_andi_i32(X, X, 1); + tcg_temp_free(sz); + + return X; +} + +/* Result of rotate32_x() is valid if 0 <= shift < 33 */ +static TCGv rotate32_x(TCGv reg, TCGv shift, int left) +{ + TCGv_i64 t0, shift64; + TCGv X, lo, hi, zero; + + shift64 = tcg_temp_new_i64(); + tcg_gen_extu_i32_i64(shift64, shift); + + t0 = tcg_temp_new_i64(); + + X = tcg_temp_new(); + lo = tcg_temp_new(); + hi = tcg_temp_new(); + + if (left) { + /* create [reg:X:..] */ + + tcg_gen_shli_i32(lo, QREG_CC_X, 31); + tcg_gen_concat_i32_i64(t0, lo, reg); + + /* rotate */ + + tcg_gen_rotl_i64(t0, t0, shift64); + tcg_temp_free_i64(shift64); + + /* result is [reg:..:reg:X] */ + + tcg_gen_extr_i64_i32(lo, hi, t0); + tcg_gen_andi_i32(X, lo, 1); + + tcg_gen_shri_i32(lo, lo, 1); + } else { + /* create [..:X:reg] */ + + tcg_gen_concat_i32_i64(t0, reg, QREG_CC_X); + + tcg_gen_rotr_i64(t0, t0, shift64); + tcg_temp_free_i64(shift64); + + /* result is value: [X:reg:..:reg] */ + + tcg_gen_extr_i64_i32(lo, hi, t0); + + /* extract X */ + + tcg_gen_shri_i32(X, hi, 31); + + /* extract result */ + + tcg_gen_shli_i32(hi, hi, 1); + } + tcg_temp_free_i64(t0); + tcg_gen_or_i32(lo, lo, hi); + tcg_temp_free(hi); + + /* if shift == 0, register and X are not affected */ + + zero = tcg_const_i32(0); + tcg_gen_movcond_i32(TCG_COND_EQ, X, shift, zero, QREG_CC_X, X); + tcg_gen_movcond_i32(TCG_COND_EQ, reg, shift, zero, reg, lo); + tcg_temp_free(zero); + tcg_temp_free(lo); + + return X; +} + +DISAS_INSN(rotate_im) +{ TCGv shift; + int tmp; + int left = (insn & 0x100); + + tmp = (insn >> 9) & 7; + if (tmp == 0) { + tmp = 8; + } + + shift = tcg_const_i32(tmp); + if (insn & 8) { + rotate(DREG(insn, 0), shift, left, 32); + } else { + TCGv X = rotate32_x(DREG(insn, 0), shift, left); + rotate_x_flags(DREG(insn, 0), X, 32); + tcg_temp_free(X); + } + tcg_temp_free(shift); set_cc_op(s, CC_OP_FLAGS); +} + +DISAS_INSN(rotate8_im) +{ + int left = (insn & 0x100); + TCGv reg; + TCGv shift; + int tmp; + + reg = gen_extend(DREG(insn, 0), OS_BYTE, 0); - reg = DREG(insn, 0); tmp = (insn >> 9) & 7; - if (tmp == 0) + if (tmp == 0) { tmp = 8; + } + shift = tcg_const_i32(tmp); - /* No need to flush flags becuse we know we will set C flag. */ - if (insn & 0x100) { - gen_helper_shl_cc(reg, cpu_env, reg, shift); + if (insn & 8) { + rotate(reg, shift, left, 8); } else { - if (insn & 8) { - gen_helper_shr_cc(reg, cpu_env, reg, shift); - } else { - gen_helper_sar_cc(reg, cpu_env, reg, shift); - } + TCGv X = rotate_x(reg, shift, left, 8); + rotate_x_flags(reg, X, 8); + tcg_temp_free(X); } + tcg_temp_free(shift); + gen_partset_reg(OS_BYTE, DREG(insn, 0), reg); + set_cc_op(s, CC_OP_FLAGS); } -DISAS_INSN(shift_reg) +DISAS_INSN(rotate16_im) { + int left = (insn & 0x100); TCGv reg; TCGv shift; + int tmp; + + reg = gen_extend(DREG(insn, 0), OS_WORD, 0); + tmp = (insn >> 9) & 7; + if (tmp == 0) { + tmp = 8; + } + + shift = tcg_const_i32(tmp); + if (insn & 8) { + rotate(reg, shift, left, 16); + } else { + TCGv X = rotate_x(reg, shift, left, 16); + rotate_x_flags(reg, X, 16); + tcg_temp_free(X); + } + tcg_temp_free(shift); + gen_partset_reg(OS_WORD, DREG(insn, 0), reg); + set_cc_op(s, CC_OP_FLAGS); +} + +DISAS_INSN(rotate_reg) +{ + TCGv reg; + TCGv src; + TCGv t0, t1; + int left = (insn & 0x100); reg = DREG(insn, 0); - shift = DREG(insn, 9); - if (insn & 0x100) { - gen_helper_shl_cc(reg, cpu_env, reg, shift); + src = DREG(insn, 9); + /* shift in [0..63] */ + t0 = tcg_temp_new(); + tcg_gen_andi_i32(t0, src, 63); + t1 = tcg_temp_new_i32(); + if (insn & 8) { + tcg_gen_andi_i32(t1, src, 31); + rotate(reg, t1, left, 32); + /* if shift == 0, clear C */ + tcg_gen_movcond_i32(TCG_COND_EQ, QREG_CC_C, + t0, QREG_CC_V /* 0 */, + QREG_CC_V /* 0 */, QREG_CC_C); } else { - if (insn & 8) { - gen_helper_shr_cc(reg, cpu_env, reg, shift); - } else { - gen_helper_sar_cc(reg, cpu_env, reg, shift); - } + TCGv X; + /* modulo 33 */ + tcg_gen_movi_i32(t1, 33); + tcg_gen_remu_i32(t1, t0, t1); + X = rotate32_x(DREG(insn, 0), t1, left); + rotate_x_flags(DREG(insn, 0), X, 32); + tcg_temp_free(X); + } + tcg_temp_free(t1); + tcg_temp_free(t0); + set_cc_op(s, CC_OP_FLAGS); +} + +DISAS_INSN(rotate8_reg) +{ + TCGv reg; + TCGv src; + TCGv t0, t1; + int left = (insn & 0x100); + + reg = gen_extend(DREG(insn, 0), OS_BYTE, 0); + src = DREG(insn, 9); + /* shift in [0..63] */ + t0 = tcg_temp_new_i32(); + tcg_gen_andi_i32(t0, src, 63); + t1 = tcg_temp_new_i32(); + if (insn & 8) { + tcg_gen_andi_i32(t1, src, 7); + rotate(reg, t1, left, 8); + /* if shift == 0, clear C */ + tcg_gen_movcond_i32(TCG_COND_EQ, QREG_CC_C, + t0, QREG_CC_V /* 0 */, + QREG_CC_V /* 0 */, QREG_CC_C); + } else { + TCGv X; + /* modulo 9 */ + tcg_gen_movi_i32(t1, 9); + tcg_gen_remu_i32(t1, t0, t1); + X = rotate_x(reg, t1, left, 8); + rotate_x_flags(reg, X, 8); + tcg_temp_free(X); + } + tcg_temp_free(t1); + tcg_temp_free(t0); + gen_partset_reg(OS_BYTE, DREG(insn, 0), reg); + set_cc_op(s, CC_OP_FLAGS); +} + +DISAS_INSN(rotate16_reg) +{ + TCGv reg; + TCGv src; + TCGv t0, t1; + int left = (insn & 0x100); + + reg = gen_extend(DREG(insn, 0), OS_WORD, 0); + src = DREG(insn, 9); + /* shift in [0..63] */ + t0 = tcg_temp_new_i32(); + tcg_gen_andi_i32(t0, src, 63); + t1 = tcg_temp_new_i32(); + if (insn & 8) { + tcg_gen_andi_i32(t1, src, 15); + rotate(reg, t1, left, 16); + /* if shift == 0, clear C */ + tcg_gen_movcond_i32(TCG_COND_EQ, QREG_CC_C, + t0, QREG_CC_V /* 0 */, + QREG_CC_V /* 0 */, QREG_CC_C); + } else { + TCGv X; + /* modulo 17 */ + tcg_gen_movi_i32(t1, 17); + tcg_gen_remu_i32(t1, t0, t1); + X = rotate_x(reg, t1, left, 16); + rotate_x_flags(reg, X, 16); + tcg_temp_free(X); + } + tcg_temp_free(t1); + tcg_temp_free(t0); + gen_partset_reg(OS_WORD, DREG(insn, 0), reg); + set_cc_op(s, CC_OP_FLAGS); +} + +DISAS_INSN(rotate_mem) +{ + TCGv src; + TCGv addr; + TCGv shift; + int left = (insn & 0x100); + + SRC_EA(env, src, OS_WORD, 0, &addr); + + shift = tcg_const_i32(1); + if (insn & 0x0200) { + rotate(src, shift, left, 16); + } else { + TCGv X = rotate_x(src, shift, left, 16); + rotate_x_flags(src, X, 16); + tcg_temp_free(X); } + tcg_temp_free(shift); + DEST_EA(env, insn, OS_WORD, src, &addr); set_cc_op(s, CC_OP_FLAGS); } @@ -3312,6 +4450,11 @@ void register_m68k_insns (CPUM68KState *env) BASE(bitop_im, 08c0, ffc0); INSN(arith_im, 0a80, fff8, CF_ISA_A); INSN(arith_im, 0a00, ff00, M68000); + INSN(cas, 0ac0, ffc0, CAS); + INSN(cas, 0cc0, ffc0, CAS); + INSN(cas, 0ec0, ffc0, CAS); + INSN(cas2w, 0cfc, ffff, CAS); + INSN(cas2l, 0efc, ffff, CAS); BASE(move, 1000, f000); BASE(move, 2000, f000); BASE(move, 3000, f000); @@ -3334,11 +4477,14 @@ void register_m68k_insns (CPUM68KState *env) INSN(not, 4600, ff00, M68000); INSN(undef, 46c0, ffc0, M68000); INSN(move_to_sr, 46c0, ffc0, CF_ISA_A); + INSN(nbcd, 4800, ffc0, M68000); INSN(linkl, 4808, fff8, M68000); BASE(pea, 4840, ffc0); BASE(swap, 4840, fff8); INSN(bkpt, 4848, fff8, BKPT); - BASE(movem, 48c0, fbc0); + INSN(movem, 48d0, fbf8, CF_ISA_A); + INSN(movem, 48e8, fbf8, CF_ISA_A); + INSN(movem, 4880, fb80, M68000); BASE(ext, 4880, fff8); BASE(ext, 48c0, fff8); BASE(ext, 49c0, fff8); @@ -3385,6 +4531,8 @@ void register_m68k_insns (CPUM68KState *env) INSN(mvzs, 7100, f100, CF_ISA_B); BASE(or, 8000, f000); BASE(divw, 80c0, f0c0); + INSN(sbcd_reg, 8100, f1f8, M68000); + INSN(sbcd_mem, 8108, f1f8, M68000); BASE(addsub, 9000, f000); INSN(undef, 90c0, f0c0, CF_ISA_A); INSN(subx_reg, 9180, f1f8, CF_ISA_A); @@ -3414,6 +4562,7 @@ void register_m68k_insns (CPUM68KState *env) INSN(cmpa, b1c0, f1c0, CF_ISA_A); INSN(cmp, b000, f100, M68000); INSN(eor, b100, f100, M68000); + INSN(cmpm, b108, f138, M68000); INSN(cmpa, b0c0, f0c0, M68000); INSN(eor, b180, f1c0, CF_ISA_A); BASE(and, c000, f000); @@ -3421,6 +4570,8 @@ void register_m68k_insns (CPUM68KState *env) INSN(exg_aa, c148, f1f8, M68000); INSN(exg_da, c188, f1f8, M68000); BASE(mulw, c0c0, f0c0); + INSN(abcd_reg, c100, f1f8, M68000); + INSN(abcd_mem, c108, f1f8, M68000); BASE(addsub, d000, f000); INSN(undef, d0c0, f0c0, CF_ISA_A); INSN(addx_reg, d180, f1f8, CF_ISA_A); @@ -3430,6 +4581,20 @@ void register_m68k_insns (CPUM68KState *env) INSN(adda, d0c0, f0c0, M68000); INSN(shift_im, e080, f0f0, CF_ISA_A); INSN(shift_reg, e0a0, f0f0, CF_ISA_A); + INSN(shift8_im, e000, f0f0, M68000); + INSN(shift16_im, e040, f0f0, M68000); + INSN(shift_im, e080, f0f0, M68000); + INSN(shift8_reg, e020, f0f0, M68000); + INSN(shift16_reg, e060, f0f0, M68000); + INSN(shift_reg, e0a0, f0f0, M68000); + INSN(shift_mem, e0c0, fcc0, M68000); + INSN(rotate_im, e090, f0f0, M68000); + INSN(rotate8_im, e010, f0f0, M68000); + INSN(rotate16_im, e050, f0f0, M68000); + INSN(rotate_reg, e0b0, f0f0, M68000); + INSN(rotate8_reg, e030, f0f0, M68000); + INSN(rotate16_reg, e070, f0f0, M68000); + INSN(rotate_mem, e4c0, fcc0, M68000); INSN(undef_fpu, f000, f000, CF_ISA_A); INSN(fpu, f200, ffc0, CF_FPU); INSN(fbcc, f280, ffc0, CF_FPU); @@ -3446,11 +4611,9 @@ void register_m68k_insns (CPUM68KState *env) write back the result to memory before setting the condition codes. */ static void disas_m68k_insn(CPUM68KState * env, DisasContext *s) { - uint16_t insn; - - insn = read_im16(env, s); - + uint16_t insn = read_im16(env, s); opcode_table[insn](env, s, insn); + do_writebacks(s); } /* generate intermediate code for basic block 'tb'. */ @@ -3478,6 +4641,7 @@ void gen_intermediate_code(CPUM68KState *env, TranslationBlock *tb) dc->fpcr = env->fpcr; dc->user = (env->sr & SR_S) == 0; dc->done_mac = 0; + dc->writeback_mask = 0; num_insns = 0; max_insns = tb->cflags & CF_COUNT_MASK; if (max_insns == 0) { diff --git a/target-microblaze/Makefile.objs b/target/microblaze/Makefile.objs index f3d7b44c89..f3d7b44c89 100644 --- a/target-microblaze/Makefile.objs +++ b/target/microblaze/Makefile.objs diff --git a/target-microblaze/cpu-qom.h b/target/microblaze/cpu-qom.h index 1a61db77d0..1a61db77d0 100644 --- a/target-microblaze/cpu-qom.h +++ b/target/microblaze/cpu-qom.h diff --git a/target-microblaze/cpu.c b/target/microblaze/cpu.c index 389c7b691e..389c7b691e 100644 --- a/target-microblaze/cpu.c +++ b/target/microblaze/cpu.c diff --git a/target-microblaze/cpu.h b/target/microblaze/cpu.h index beb75ffd26..beb75ffd26 100644 --- a/target-microblaze/cpu.h +++ b/target/microblaze/cpu.h diff --git a/target-microblaze/gdbstub.c b/target/microblaze/gdbstub.c index 7fb076c2e9..7fb076c2e9 100644 --- a/target-microblaze/gdbstub.c +++ b/target/microblaze/gdbstub.c diff --git a/target-microblaze/helper.c b/target/microblaze/helper.c index da394d1dfc..da394d1dfc 100644 --- a/target-microblaze/helper.c +++ b/target/microblaze/helper.c diff --git a/target-microblaze/helper.h b/target/microblaze/helper.h index bd13826de0..bd13826de0 100644 --- a/target-microblaze/helper.h +++ b/target/microblaze/helper.h diff --git a/target-microblaze/microblaze-decode.h b/target/microblaze/microblaze-decode.h index 401319ed46..401319ed46 100644 --- a/target-microblaze/microblaze-decode.h +++ b/target/microblaze/microblaze-decode.h diff --git a/target-microblaze/mmu.c b/target/microblaze/mmu.c index a22a496ebb..a22a496ebb 100644 --- a/target-microblaze/mmu.c +++ b/target/microblaze/mmu.c diff --git a/target-microblaze/mmu.h b/target/microblaze/mmu.h index 3b7a9983d5..3b7a9983d5 100644 --- a/target-microblaze/mmu.h +++ b/target/microblaze/mmu.h diff --git a/target-microblaze/op_helper.c b/target/microblaze/op_helper.c index 4a856e6204..4a856e6204 100644 --- a/target-microblaze/op_helper.c +++ b/target/microblaze/op_helper.c diff --git a/target-microblaze/translate.c b/target/microblaze/translate.c index de2090ac71..de2090ac71 100644 --- a/target-microblaze/translate.c +++ b/target/microblaze/translate.c diff --git a/target-mips/Makefile.objs b/target/mips/Makefile.objs index bc5ed8511f..bc5ed8511f 100644 --- a/target-mips/Makefile.objs +++ b/target/mips/Makefile.objs diff --git a/target-mips/TODO b/target/mips/TODO index 1d782d8027..1d782d8027 100644 --- a/target-mips/TODO +++ b/target/mips/TODO diff --git a/target-mips/cpu-qom.h b/target/mips/cpu-qom.h index 3f5bf23823..3f5bf23823 100644 --- a/target-mips/cpu-qom.h +++ b/target/mips/cpu-qom.h diff --git a/target-mips/cpu.c b/target/mips/cpu.c index 65ca607f88..65ca607f88 100644 --- a/target-mips/cpu.c +++ b/target/mips/cpu.c diff --git a/target-mips/cpu.h b/target/mips/cpu.h index 5182dc74ff..5182dc74ff 100644 --- a/target-mips/cpu.h +++ b/target/mips/cpu.h diff --git a/target-mips/dsp_helper.c b/target/mips/dsp_helper.c index dc707934ea..dc707934ea 100644 --- a/target-mips/dsp_helper.c +++ b/target/mips/dsp_helper.c diff --git a/target-mips/gdbstub.c b/target/mips/gdbstub.c index 7c682289c2..7c682289c2 100644 --- a/target-mips/gdbstub.c +++ b/target/mips/gdbstub.c diff --git a/target-mips/helper.c b/target/mips/helper.c index c864b15b97..c864b15b97 100644 --- a/target-mips/helper.c +++ b/target/mips/helper.c diff --git a/target-mips/helper.h b/target/mips/helper.h index 666936c81b..666936c81b 100644 --- a/target-mips/helper.h +++ b/target/mips/helper.h diff --git a/target-mips/kvm.c b/target/mips/kvm.c index dcf5fbba0c..dcf5fbba0c 100644 --- a/target-mips/kvm.c +++ b/target/mips/kvm.c diff --git a/target-mips/kvm_mips.h b/target/mips/kvm_mips.h index ae957f37f0..ae957f37f0 100644 --- a/target-mips/kvm_mips.h +++ b/target/mips/kvm_mips.h diff --git a/target-mips/lmi_helper.c b/target/mips/lmi_helper.c index fb1245b39d..fb1245b39d 100644 --- a/target-mips/lmi_helper.c +++ b/target/mips/lmi_helper.c diff --git a/target-mips/machine.c b/target/mips/machine.c index d20d948457..d20d948457 100644 --- a/target-mips/machine.c +++ b/target/mips/machine.c diff --git a/target-mips/mips-defs.h b/target/mips/mips-defs.h index 047554ee45..047554ee45 100644 --- a/target-mips/mips-defs.h +++ b/target/mips/mips-defs.h diff --git a/target-mips/mips-semi.c b/target/mips/mips-semi.c index a7aefbaefc..a7aefbaefc 100644 --- a/target-mips/mips-semi.c +++ b/target/mips/mips-semi.c diff --git a/target-mips/msa_helper.c b/target/mips/msa_helper.c index 1fdb0d9792..1fdb0d9792 100644 --- a/target-mips/msa_helper.c +++ b/target/mips/msa_helper.c diff --git a/target-mips/op_helper.c b/target/mips/op_helper.c index 7af4c2f084..7af4c2f084 100644 --- a/target-mips/op_helper.c +++ b/target/mips/op_helper.c diff --git a/target-mips/translate.c b/target/mips/translate.c index 57b824ff2d..57b824ff2d 100644 --- a/target-mips/translate.c +++ b/target/mips/translate.c diff --git a/target-mips/translate_init.c b/target/mips/translate_init.c index 6ae23e476f..6ae23e476f 100644 --- a/target-mips/translate_init.c +++ b/target/mips/translate_init.c diff --git a/target-moxie/Makefile.objs b/target/moxie/Makefile.objs index 6381d4d636..6381d4d636 100644 --- a/target-moxie/Makefile.objs +++ b/target/moxie/Makefile.objs diff --git a/target-moxie/cpu.c b/target/moxie/cpu.c index b0be4a7551..b0be4a7551 100644 --- a/target-moxie/cpu.c +++ b/target/moxie/cpu.c diff --git a/target-moxie/cpu.h b/target/moxie/cpu.h index 3e880facf4..3e880facf4 100644 --- a/target-moxie/cpu.h +++ b/target/moxie/cpu.h diff --git a/target-moxie/helper.c b/target/moxie/helper.c index 330299f5a7..330299f5a7 100644 --- a/target-moxie/helper.c +++ b/target/moxie/helper.c diff --git a/target-moxie/helper.h b/target/moxie/helper.h index d94ef7a17e..d94ef7a17e 100644 --- a/target-moxie/helper.h +++ b/target/moxie/helper.h diff --git a/target-moxie/machine.c b/target/moxie/machine.c index 282dcd869f..282dcd869f 100644 --- a/target-moxie/machine.c +++ b/target/moxie/machine.c diff --git a/target-moxie/machine.h b/target/moxie/machine.h index a1b72907ae..a1b72907ae 100644 --- a/target-moxie/machine.h +++ b/target/moxie/machine.h diff --git a/target-moxie/mmu.c b/target/moxie/mmu.c index 9203330b3b..9203330b3b 100644 --- a/target-moxie/mmu.c +++ b/target/moxie/mmu.c diff --git a/target-moxie/mmu.h b/target/moxie/mmu.h index 284a44d18e..284a44d18e 100644 --- a/target-moxie/mmu.h +++ b/target/moxie/mmu.h diff --git a/target-moxie/translate.c b/target/moxie/translate.c index 0660b44c08..0660b44c08 100644 --- a/target-moxie/translate.c +++ b/target/moxie/translate.c diff --git a/target-openrisc/Makefile.objs b/target/openrisc/Makefile.objs index 397d01650e..397d01650e 100644 --- a/target-openrisc/Makefile.objs +++ b/target/openrisc/Makefile.objs diff --git a/target-openrisc/cpu.c b/target/openrisc/cpu.c index 698e87bb25..698e87bb25 100644 --- a/target-openrisc/cpu.c +++ b/target/openrisc/cpu.c diff --git a/target-openrisc/cpu.h b/target/openrisc/cpu.h index aaf153579a..aaf153579a 100644 --- a/target-openrisc/cpu.h +++ b/target/openrisc/cpu.h diff --git a/target-openrisc/exception.c b/target/openrisc/exception.c index 49470be051..49470be051 100644 --- a/target-openrisc/exception.c +++ b/target/openrisc/exception.c diff --git a/target-openrisc/exception.h b/target/openrisc/exception.h index 4ec56b4653..4ec56b4653 100644 --- a/target-openrisc/exception.h +++ b/target/openrisc/exception.h diff --git a/target-openrisc/exception_helper.c b/target/openrisc/exception_helper.c index 329a9e400b..329a9e400b 100644 --- a/target-openrisc/exception_helper.c +++ b/target/openrisc/exception_helper.c diff --git a/target-openrisc/fpu_helper.c b/target/openrisc/fpu_helper.c index c54404b80d..c54404b80d 100644 --- a/target-openrisc/fpu_helper.c +++ b/target/openrisc/fpu_helper.c diff --git a/target-openrisc/gdbstub.c b/target/openrisc/gdbstub.c index cb16e76358..cb16e76358 100644 --- a/target-openrisc/gdbstub.c +++ b/target/openrisc/gdbstub.c diff --git a/target-openrisc/helper.h b/target/openrisc/helper.h index f53fa21344..f53fa21344 100644 --- a/target-openrisc/helper.h +++ b/target/openrisc/helper.h diff --git a/target-openrisc/int_helper.c b/target/openrisc/int_helper.c index 4d1f958901..4d1f958901 100644 --- a/target-openrisc/int_helper.c +++ b/target/openrisc/int_helper.c diff --git a/target-openrisc/interrupt.c b/target/openrisc/interrupt.c index 5fe3f11ffc..5fe3f11ffc 100644 --- a/target-openrisc/interrupt.c +++ b/target/openrisc/interrupt.c diff --git a/target-openrisc/interrupt_helper.c b/target/openrisc/interrupt_helper.c index 116f9109a7..116f9109a7 100644 --- a/target-openrisc/interrupt_helper.c +++ b/target/openrisc/interrupt_helper.c diff --git a/target-openrisc/machine.c b/target/openrisc/machine.c index 17b0c77d6c..17b0c77d6c 100644 --- a/target-openrisc/machine.c +++ b/target/openrisc/machine.c diff --git a/target-openrisc/mmu.c b/target/openrisc/mmu.c index 505dcdcdc8..505dcdcdc8 100644 --- a/target-openrisc/mmu.c +++ b/target/openrisc/mmu.c diff --git a/target-openrisc/mmu_helper.c b/target/openrisc/mmu_helper.c index a44d0aa51a..a44d0aa51a 100644 --- a/target-openrisc/mmu_helper.c +++ b/target/openrisc/mmu_helper.c diff --git a/target-openrisc/sys_helper.c b/target/openrisc/sys_helper.c index a719e452be..a719e452be 100644 --- a/target-openrisc/sys_helper.c +++ b/target/openrisc/sys_helper.c diff --git a/target-openrisc/translate.c b/target/openrisc/translate.c index 229361aed1..229361aed1 100644 --- a/target-openrisc/translate.c +++ b/target/openrisc/translate.c diff --git a/target-ppc/Makefile.objs b/target/ppc/Makefile.objs index e667e69701..e667e69701 100644 --- a/target-ppc/Makefile.objs +++ b/target/ppc/Makefile.objs diff --git a/target-ppc/STATUS b/target/ppc/STATUS index a4d48a7ca2..a4d48a7ca2 100644 --- a/target-ppc/STATUS +++ b/target/ppc/STATUS diff --git a/target-ppc/arch_dump.c b/target/ppc/arch_dump.c index 40282a1f50..40282a1f50 100644 --- a/target-ppc/arch_dump.c +++ b/target/ppc/arch_dump.c diff --git a/target-ppc/cpu-models.c b/target/ppc/cpu-models.c index 506dee1ee8..506dee1ee8 100644 --- a/target-ppc/cpu-models.c +++ b/target/ppc/cpu-models.c diff --git a/target-ppc/cpu-models.h b/target/ppc/cpu-models.h index aafbbd7d5d..aafbbd7d5d 100644 --- a/target-ppc/cpu-models.h +++ b/target/ppc/cpu-models.h diff --git a/target-ppc/cpu-qom.h b/target/ppc/cpu-qom.h index d46c31a15d..d46c31a15d 100644 --- a/target-ppc/cpu-qom.h +++ b/target/ppc/cpu-qom.h diff --git a/target-ppc/cpu.h b/target/ppc/cpu.h index 2a50c43689..2a50c43689 100644 --- a/target-ppc/cpu.h +++ b/target/ppc/cpu.h diff --git a/target-ppc/dfp_helper.c b/target/ppc/dfp_helper.c index 9164fe701b..9164fe701b 100644 --- a/target-ppc/dfp_helper.c +++ b/target/ppc/dfp_helper.c diff --git a/target-ppc/excp_helper.c b/target/ppc/excp_helper.c index 93369d4fe5..93369d4fe5 100644 --- a/target-ppc/excp_helper.c +++ b/target/ppc/excp_helper.c diff --git a/target-ppc/fpu_helper.c b/target/ppc/fpu_helper.c index 8a389e19af..8a389e19af 100644 --- a/target-ppc/fpu_helper.c +++ b/target/ppc/fpu_helper.c diff --git a/target-ppc/gdbstub.c b/target/ppc/gdbstub.c index 7a338136a8..7a338136a8 100644 --- a/target-ppc/gdbstub.c +++ b/target/ppc/gdbstub.c diff --git a/target-ppc/helper.h b/target/ppc/helper.h index da00f0ab49..da00f0ab49 100644 --- a/target-ppc/helper.h +++ b/target/ppc/helper.h diff --git a/target-ppc/helper_regs.h b/target/ppc/helper_regs.h index 62138163a5..62138163a5 100644 --- a/target-ppc/helper_regs.h +++ b/target/ppc/helper_regs.h diff --git a/target-ppc/int_helper.c b/target/ppc/int_helper.c index 2d57c9a1c2..2d57c9a1c2 100644 --- a/target-ppc/int_helper.c +++ b/target/ppc/int_helper.c diff --git a/target-ppc/internal.h b/target/ppc/internal.h index 1ff4896c45..1ff4896c45 100644 --- a/target-ppc/internal.h +++ b/target/ppc/internal.h diff --git a/target-ppc/kvm-stub.c b/target/ppc/kvm-stub.c index efeafca1df..efeafca1df 100644 --- a/target-ppc/kvm-stub.c +++ b/target/ppc/kvm-stub.c diff --git a/target-ppc/kvm.c b/target/ppc/kvm.c index 9c4834c4fc..9c4834c4fc 100644 --- a/target-ppc/kvm.c +++ b/target/ppc/kvm.c diff --git a/target-ppc/kvm_ppc.h b/target/ppc/kvm_ppc.h index bd1d78bfbe..bd1d78bfbe 100644 --- a/target-ppc/kvm_ppc.h +++ b/target/ppc/kvm_ppc.h diff --git a/target-ppc/machine.c b/target/ppc/machine.c index 18c16d2512..18c16d2512 100644 --- a/target-ppc/machine.c +++ b/target/ppc/machine.c diff --git a/target-ppc/mem_helper.c b/target/ppc/mem_helper.c index 1ab8a6eab4..1ab8a6eab4 100644 --- a/target-ppc/mem_helper.c +++ b/target/ppc/mem_helper.c diff --git a/target-ppc/mfrom_table.c b/target/ppc/mfrom_table.c index 6a1fa375c9..6a1fa375c9 100644 --- a/target-ppc/mfrom_table.c +++ b/target/ppc/mfrom_table.c diff --git a/target-ppc/mfrom_table_gen.c b/target/ppc/mfrom_table_gen.c index 631791808e..631791808e 100644 --- a/target-ppc/mfrom_table_gen.c +++ b/target/ppc/mfrom_table_gen.c diff --git a/target-ppc/misc_helper.c b/target/ppc/misc_helper.c index 1e6e705a4e..1e6e705a4e 100644 --- a/target-ppc/misc_helper.c +++ b/target/ppc/misc_helper.c diff --git a/target-ppc/mmu-hash32.c b/target/ppc/mmu-hash32.c index 29bace622a..29bace622a 100644 --- a/target-ppc/mmu-hash32.c +++ b/target/ppc/mmu-hash32.c diff --git a/target-ppc/mmu-hash32.h b/target/ppc/mmu-hash32.h index 5b9fb08d1a..5b9fb08d1a 100644 --- a/target-ppc/mmu-hash32.h +++ b/target/ppc/mmu-hash32.h diff --git a/target-ppc/mmu-hash64.c b/target/ppc/mmu-hash64.c index fdb7a787bf..fdb7a787bf 100644 --- a/target-ppc/mmu-hash64.c +++ b/target/ppc/mmu-hash64.c diff --git a/target-ppc/mmu-hash64.h b/target/ppc/mmu-hash64.h index ab5d347a53..ab5d347a53 100644 --- a/target-ppc/mmu-hash64.h +++ b/target/ppc/mmu-hash64.h diff --git a/target-ppc/mmu_helper.c b/target/ppc/mmu_helper.c index d09fc0a85f..d09fc0a85f 100644 --- a/target-ppc/mmu_helper.c +++ b/target/ppc/mmu_helper.c diff --git a/target-ppc/monitor.c b/target/ppc/monitor.c index c2d0806dd1..c2d0806dd1 100644 --- a/target-ppc/monitor.c +++ b/target/ppc/monitor.c diff --git a/target-ppc/timebase_helper.c b/target/ppc/timebase_helper.c index 73363e08ae..73363e08ae 100644 --- a/target-ppc/timebase_helper.c +++ b/target/ppc/timebase_helper.c diff --git a/target-ppc/trace-events b/target/ppc/trace-events index 8fcc3ce98c..b666156114 100644 --- a/target-ppc/trace-events +++ b/target/ppc/trace-events @@ -1,5 +1,5 @@ # See docs/tracing.txt for syntax documentation. -# target-ppc/kvm.c +# target/ppc/kvm.c kvm_failed_spr_set(int str, const char *msg) "Warning: Unable to set SPR %d to KVM: %s" kvm_failed_spr_get(int str, const char *msg) "Warning: Unable to retrieve SPR %d from KVM: %s" diff --git a/target-ppc/translate.c b/target/ppc/translate.c index 59e9552d2b..59e9552d2b 100644 --- a/target-ppc/translate.c +++ b/target/ppc/translate.c diff --git a/target-ppc/translate/dfp-impl.inc.c b/target/ppc/translate/dfp-impl.inc.c index 178d3044a7..178d3044a7 100644 --- a/target-ppc/translate/dfp-impl.inc.c +++ b/target/ppc/translate/dfp-impl.inc.c diff --git a/target-ppc/translate/dfp-ops.inc.c b/target/ppc/translate/dfp-ops.inc.c index 6ef38e5712..6ef38e5712 100644 --- a/target-ppc/translate/dfp-ops.inc.c +++ b/target/ppc/translate/dfp-ops.inc.c diff --git a/target-ppc/translate/fp-impl.inc.c b/target/ppc/translate/fp-impl.inc.c index 872af7b56f..872af7b56f 100644 --- a/target-ppc/translate/fp-impl.inc.c +++ b/target/ppc/translate/fp-impl.inc.c diff --git a/target-ppc/translate/fp-ops.inc.c b/target/ppc/translate/fp-ops.inc.c index d36ab4ecc3..d36ab4ecc3 100644 --- a/target-ppc/translate/fp-ops.inc.c +++ b/target/ppc/translate/fp-ops.inc.c diff --git a/target-ppc/translate/spe-impl.inc.c b/target/ppc/translate/spe-impl.inc.c index 8c1c16c63e..8c1c16c63e 100644 --- a/target-ppc/translate/spe-impl.inc.c +++ b/target/ppc/translate/spe-impl.inc.c diff --git a/target-ppc/translate/spe-ops.inc.c b/target/ppc/translate/spe-ops.inc.c index 7efe8b8746..7efe8b8746 100644 --- a/target-ppc/translate/spe-ops.inc.c +++ b/target/ppc/translate/spe-ops.inc.c diff --git a/target-ppc/translate/vmx-impl.inc.c b/target/ppc/translate/vmx-impl.inc.c index 7143eb3a39..7143eb3a39 100644 --- a/target-ppc/translate/vmx-impl.inc.c +++ b/target/ppc/translate/vmx-impl.inc.c diff --git a/target-ppc/translate/vmx-ops.inc.c b/target/ppc/translate/vmx-ops.inc.c index f02b3bed50..f02b3bed50 100644 --- a/target-ppc/translate/vmx-ops.inc.c +++ b/target/ppc/translate/vmx-ops.inc.c diff --git a/target-ppc/translate/vsx-impl.inc.c b/target/ppc/translate/vsx-impl.inc.c index 5a27be4bd4..5a27be4bd4 100644 --- a/target-ppc/translate/vsx-impl.inc.c +++ b/target/ppc/translate/vsx-impl.inc.c diff --git a/target-ppc/translate/vsx-ops.inc.c b/target/ppc/translate/vsx-ops.inc.c index 3d9104155a..3d9104155a 100644 --- a/target-ppc/translate/vsx-ops.inc.c +++ b/target/ppc/translate/vsx-ops.inc.c diff --git a/target-ppc/translate_init.c b/target/ppc/translate_init.c index 626e03186c..626e03186c 100644 --- a/target-ppc/translate_init.c +++ b/target/ppc/translate_init.c diff --git a/target-ppc/user_only_helper.c b/target/ppc/user_only_helper.c index 6aff34713f..6aff34713f 100644 --- a/target-ppc/user_only_helper.c +++ b/target/ppc/user_only_helper.c diff --git a/target-s390x/Makefile.objs b/target/s390x/Makefile.objs index 6b02b1794c..c573633bd1 100644 --- a/target-s390x/Makefile.objs +++ b/target/s390x/Makefile.objs @@ -5,7 +5,7 @@ obj-$(CONFIG_SOFTMMU) += machine.o ioinst.o arch_dump.o mmu_helper.o obj-$(CONFIG_KVM) += kvm.o # build and run feature list generator -feat-src = $(SRC_PATH)/target-$(TARGET_BASE_ARCH)/ +feat-src = $(SRC_PATH)/target/$(TARGET_BASE_ARCH)/ feat-dst = $(BUILD_DIR)/$(TARGET_DIR) ifneq ($(MAKECMDGOALS),clean) GENERATED_HEADERS += $(feat-dst)gen-features.h diff --git a/target-s390x/arch_dump.c b/target/s390x/arch_dump.c index 4731869f6b..4731869f6b 100644 --- a/target-s390x/arch_dump.c +++ b/target/s390x/arch_dump.c diff --git a/target-s390x/cc_helper.c b/target/s390x/cc_helper.c index 1cf855133e..1cf855133e 100644 --- a/target-s390x/cc_helper.c +++ b/target/s390x/cc_helper.c diff --git a/target-s390x/cpu-qom.h b/target/s390x/cpu-qom.h index 4e936e7788..4e936e7788 100644 --- a/target-s390x/cpu-qom.h +++ b/target/s390x/cpu-qom.h diff --git a/target-s390x/cpu.c b/target/s390x/cpu.c index 0a39d31237..0a39d31237 100644 --- a/target-s390x/cpu.c +++ b/target/s390x/cpu.c diff --git a/target-s390x/cpu.h b/target/s390x/cpu.h index fd36a25cf5..fd36a25cf5 100644 --- a/target-s390x/cpu.h +++ b/target/s390x/cpu.h diff --git a/target-s390x/cpu_features.c b/target/s390x/cpu_features.c index 42fd9d792b..42fd9d792b 100644 --- a/target-s390x/cpu_features.c +++ b/target/s390x/cpu_features.c diff --git a/target-s390x/cpu_features.h b/target/s390x/cpu_features.h index d669121786..d669121786 100644 --- a/target-s390x/cpu_features.h +++ b/target/s390x/cpu_features.h diff --git a/target-s390x/cpu_features_def.h b/target/s390x/cpu_features_def.h index aa5ab8d371..aa5ab8d371 100644 --- a/target-s390x/cpu_features_def.h +++ b/target/s390x/cpu_features_def.h diff --git a/target-s390x/cpu_models.c b/target/s390x/cpu_models.c index c1e729df5e..c1e729df5e 100644 --- a/target-s390x/cpu_models.c +++ b/target/s390x/cpu_models.c diff --git a/target-s390x/cpu_models.h b/target/s390x/cpu_models.h index 136a602313..136a602313 100644 --- a/target-s390x/cpu_models.h +++ b/target/s390x/cpu_models.h diff --git a/target-s390x/fpu_helper.c b/target/s390x/fpu_helper.c index e604e9f7be..e604e9f7be 100644 --- a/target-s390x/fpu_helper.c +++ b/target/s390x/fpu_helper.c diff --git a/target-s390x/gdbstub.c b/target/s390x/gdbstub.c index 3d223dec97..3d223dec97 100644 --- a/target-s390x/gdbstub.c +++ b/target/s390x/gdbstub.c diff --git a/target-s390x/gen-features.c b/target/s390x/gen-features.c index e674738ae3..e674738ae3 100644 --- a/target-s390x/gen-features.c +++ b/target/s390x/gen-features.c diff --git a/target-s390x/helper.c b/target/s390x/helper.c index 68bd2f9784..68bd2f9784 100644 --- a/target-s390x/helper.c +++ b/target/s390x/helper.c diff --git a/target-s390x/helper.h b/target/s390x/helper.h index 207a6e7d1c..207a6e7d1c 100644 --- a/target-s390x/helper.h +++ b/target/s390x/helper.h diff --git a/target-s390x/insn-data.def b/target/s390x/insn-data.def index 075ff597c3..075ff597c3 100644 --- a/target-s390x/insn-data.def +++ b/target/s390x/insn-data.def diff --git a/target-s390x/insn-format.def b/target/s390x/insn-format.def index 0e898b90bd..0e898b90bd 100644 --- a/target-s390x/insn-format.def +++ b/target/s390x/insn-format.def diff --git a/target-s390x/int_helper.c b/target/s390x/int_helper.c index 370c94da55..370c94da55 100644 --- a/target-s390x/int_helper.c +++ b/target/s390x/int_helper.c diff --git a/target-s390x/interrupt.c b/target/s390x/interrupt.c index 9edef96795..9edef96795 100644 --- a/target-s390x/interrupt.c +++ b/target/s390x/interrupt.c diff --git a/target-s390x/ioinst.c b/target/s390x/ioinst.c index 590bfa4f12..590bfa4f12 100644 --- a/target-s390x/ioinst.c +++ b/target/s390x/ioinst.c diff --git a/target-s390x/kvm.c b/target/s390x/kvm.c index 97afe02599..97afe02599 100644 --- a/target-s390x/kvm.c +++ b/target/s390x/kvm.c diff --git a/target-s390x/machine.c b/target/s390x/machine.c index edc3a4717b..edc3a4717b 100644 --- a/target-s390x/machine.c +++ b/target/s390x/machine.c diff --git a/target-s390x/mem_helper.c b/target/s390x/mem_helper.c index 99bc5e2834..99bc5e2834 100644 --- a/target-s390x/mem_helper.c +++ b/target/s390x/mem_helper.c diff --git a/target-s390x/misc_helper.c b/target/s390x/misc_helper.c index c9604ea9c7..c9604ea9c7 100644 --- a/target-s390x/misc_helper.c +++ b/target/s390x/misc_helper.c diff --git a/target-s390x/mmu_helper.c b/target/s390x/mmu_helper.c index b11a02706c..b11a02706c 100644 --- a/target-s390x/mmu_helper.c +++ b/target/s390x/mmu_helper.c diff --git a/target-s390x/trace-events b/target/s390x/trace-events index df59f5f19f..1574033e31 100644 --- a/target-s390x/trace-events +++ b/target/s390x/trace-events @@ -1,22 +1,22 @@ # See docs/tracing.txt for syntax documentation. -# target-s390x/mmu_helper.c +# target/s390x/mmu_helper.c get_skeys_nonzero(int rc) "SKEY: Call to get_skeys unexpectedly returned %d" set_skeys_nonzero(int rc) "SKEY: Call to set_skeys unexpectedly returned %d" -# target-s390x/ioinst.c +# target/s390x/ioinst.c ioinst(const char *insn) "IOINST: %s" ioinst_sch_id(const char *insn, int cssid, int ssid, int schid) "IOINST: %s (%x.%x.%04x)" ioinst_chp_id(const char *insn, int cssid, int chpid) "IOINST: %s (%x.%02x)" ioinst_chsc_cmd(uint16_t cmd, uint16_t len) "IOINST: chsc command %04x, len %04x" -# target-s390x/kvm.c +# target/s390x/kvm.c kvm_enable_cmma(int rc) "CMMA: enabling with result code %d" kvm_clear_cmma(int rc) "CMMA: clearing with result code %d" kvm_failed_cpu_state_set(int cpu_index, uint8_t state, const char *msg) "Warning: Unable to set cpu %d state %" PRIu8 " to KVM: %s" kvm_sigp_finished(uint8_t order, int cpu_index, int dst_index, int cc) "SIGP: Finished order %u on cpu %d -> cpu %d with cc=%d" -# target-s390x/cpu.c +# target/s390x/cpu.c cpu_set_state(int cpu_index, uint8_t state) "setting cpu %d state to %" PRIu8 cpu_halt(int cpu_index) "halting cpu %d" cpu_unhalt(int cpu_index) "unhalting cpu %d" diff --git a/target-s390x/translate.c b/target/s390x/translate.c index 02bc7058fd..02bc7058fd 100644 --- a/target-s390x/translate.c +++ b/target/s390x/translate.c diff --git a/target-sh4/Makefile.objs b/target/sh4/Makefile.objs index 2c25d96e65..2c25d96e65 100644 --- a/target-sh4/Makefile.objs +++ b/target/sh4/Makefile.objs diff --git a/target-sh4/README.sh4 b/target/sh4/README.sh4 index ece046442a..a192ca7540 100644 --- a/target-sh4/README.sh4 +++ b/target/sh4/README.sh4 @@ -8,7 +8,7 @@ file describes the current state of implementation. Most places requiring attention and/or modification can be detected by looking for "XXXXX" or "abort()". -The sh4 core is located in target-sh4/*, while the 7750 peripheral +The sh4 core is located in target/sh4/*, while the 7750 peripheral features (IO ports for example) are located in hw/sh7750.[ch]. The main board description is in hw/shix.c, and the NAND flash in hw/tc58128.[ch]. diff --git a/target-sh4/cpu-qom.h b/target/sh4/cpu-qom.h index 01abb206e4..01abb206e4 100644 --- a/target-sh4/cpu-qom.h +++ b/target/sh4/cpu-qom.h diff --git a/target-sh4/cpu.c b/target/sh4/cpu.c index a38f6a6ded..a38f6a6ded 100644 --- a/target-sh4/cpu.c +++ b/target/sh4/cpu.c diff --git a/target-sh4/cpu.h b/target/sh4/cpu.h index 478ab55868..478ab55868 100644 --- a/target-sh4/cpu.h +++ b/target/sh4/cpu.h diff --git a/target-sh4/gdbstub.c b/target/sh4/gdbstub.c index 13bea00d7d..13bea00d7d 100644 --- a/target-sh4/gdbstub.c +++ b/target/sh4/gdbstub.c diff --git a/target-sh4/helper.c b/target/sh4/helper.c index a33ac697c5..a33ac697c5 100644 --- a/target-sh4/helper.c +++ b/target/sh4/helper.c diff --git a/target-sh4/helper.h b/target/sh4/helper.h index dce859caea..dce859caea 100644 --- a/target-sh4/helper.h +++ b/target/sh4/helper.h diff --git a/target-sh4/monitor.c b/target/sh4/monitor.c index 426e5d4914..426e5d4914 100644 --- a/target-sh4/monitor.c +++ b/target/sh4/monitor.c diff --git a/target-sh4/op_helper.c b/target/sh4/op_helper.c index 684d3f3758..684d3f3758 100644 --- a/target-sh4/op_helper.c +++ b/target/sh4/op_helper.c diff --git a/target-sh4/translate.c b/target/sh4/translate.c index c89a14733f..c89a14733f 100644 --- a/target-sh4/translate.c +++ b/target/sh4/translate.c diff --git a/target-sparc/Makefile.objs b/target/sparc/Makefile.objs index ec905698c5..ec905698c5 100644 --- a/target-sparc/Makefile.objs +++ b/target/sparc/Makefile.objs diff --git a/target-sparc/TODO b/target/sparc/TODO index b8c727e858..b8c727e858 100644 --- a/target-sparc/TODO +++ b/target/sparc/TODO diff --git a/target-sparc/asi.h b/target/sparc/asi.h index c9a1849600..c9a1849600 100644 --- a/target-sparc/asi.h +++ b/target/sparc/asi.h diff --git a/target-sparc/cc_helper.c b/target/sparc/cc_helper.c index a410a0b98f..a410a0b98f 100644 --- a/target-sparc/cc_helper.c +++ b/target/sparc/cc_helper.c diff --git a/target-sparc/cpu-qom.h b/target/sparc/cpu-qom.h index f63af728ee..f63af728ee 100644 --- a/target-sparc/cpu-qom.h +++ b/target/sparc/cpu-qom.h diff --git a/target-sparc/cpu.c b/target/sparc/cpu.c index 4e07b92fbd..4e07b92fbd 100644 --- a/target-sparc/cpu.c +++ b/target/sparc/cpu.c diff --git a/target-sparc/cpu.h b/target/sparc/cpu.h index 5fb0ed1aad..5fb0ed1aad 100644 --- a/target-sparc/cpu.h +++ b/target/sparc/cpu.h diff --git a/target-sparc/fop_helper.c b/target/sparc/fop_helper.c index c7fb176e4c..c7fb176e4c 100644 --- a/target-sparc/fop_helper.c +++ b/target/sparc/fop_helper.c diff --git a/target-sparc/gdbstub.c b/target/sparc/gdbstub.c index ffc2baa2e7..ffc2baa2e7 100644 --- a/target-sparc/gdbstub.c +++ b/target/sparc/gdbstub.c diff --git a/target-sparc/helper.c b/target/sparc/helper.c index 359b0b15ed..359b0b15ed 100644 --- a/target-sparc/helper.c +++ b/target/sparc/helper.c diff --git a/target-sparc/helper.h b/target/sparc/helper.h index 0cf1bfb73a..0cf1bfb73a 100644 --- a/target-sparc/helper.h +++ b/target/sparc/helper.h diff --git a/target-sparc/int32_helper.c b/target/sparc/int32_helper.c index 09afe136e5..09afe136e5 100644 --- a/target-sparc/int32_helper.c +++ b/target/sparc/int32_helper.c diff --git a/target-sparc/int64_helper.c b/target/sparc/int64_helper.c index 29360fa5fe..29360fa5fe 100644 --- a/target-sparc/int64_helper.c +++ b/target/sparc/int64_helper.c diff --git a/target-sparc/ldst_helper.c b/target/sparc/ldst_helper.c index de7d53ae20..de7d53ae20 100644 --- a/target-sparc/ldst_helper.c +++ b/target/sparc/ldst_helper.c diff --git a/target-sparc/machine.c b/target/sparc/machine.c index aea6397861..aea6397861 100644 --- a/target-sparc/machine.c +++ b/target/sparc/machine.c diff --git a/target-sparc/mmu_helper.c b/target/sparc/mmu_helper.c index 044e88c4c5..044e88c4c5 100644 --- a/target-sparc/mmu_helper.c +++ b/target/sparc/mmu_helper.c diff --git a/target-sparc/monitor.c b/target/sparc/monitor.c index 7cc1b0f87f..7cc1b0f87f 100644 --- a/target-sparc/monitor.c +++ b/target/sparc/monitor.c diff --git a/target-sparc/trace-events b/target/sparc/trace-events index bf52d9769b..8df178a347 100644 --- a/target-sparc/trace-events +++ b/target/sparc/trace-events @@ -1,6 +1,6 @@ # See docs/tracing.txt for syntax documentation. -# target-sparc/mmu_helper.c +# target/sparc/mmu_helper.c mmu_helper_dfault(uint64_t address, uint64_t context, int mmu_idx, uint32_t tl) "DFAULT at %"PRIx64" context %"PRIx64" mmu_idx=%d tl=%d" mmu_helper_dprot(uint64_t address, uint64_t context, int mmu_idx, uint32_t tl) "DPROT at %"PRIx64" context %"PRIx64" mmu_idx=%d tl=%d" mmu_helper_dmiss(uint64_t address, uint64_t context) "DMISS at %"PRIx64" context %"PRIx64 @@ -10,16 +10,16 @@ mmu_helper_get_phys_addr_code(uint32_t tl, int mmu_idx, uint64_t prim_context, u mmu_helper_get_phys_addr_data(uint32_t tl, int mmu_idx, uint64_t prim_context, uint64_t sec_context, uint64_t address) "tl=%d mmu_idx=%d primary context=%"PRIx64" secondary context=%"PRIx64" address=%"PRIx64 mmu_helper_mmu_fault(uint64_t address, uint64_t paddr, int mmu_idx, uint32_t tl, uint64_t prim_context, uint64_t sec_context) "Translate at %"PRIx64" -> %"PRIx64", mmu_idx=%d tl=%d primary context=%"PRIx64" secondary context=%"PRIx64 -# target-sparc/int64_helper.c +# target/sparc/int64_helper.c int_helper_set_softint(uint32_t softint) "new %08x" int_helper_clear_softint(uint32_t softint) "new %08x" int_helper_write_softint(uint32_t softint) "new %08x" -# target-sparc/int32_helper.c +# target/sparc/int32_helper.c int_helper_icache_freeze(void) "Instruction cache: freeze" int_helper_dcache_freeze(void) "Data cache: freeze" -# target-sparc/win_helper.c +# target/sparc/win_helper.c win_helper_gregset_error(uint32_t pstate) "ERROR in get_gregset: active pstate bits=%x" win_helper_switch_pstate(uint32_t pstate_regs, uint32_t new_pstate_regs) "change_pstate: switching regs old=%x new=%x" win_helper_no_switch_pstate(uint32_t new_pstate_regs) "change_pstate: regs new=%x (unchanged)" diff --git a/target-sparc/translate.c b/target/sparc/translate.c index 2205f89837..2205f89837 100644 --- a/target-sparc/translate.c +++ b/target/sparc/translate.c diff --git a/target-sparc/vis_helper.c b/target/sparc/vis_helper.c index 8a9b763d0b..8a9b763d0b 100644 --- a/target-sparc/vis_helper.c +++ b/target/sparc/vis_helper.c diff --git a/target-sparc/win_helper.c b/target/sparc/win_helper.c index 2d5b5469a9..2d5b5469a9 100644 --- a/target-sparc/win_helper.c +++ b/target/sparc/win_helper.c diff --git a/target-tilegx/Makefile.objs b/target/tilegx/Makefile.objs index 0db778f407..0db778f407 100644 --- a/target-tilegx/Makefile.objs +++ b/target/tilegx/Makefile.objs diff --git a/target-tilegx/cpu.c b/target/tilegx/cpu.c index 454793f94a..454793f94a 100644 --- a/target-tilegx/cpu.c +++ b/target/tilegx/cpu.c diff --git a/target-tilegx/cpu.h b/target/tilegx/cpu.h index 1735427233..1735427233 100644 --- a/target-tilegx/cpu.h +++ b/target/tilegx/cpu.h diff --git a/target-tilegx/helper.c b/target/tilegx/helper.c index b4fba9cc21..b4fba9cc21 100644 --- a/target-tilegx/helper.c +++ b/target/tilegx/helper.c diff --git a/target-tilegx/helper.h b/target/tilegx/helper.h index 9281d0f428..9281d0f428 100644 --- a/target-tilegx/helper.h +++ b/target/tilegx/helper.h diff --git a/target-tilegx/opcode_tilegx.h b/target/tilegx/opcode_tilegx.h index 55376be4cf..55376be4cf 100644 --- a/target-tilegx/opcode_tilegx.h +++ b/target/tilegx/opcode_tilegx.h diff --git a/target-tilegx/simd_helper.c b/target/tilegx/simd_helper.c index 2d40ddb63e..2d40ddb63e 100644 --- a/target-tilegx/simd_helper.c +++ b/target/tilegx/simd_helper.c diff --git a/target-tilegx/spr_def_64.h b/target/tilegx/spr_def_64.h index 67a6c1751e..67a6c1751e 100644 --- a/target-tilegx/spr_def_64.h +++ b/target/tilegx/spr_def_64.h diff --git a/target-tilegx/translate.c b/target/tilegx/translate.c index 9c734eeba3..9c734eeba3 100644 --- a/target-tilegx/translate.c +++ b/target/tilegx/translate.c diff --git a/target-tricore/Makefile.objs b/target/tricore/Makefile.objs index 7a05670718..7a05670718 100644 --- a/target-tricore/Makefile.objs +++ b/target/tricore/Makefile.objs diff --git a/target-tricore/cpu-qom.h b/target/tricore/cpu-qom.h index 6a69756126..6a69756126 100644 --- a/target-tricore/cpu-qom.h +++ b/target/tricore/cpu-qom.h diff --git a/target-tricore/cpu.c b/target/tricore/cpu.c index 785b76bd3a..785b76bd3a 100644 --- a/target-tricore/cpu.c +++ b/target/tricore/cpu.c diff --git a/target-tricore/cpu.h b/target/tricore/cpu.h index a3493a123c..a3493a123c 100644 --- a/target-tricore/cpu.h +++ b/target/tricore/cpu.h diff --git a/target-tricore/csfr.def b/target/tricore/csfr.def index 05c45dd628..05c45dd628 100644 --- a/target-tricore/csfr.def +++ b/target/tricore/csfr.def diff --git a/target-tricore/fpu_helper.c b/target/tricore/fpu_helper.c index 98fe9472b1..98fe9472b1 100644 --- a/target-tricore/fpu_helper.c +++ b/target/tricore/fpu_helper.c diff --git a/target-tricore/helper.c b/target/tricore/helper.c index 3118905eca..3118905eca 100644 --- a/target-tricore/helper.c +++ b/target/tricore/helper.c diff --git a/target-tricore/helper.h b/target/tricore/helper.h index 9333e161ab..9333e161ab 100644 --- a/target-tricore/helper.h +++ b/target/tricore/helper.h diff --git a/target-tricore/op_helper.c b/target/tricore/op_helper.c index ac02e0a36b..ac02e0a36b 100644 --- a/target-tricore/op_helper.c +++ b/target/tricore/op_helper.c diff --git a/target-tricore/translate.c b/target/tricore/translate.c index 36f734a662..36f734a662 100644 --- a/target-tricore/translate.c +++ b/target/tricore/translate.c diff --git a/target-tricore/tricore-defs.h b/target/tricore/tricore-defs.h index 40abfaac14..40abfaac14 100644 --- a/target-tricore/tricore-defs.h +++ b/target/tricore/tricore-defs.h diff --git a/target-tricore/tricore-opcodes.h b/target/tricore/tricore-opcodes.h index df666b081f..df666b081f 100644 --- a/target-tricore/tricore-opcodes.h +++ b/target/tricore/tricore-opcodes.h diff --git a/target-unicore32/Makefile.objs b/target/unicore32/Makefile.objs index 6b41b1e9ef..6b41b1e9ef 100644 --- a/target-unicore32/Makefile.objs +++ b/target/unicore32/Makefile.objs diff --git a/target-unicore32/cpu-qom.h b/target/unicore32/cpu-qom.h index bc68e78045..bc68e78045 100644 --- a/target-unicore32/cpu-qom.h +++ b/target/unicore32/cpu-qom.h diff --git a/target-unicore32/cpu.c b/target/unicore32/cpu.c index c169972b59..c169972b59 100644 --- a/target-unicore32/cpu.c +++ b/target/unicore32/cpu.c diff --git a/target-unicore32/cpu.h b/target/unicore32/cpu.h index 7b5b405e79..7b5b405e79 100644 --- a/target-unicore32/cpu.h +++ b/target/unicore32/cpu.h diff --git a/target-unicore32/helper.c b/target/unicore32/helper.c index d603bde237..d603bde237 100644 --- a/target-unicore32/helper.c +++ b/target/unicore32/helper.c diff --git a/target-unicore32/helper.h b/target/unicore32/helper.h index 941813749d..941813749d 100644 --- a/target-unicore32/helper.h +++ b/target/unicore32/helper.h diff --git a/target-unicore32/op_helper.c b/target/unicore32/op_helper.c index 0872c29faa..0872c29faa 100644 --- a/target-unicore32/op_helper.c +++ b/target/unicore32/op_helper.c diff --git a/target-unicore32/softmmu.c b/target/unicore32/softmmu.c index e7152e72e0..e7152e72e0 100644 --- a/target-unicore32/softmmu.c +++ b/target/unicore32/softmmu.c diff --git a/target-unicore32/translate.c b/target/unicore32/translate.c index 514d460408..514d460408 100644 --- a/target-unicore32/translate.c +++ b/target/unicore32/translate.c diff --git a/target-unicore32/ucf64_helper.c b/target/unicore32/ucf64_helper.c index 6c919010c3..6c919010c3 100644 --- a/target-unicore32/ucf64_helper.c +++ b/target/unicore32/ucf64_helper.c diff --git a/target-xtensa/Makefile.objs b/target/xtensa/Makefile.objs index 481de91973..481de91973 100644 --- a/target-xtensa/Makefile.objs +++ b/target/xtensa/Makefile.objs diff --git a/target-xtensa/core-dc232b.c b/target/xtensa/core-dc232b.c index bb8ed4197f..bb8ed4197f 100644 --- a/target-xtensa/core-dc232b.c +++ b/target/xtensa/core-dc232b.c diff --git a/target-xtensa/core-dc232b/core-isa.h b/target/xtensa/core-dc232b/core-isa.h index a9935b87af..a9935b87af 100644 --- a/target-xtensa/core-dc232b/core-isa.h +++ b/target/xtensa/core-dc232b/core-isa.h diff --git a/target-xtensa/core-dc232b/gdb-config.c b/target/xtensa/core-dc232b/gdb-config.c index 13aba5edec..13aba5edec 100644 --- a/target-xtensa/core-dc232b/gdb-config.c +++ b/target/xtensa/core-dc232b/gdb-config.c diff --git a/target-xtensa/core-dc233c.c b/target/xtensa/core-dc233c.c index 40475e5205..40475e5205 100644 --- a/target-xtensa/core-dc233c.c +++ b/target/xtensa/core-dc233c.c diff --git a/target-xtensa/core-dc233c/core-isa.h b/target/xtensa/core-dc233c/core-isa.h index ff92b7f3ed..ff92b7f3ed 100644 --- a/target-xtensa/core-dc233c/core-isa.h +++ b/target/xtensa/core-dc233c/core-isa.h diff --git a/target-xtensa/core-dc233c/gdb-config.c b/target/xtensa/core-dc233c/gdb-config.c index b632341b28..b632341b28 100644 --- a/target-xtensa/core-dc233c/gdb-config.c +++ b/target/xtensa/core-dc233c/gdb-config.c diff --git a/target-xtensa/core-fsf.c b/target/xtensa/core-fsf.c index 15ef470e8b..15ef470e8b 100644 --- a/target-xtensa/core-fsf.c +++ b/target/xtensa/core-fsf.c diff --git a/target-xtensa/core-fsf/core-isa.h b/target/xtensa/core-fsf/core-isa.h index fb2bb8f2cb..fb2bb8f2cb 100644 --- a/target-xtensa/core-fsf/core-isa.h +++ b/target/xtensa/core-fsf/core-isa.h diff --git a/target-xtensa/cpu-qom.h b/target/xtensa/cpu-qom.h index 403bd95721..403bd95721 100644 --- a/target-xtensa/cpu-qom.h +++ b/target/xtensa/cpu-qom.h diff --git a/target-xtensa/cpu.c b/target/xtensa/cpu.c index e8e9f9175b..e8e9f9175b 100644 --- a/target-xtensa/cpu.c +++ b/target/xtensa/cpu.c diff --git a/target-xtensa/cpu.h b/target/xtensa/cpu.h index 7fe82a37af..7fe82a37af 100644 --- a/target-xtensa/cpu.h +++ b/target/xtensa/cpu.h diff --git a/target-xtensa/gdbstub.c b/target/xtensa/gdbstub.c index fa5469a4ef..fa5469a4ef 100644 --- a/target-xtensa/gdbstub.c +++ b/target/xtensa/gdbstub.c diff --git a/target-xtensa/helper.c b/target/xtensa/helper.c index 768b32c417..768b32c417 100644 --- a/target-xtensa/helper.c +++ b/target/xtensa/helper.c diff --git a/target-xtensa/helper.h b/target/xtensa/helper.h index 5ea9c5beec..5ea9c5beec 100644 --- a/target-xtensa/helper.h +++ b/target/xtensa/helper.h diff --git a/target-xtensa/import_core.sh b/target/xtensa/import_core.sh index 351bee41c2..351bee41c2 100755 --- a/target-xtensa/import_core.sh +++ b/target/xtensa/import_core.sh diff --git a/target-xtensa/monitor.c b/target/xtensa/monitor.c index f3fa4cd278..f3fa4cd278 100644 --- a/target-xtensa/monitor.c +++ b/target/xtensa/monitor.c diff --git a/target-xtensa/op_helper.c b/target/xtensa/op_helper.c index 0a4b2147bc..0a4b2147bc 100644 --- a/target-xtensa/op_helper.c +++ b/target/xtensa/op_helper.c diff --git a/target-xtensa/overlay_tool.h b/target/xtensa/overlay_tool.h index e8a7fda3d8..e8a7fda3d8 100644 --- a/target-xtensa/overlay_tool.h +++ b/target/xtensa/overlay_tool.h diff --git a/target-xtensa/translate.c b/target/xtensa/translate.c index 0858c296ea..0858c296ea 100644 --- a/target-xtensa/translate.c +++ b/target/xtensa/translate.c diff --git a/target-xtensa/xtensa-semi.c b/target/xtensa/xtensa-semi.c index 370e365c65..370e365c65 100644 --- a/target-xtensa/xtensa-semi.c +++ b/target/xtensa/xtensa-semi.c diff --git a/tcg/s390/tcg-target.inc.c b/tcg/s390/tcg-target.inc.c index 253d4a0a0b..8d5d2bd300 100644 --- a/tcg/s390/tcg-target.inc.c +++ b/tcg/s390/tcg-target.inc.c @@ -378,11 +378,6 @@ static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str) ct->ct |= TCG_CT_REG; tcg_regset_set32(ct->u.regs, 0, 0xffff); break; - case 'R': /* not R0 */ - ct->ct |= TCG_CT_REG; - tcg_regset_set32(ct->u.regs, 0, 0xffff); - tcg_regset_reset_reg(ct->u.regs, TCG_REG_R0); - break; case 'L': /* qemu_ld/st constraint */ ct->ct |= TCG_CT_REG; tcg_regset_set32(ct->u.regs, 0, 0xffff); @@ -1093,33 +1088,43 @@ static void tgen64_xori(TCGContext *s, TCGReg dest, tcg_target_ulong val) } static int tgen_cmp(TCGContext *s, TCGType type, TCGCond c, TCGReg r1, - TCGArg c2, int c2const) + TCGArg c2, bool c2const, bool need_carry) { bool is_unsigned = is_unsigned_cond(c); if (c2const) { if (c2 == 0) { + if (!(is_unsigned && need_carry)) { + if (type == TCG_TYPE_I32) { + tcg_out_insn(s, RR, LTR, r1, r1); + } else { + tcg_out_insn(s, RRE, LTGR, r1, r1); + } + return tcg_cond_to_ltr_cond[c]; + } + /* If we only got here because of load-and-test, + and we couldn't use that, then we need to load + the constant into a register. */ + if (!(facilities & FACILITY_EXT_IMM)) { + c2 = TCG_TMP0; + tcg_out_movi(s, type, c2, 0); + goto do_reg; + } + } + if (is_unsigned) { if (type == TCG_TYPE_I32) { - tcg_out_insn(s, RR, LTR, r1, r1); + tcg_out_insn(s, RIL, CLFI, r1, c2); } else { - tcg_out_insn(s, RRE, LTGR, r1, r1); + tcg_out_insn(s, RIL, CLGFI, r1, c2); } - return tcg_cond_to_ltr_cond[c]; } else { - if (is_unsigned) { - if (type == TCG_TYPE_I32) { - tcg_out_insn(s, RIL, CLFI, r1, c2); - } else { - tcg_out_insn(s, RIL, CLGFI, r1, c2); - } + if (type == TCG_TYPE_I32) { + tcg_out_insn(s, RIL, CFI, r1, c2); } else { - if (type == TCG_TYPE_I32) { - tcg_out_insn(s, RIL, CFI, r1, c2); - } else { - tcg_out_insn(s, RIL, CGFI, r1, c2); - } + tcg_out_insn(s, RIL, CGFI, r1, c2); } } } else { + do_reg: if (is_unsigned) { if (type == TCG_TYPE_I32) { tcg_out_insn(s, RR, CLR, r1, c2); @@ -1148,7 +1153,7 @@ static void tgen_setcond(TCGContext *s, TCGType type, TCGCond cond, do_greater: /* The result of a compare has CC=2 for GT and CC=3 unused. ADD LOGICAL WITH CARRY considers (CC & 2) the carry bit. */ - tgen_cmp(s, type, cond, c1, c2, c2const); + tgen_cmp(s, type, cond, c1, c2, c2const, true); tcg_out_movi(s, type, dest, 0); tcg_out_insn(s, RRE, ALCGR, dest, dest); return; @@ -1219,7 +1224,7 @@ static void tgen_setcond(TCGContext *s, TCGType type, TCGCond cond, break; } - cc = tgen_cmp(s, type, cond, c1, c2, c2const); + cc = tgen_cmp(s, type, cond, c1, c2, c2const, false); if (facilities & FACILITY_LOAD_ON_COND) { /* Emit: d = 0, t = 1, d = (cc ? t : d). */ tcg_out_movi(s, TCG_TYPE_I64, dest, 0); @@ -1238,11 +1243,11 @@ static void tgen_movcond(TCGContext *s, TCGType type, TCGCond c, TCGReg dest, { int cc; if (facilities & FACILITY_LOAD_ON_COND) { - cc = tgen_cmp(s, type, c, c1, c2, c2const); + cc = tgen_cmp(s, type, c, c1, c2, c2const, false); tcg_out_insn(s, RRF, LOCGR, dest, r3, cc); } else { c = tcg_invert_cond(c); - cc = tgen_cmp(s, type, c, c1, c2, c2const); + cc = tgen_cmp(s, type, c, c1, c2, c2const, false); /* Emit: if (cc) goto over; dest = r3; over: */ tcg_out_insn(s, RI, BRC, cc, (4 + 4) >> 1); @@ -1374,7 +1379,7 @@ static void tgen_brcond(TCGContext *s, TCGType type, TCGCond c, } } - cc = tgen_cmp(s, type, c, r1, c2, c2const); + cc = tgen_cmp(s, type, c, r1, c2, c2const, false); tgen_branch(s, cc, l); } @@ -2216,12 +2221,12 @@ static const TCGTargetOpDef s390_op_defs[] = { { INDEX_op_neg_i32, { "r", "r" } }, - { INDEX_op_shl_i32, { "r", "0", "Ri" } }, - { INDEX_op_shr_i32, { "r", "0", "Ri" } }, - { INDEX_op_sar_i32, { "r", "0", "Ri" } }, + { INDEX_op_shl_i32, { "r", "0", "ri" } }, + { INDEX_op_shr_i32, { "r", "0", "ri" } }, + { INDEX_op_sar_i32, { "r", "0", "ri" } }, - { INDEX_op_rotl_i32, { "r", "r", "Ri" } }, - { INDEX_op_rotr_i32, { "r", "r", "Ri" } }, + { INDEX_op_rotl_i32, { "r", "r", "ri" } }, + { INDEX_op_rotr_i32, { "r", "r", "ri" } }, { INDEX_op_ext8s_i32, { "r", "r" } }, { INDEX_op_ext8u_i32, { "r", "r" } }, @@ -2271,12 +2276,12 @@ static const TCGTargetOpDef s390_op_defs[] = { { INDEX_op_neg_i64, { "r", "r" } }, - { INDEX_op_shl_i64, { "r", "r", "Ri" } }, - { INDEX_op_shr_i64, { "r", "r", "Ri" } }, - { INDEX_op_sar_i64, { "r", "r", "Ri" } }, + { INDEX_op_shl_i64, { "r", "r", "ri" } }, + { INDEX_op_shr_i64, { "r", "r", "ri" } }, + { INDEX_op_sar_i64, { "r", "r", "ri" } }, - { INDEX_op_rotl_i64, { "r", "r", "Ri" } }, - { INDEX_op_rotr_i64, { "r", "r", "Ri" } }, + { INDEX_op_rotl_i64, { "r", "r", "ri" } }, + { INDEX_op_rotr_i64, { "r", "r", "ri" } }, { INDEX_op_ext8s_i64, { "r", "r" } }, { INDEX_op_ext8u_i64, { "r", "r" } }, diff --git a/tests/Makefile.include b/tests/Makefile.include index e98d3b6bb3..4841d582a1 100644 --- a/tests/Makefile.include +++ b/tests/Makefile.include @@ -91,6 +91,7 @@ gcov-files-test-qemu-opts-y = qom/test-qemu-opts.c check-unit-y += tests/test-write-threshold$(EXESUF) gcov-files-test-write-threshold-y = block/write-threshold.c check-unit-y += tests/test-crypto-hash$(EXESUF) +check-unit-y += tests/test-crypto-hmac$(EXESUF) check-unit-y += tests/test-crypto-cipher$(EXESUF) check-unit-y += tests/test-crypto-secret$(EXESUF) check-unit-$(CONFIG_GNUTLS) += tests/test-crypto-tlscredsx509$(EXESUF) @@ -571,6 +572,7 @@ tests/test-opts-visitor$(EXESUF): tests/test-opts-visitor.o $(test-qapi-obj-y) tests/test-mul64$(EXESUF): tests/test-mul64.o $(test-util-obj-y) tests/test-bitops$(EXESUF): tests/test-bitops.o $(test-util-obj-y) tests/test-crypto-hash$(EXESUF): tests/test-crypto-hash.o $(test-crypto-obj-y) +tests/test-crypto-hmac$(EXESUF): tests/test-crypto-hmac.o $(test-crypto-obj-y) tests/test-crypto-cipher$(EXESUF): tests/test-crypto-cipher.o $(test-crypto-obj-y) tests/test-crypto-secret$(EXESUF): tests/test-crypto-secret.o $(test-crypto-obj-y) tests/test-crypto-xts$(EXESUF): tests/test-crypto-xts.o $(test-crypto-obj-y) diff --git a/tests/tcg/xtensa/Makefile b/tests/tcg/xtensa/Makefile index 522a63e36b..7f9f2d96c3 100644 --- a/tests/tcg/xtensa/Makefile +++ b/tests/tcg/xtensa/Makefile @@ -19,7 +19,7 @@ AS = $(CROSS)gcc -x assembler-with-cpp LD = $(CROSS)ld XTENSA_SRC_PATH = $(SRC_PATH)/tests/tcg/xtensa -INCLUDE_DIRS = $(XTENSA_SRC_PATH) $(SRC_PATH)/target-xtensa/core-$(CORE) +INCLUDE_DIRS = $(XTENSA_SRC_PATH) $(SRC_PATH)/target/xtensa/core-$(CORE) XTENSA_INC = $(addprefix -I,$(INCLUDE_DIRS)) LDFLAGS = -Tlinker.ld diff --git a/tests/test-crypto-cipher.c b/tests/test-crypto-cipher.c index 5d9e535e2e..07fa2fa616 100644 --- a/tests/test-crypto-cipher.c +++ b/tests/test-crypto-cipher.c @@ -165,6 +165,125 @@ static QCryptoCipherTestData test_data[] = { "ffd29f1bb5596ad94ea2d8e6196b7f09" "30d8ed0bf2773af36dd82a6280c20926", }, +#if defined(CONFIG_NETTLE) || defined(CONFIG_GCRYPT) + { + /* Borrowed from linux-kernel crypto/testmgr.h */ + .path = "/crypto/cipher/3des-cbc", + .alg = QCRYPTO_CIPHER_ALG_3DES, + .mode = QCRYPTO_CIPHER_MODE_CBC, + .key = + "e9c0ff2e760b6424444d995a12d640c0" + "eac284e81495dbe8", + .iv = + "7d3388930f93b242", + .plaintext = + "6f54206f614d796e5320636565727374" + "54206f6f4d206e612079655372637465" + "20736f54206f614d796e532063656572" + "737454206f6f4d206e61207965537263" + "746520736f54206f614d796e53206365" + "6572737454206f6f4d206e6120796553" + "7263746520736f54206f614d796e5320" + "63656572737454206f6f4d206e610a79", + .ciphertext = + "0e2db6973c5633f4671721c76e8ad549" + "74b34905c51cd0ed12565c5396b6007d" + "9048fcf58d2939cc8ad5351836234ed7" + "76d1da0c9467bb048bf2036ca8cfb6ea" + "226447aa8f7513bf9fc2c3f0c956c57a" + "71632e897b1e12cae25fafd8a4f8c97a" + "d6f92131624445a6d6bc5ad32d5443cc" + "9ddea570e942458a6bfab19113b0d919", + }, + { + /* Borrowed from linux-kernel crypto/testmgr.h */ + .path = "/crypto/cipher/3des-ecb", + .alg = QCRYPTO_CIPHER_ALG_3DES, + .mode = QCRYPTO_CIPHER_MODE_ECB, + .key = + "0123456789abcdef5555555555555555" + "fedcba9876543210", + .plaintext = + "736f6d6564617461", + .ciphertext = + "18d748e563620572", + }, + { + /* Borrowed from linux-kernel crypto/testmgr.h */ + .path = "/crypto/cipher/3des-ctr", + .alg = QCRYPTO_CIPHER_ALG_3DES, + .mode = QCRYPTO_CIPHER_MODE_CTR, + .key = + "9cd6f39cb95a67005a67002dceeb2dce" + "ebb45172b451721f", + .iv = + "ffffffffffffffff", + .plaintext = + "05ec77fb42d559208b128669f05bcf56" + "39ad349f66ea7dc448d3ba0db118e34a" + "fe41285c278e11856cf75ec2553ca00b" + "9265e970db4fd6b900b41fe649fd442f" + "533a8d149863ca5dc1a833a70e9178ec" + "77de42d5bc078b12e54cf05b22563980" + "6b9f66c950c4af36ba0d947fe34add41" + "28b31a8e11f843f75e21553c876e9265" + "cc57dba235b900eb72e649d0442fb619" + "8d14ff46ca5d24a8339a6d9178c377de" + "a108bc07ee71e54cd75b22b51c806bf2" + "45c9503baf369960947fc64adda40fb3" + "1aed74f8432a5e218813876ef158cc57" + "3ea2359c67eb72c549d0bb02b619e04b" + "ff46295d248f169a6df45fc3aa3da108" + "937aee71d84cd7be01b51ce74ef2452c" + "503b82159960cb52c6a930a40f9679ed" + "74df432abd048813fa4df15823573e81" + "689c67ce51c5ac37bb02957ce04bd246" + "29b01b8f16f940f45f26aa3d846f937a" + "cd54d8a30abe01e873e74ed1452cb71e" + "8215fc47cb5225a9309b629679c074df" + "a609bd04ef76fa4dd458238a1d8168f3" + "5ace5138ac379e61957cc74bd2a50cb0" + "1be275f9402b5f268910846ff659cd54" + "3fa30a9d64e873da4ed1b803b71ee148" + "fc472e52258c179b62f55cc0ab32a609" + "907bef76d94dd4bf068a1de44ff35a2d" + "5138836a9e61c853c7ae31a50c977ee2" + "75dc402bb2058910fb42f65920543f86" + "699d64cf56daad34b803ea7de148d347", + .ciphertext = + "07c20820721f49ef19cd6f3253052215" + "a2852bdb85d2d8b9dd0d1b45cb6911d4" + "eabeb2455d0caebea0c127ac659f537e" + "afc21bb5b86d360c25c0f86d0b2901da" + "1378dc89121243faf612ef8d87627883" + "e2be41204c6d351bd10c30cfe2de2b03" + "bf4573d4e55995d1b39b276297bdde7f" + "a4d23980aa5023f074883da86a18793b" + "c4966c8d2240926ed6ad2a1fde63c0e7" + "07f72df7b5f3f0cc017c2a9bc210caaa" + "fd2b3fc5f3f6fc9b45db53e45bf3c97b" + "8e52ffc802b8ac9da10039da3d2d0e01" + "097d8d5ebe53b9b08ee7e2966ab278ea" + "de238ba5fa5ce3dabf8e316a55d16ab2" + "b5466fa5f0eeba1f9f98b0664fd03fa9" + "df5f58c4f4ff755c403a097e6e1c97d4" + "cce7e771cf0b150871fa0797cde6ca1d" + "14280ccf99137af1ebfafa9207de1da1" + "d33669fe514d9f2e83374f1f4830ed04" + "4da4ef3aca76f41c418f6337782f86a6" + "ef417ed2af88ab675271c38ef8269372" + "aad60ee70b46b13ab408a9a8a0cf200c" + "52bc8b0556b2bc319b74b92929969a50" + "dc45dc1aeb0c64d4d3057e5955c3f490" + "c2abf89b8adacea1c3f4ad77dd44c8ac" + "a3f1c9d2195cb0caa234c1f76cfdac65" + "32dc48c4f2006b77f17d76acc031632a" + "a53a62c891b10365cb43d106dfc367bc" + "dce0cd35ce4965a0527ba70d07a91bb0" + "407772c2ea0e3a7846b991b6e73d5142" + "fd51b0c62c6313785ceefccfc4700034", + }, +#endif { /* RFC 2144, Appendix B.1 */ .path = "/crypto/cipher/cast5-128", diff --git a/tests/test-crypto-hmac.c b/tests/test-crypto-hmac.c new file mode 100644 index 0000000000..ee55382a3c --- /dev/null +++ b/tests/test-crypto-hmac.c @@ -0,0 +1,266 @@ +/* + * QEMU Crypto hmac algorithms tests + * + * Copyright (c) 2016 HUAWEI TECHNOLOGIES CO., LTD. + * + * Authors: + * Longpeng(Mike) <longpeng2@huawei.com> + * + * This work is licensed under the terms of the GNU GPL, version 2 or + * (at your option) any later version. See the COPYING file in the + * top-level directory. + * + */ + +#include "qemu/osdep.h" +#include "crypto/init.h" +#include "crypto/hmac.h" + +#define INPUT_TEXT1 "ABCDEFGHIJKLMNOPQRSTUVWXY" +#define INPUT_TEXT2 "Zabcdefghijklmnopqrstuvwx" +#define INPUT_TEXT3 "yz0123456789" +#define INPUT_TEXT INPUT_TEXT1 \ + INPUT_TEXT2 \ + INPUT_TEXT3 + +#define KEY "monkey monkey monkey monkey" + +typedef struct QCryptoHmacTestData QCryptoHmacTestData; +struct QCryptoHmacTestData { + QCryptoHashAlgorithm alg; + const char *hex_digest; +}; + +static QCryptoHmacTestData test_data[] = { + { + .alg = QCRYPTO_HASH_ALG_MD5, + .hex_digest = + "ede9cb83679ba82d88fbeae865b3f8fc", + }, + { + .alg = QCRYPTO_HASH_ALG_SHA1, + .hex_digest = + "c7b5a631e3aac975c4ededfcd346e469" + "dbc5f2d1", + }, + { + .alg = QCRYPTO_HASH_ALG_SHA224, + .hex_digest = + "5f768179dbb29ca722875d0f461a2e2f" + "597d0210340a84df1a8e9c63", + }, + { + .alg = QCRYPTO_HASH_ALG_SHA256, + .hex_digest = + "3798f363c57afa6edaffe39016ca7bad" + "efd1e670afb0e3987194307dec3197db", + }, + { + .alg = QCRYPTO_HASH_ALG_SHA384, + .hex_digest = + "d218680a6032d33dccd9882d6a6a7164" + "64f26623be257a9b2919b185294f4a49" + "9e54b190bfd6bc5cedd2cd05c7e65e82", + }, + { + .alg = QCRYPTO_HASH_ALG_SHA512, + .hex_digest = + "835a4f5b3750b4c1fccfa88da2f746a4" + "900160c9f18964309bb736c13b59491b" + "8e32d37b724cc5aebb0f554c6338a3b5" + "94c4ba26862b2dadb59b7ede1d08d53e", + }, + { + .alg = QCRYPTO_HASH_ALG_RIPEMD160, + .hex_digest = + "94964ed4c1155b62b668c241d67279e5" + "8a711676", + }, +}; + +static const char hex[] = "0123456789abcdef"; + +static void test_hmac_alloc(void) +{ + size_t i; + + for (i = 0; i < G_N_ELEMENTS(test_data); i++) { + QCryptoHmacTestData *data = &test_data[i]; + QCryptoHmac *hmac = NULL; + uint8_t *result = NULL; + size_t resultlen = 0; + Error *err = NULL; + const char *exp_output = NULL; + int ret; + size_t j; + + if (!qcrypto_hmac_supports(data->alg)) { + return; + } + + exp_output = data->hex_digest; + + hmac = qcrypto_hmac_new(data->alg, (const uint8_t *)KEY, + strlen(KEY), &err); + g_assert(err == NULL); + g_assert(hmac != NULL); + + ret = qcrypto_hmac_bytes(hmac, (const char *)INPUT_TEXT, + strlen(INPUT_TEXT), &result, + &resultlen, &err); + g_assert(err == NULL); + g_assert(ret == 0); + + for (j = 0; j < resultlen; j++) { + g_assert(exp_output[j * 2] == hex[(result[j] >> 4) & 0xf]); + g_assert(exp_output[j * 2 + 1] == hex[result[j] & 0xf]); + } + + qcrypto_hmac_free(hmac); + + g_free(result); + } +} + +static void test_hmac_prealloc(void) +{ + size_t i; + + for (i = 0; i < G_N_ELEMENTS(test_data); i++) { + QCryptoHmacTestData *data = &test_data[i]; + QCryptoHmac *hmac = NULL; + uint8_t *result = NULL; + size_t resultlen = 0; + Error *err = NULL; + const char *exp_output = NULL; + int ret; + size_t j; + + if (!qcrypto_hmac_supports(data->alg)) { + return; + } + + exp_output = data->hex_digest; + + resultlen = strlen(exp_output) / 2; + result = g_new0(uint8_t, resultlen); + + hmac = qcrypto_hmac_new(data->alg, (const uint8_t *)KEY, + strlen(KEY), &err); + g_assert(err == NULL); + g_assert(hmac != NULL); + + ret = qcrypto_hmac_bytes(hmac, (const char *)INPUT_TEXT, + strlen(INPUT_TEXT), &result, + &resultlen, &err); + g_assert(err == NULL); + g_assert(ret == 0); + + exp_output = data->hex_digest; + for (j = 0; j < resultlen; j++) { + g_assert(exp_output[j * 2] == hex[(result[j] >> 4) & 0xf]); + g_assert(exp_output[j * 2 + 1] == hex[result[j] & 0xf]); + } + + qcrypto_hmac_free(hmac); + + g_free(result); + } +} + +static void test_hmac_iov(void) +{ + size_t i; + + for (i = 0; i < G_N_ELEMENTS(test_data); i++) { + QCryptoHmacTestData *data = &test_data[i]; + QCryptoHmac *hmac = NULL; + uint8_t *result = NULL; + size_t resultlen = 0; + Error *err = NULL; + const char *exp_output = NULL; + int ret; + size_t j; + struct iovec iov[3] = { + { .iov_base = (char *)INPUT_TEXT1, .iov_len = strlen(INPUT_TEXT1) }, + { .iov_base = (char *)INPUT_TEXT2, .iov_len = strlen(INPUT_TEXT2) }, + { .iov_base = (char *)INPUT_TEXT3, .iov_len = strlen(INPUT_TEXT3) }, + }; + + if (!qcrypto_hmac_supports(data->alg)) { + return; + } + + exp_output = data->hex_digest; + + hmac = qcrypto_hmac_new(data->alg, (const uint8_t *)KEY, + strlen(KEY), &err); + g_assert(err == NULL); + g_assert(hmac != NULL); + + ret = qcrypto_hmac_bytesv(hmac, iov, 3, &result, + &resultlen, &err); + g_assert(err == NULL); + g_assert(ret == 0); + + for (j = 0; j < resultlen; j++) { + g_assert(exp_output[j * 2] == hex[(result[j] >> 4) & 0xf]); + g_assert(exp_output[j * 2 + 1] == hex[result[j] & 0xf]); + } + + qcrypto_hmac_free(hmac); + + g_free(result); + } +} + +static void test_hmac_digest(void) +{ + size_t i; + + for (i = 0; i < G_N_ELEMENTS(test_data); i++) { + QCryptoHmacTestData *data = &test_data[i]; + QCryptoHmac *hmac = NULL; + uint8_t *result = NULL; + Error *err = NULL; + const char *exp_output = NULL; + int ret; + + if (!qcrypto_hmac_supports(data->alg)) { + return; + } + + exp_output = data->hex_digest; + + hmac = qcrypto_hmac_new(data->alg, (const uint8_t *)KEY, + strlen(KEY), &err); + g_assert(err == NULL); + g_assert(hmac != NULL); + + ret = qcrypto_hmac_digest(hmac, (const char *)INPUT_TEXT, + strlen(INPUT_TEXT), (char **)&result, + &err); + g_assert(err == NULL); + g_assert(ret == 0); + + g_assert_cmpstr((const char *)result, ==, exp_output); + + qcrypto_hmac_free(hmac); + + g_free(result); + } +} + +int main(int argc, char **argv) +{ + g_test_init(&argc, &argv, NULL); + + g_assert(qcrypto_init(NULL) == 0); + + g_test_add_func("/crypto/hmac/iov", test_hmac_iov); + g_test_add_func("/crypto/hmac/alloc", test_hmac_alloc); + g_test_add_func("/crypto/hmac/prealloc", test_hmac_prealloc); + g_test_add_func("/crypto/hmac/digest", test_hmac_digest); + + return g_test_run(); +} |