summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore4
-rw-r--r--MAINTAINERS48
-rw-r--r--Makefile9
-rw-r--r--Makefile.objs11
-rw-r--r--Makefile.target5
-rw-r--r--VERSION2
-rwxr-xr-xconfigure19
-rw-r--r--crypto/Makefile.objs4
-rw-r--r--crypto/cipher-gcrypt.c6
-rw-r--r--crypto/cipher-nettle.c42
-rw-r--r--crypto/cipher.c7
-rw-r--r--crypto/hmac-gcrypt.c152
-rw-r--r--crypto/hmac-glib.c166
-rw-r--r--crypto/hmac-nettle.c175
-rw-r--r--crypto/hmac.c72
-rw-r--r--crypto/hmac.h166
-rw-r--r--disas/cris.c4
-rw-r--r--disas/m68k.c8
-rw-r--r--exec.c687
-rw-r--r--hw/alpha/alpha_sys.h2
-rw-r--r--hw/arm/aspeed.c70
-rw-r--r--hw/arm/aspeed_soc.c95
-rw-r--r--hw/arm/pxa2xx.c9
-rw-r--r--hw/arm/strongarm.h2
-rw-r--r--hw/arm/tosa.c7
-rw-r--r--hw/arm/virt-acpi-build.c2
-rw-r--r--hw/arm/virt.c19
-rw-r--r--hw/arm/z2.c7
-rw-r--r--hw/block/m25p80.c1
-rw-r--r--hw/block/pflash_cfi01.c13
-rw-r--r--hw/block/pflash_cfi02.c13
-rw-r--r--hw/char/cadence_uart.c14
-rw-r--r--hw/i2c/core.c6
-rw-r--r--hw/i386/acpi-build.c2
-rw-r--r--hw/i386/kvm/apic.c2
-rw-r--r--hw/i386/kvm/clock.c142
-rw-r--r--hw/i386/multiboot.c20
-rw-r--r--hw/i386/pc.c68
-rw-r--r--hw/i386/pc_piix.c2
-rw-r--r--hw/i386/pc_q35.c39
-rw-r--r--hw/intc/arm_gicv3.c5
-rw-r--r--hw/intc/arm_gicv3_common.c3
-rw-r--r--hw/intc/arm_gicv3_cpuif.c13
-rw-r--r--hw/intc/ioapic.c2
-rw-r--r--hw/misc/aspeed_scu.c4
-rw-r--r--hw/misc/aspeed_sdmc.c3
-rw-r--r--hw/misc/hyperv_testdev.c2
-rw-r--r--hw/ppc/fdt.c2
-rw-r--r--hw/ppc/pnv.c2
-rw-r--r--hw/ppc/pnv_core.c2
-rw-r--r--hw/ppc/pnv_lpc.c2
-rw-r--r--hw/ppc/pnv_xscom.c2
-rw-r--r--hw/ppc/spapr_cpu_core.c6
-rw-r--r--hw/scsi/scsi-disk.c9
-rw-r--r--hw/scsi/virtio-scsi.c27
-rw-r--r--hw/sh4/shix.c2
-rw-r--r--hw/ssi/aspeed_smc.c17
-rw-r--r--hw/timer/ds1338.c6
-rw-r--r--hw/watchdog/wdt_i6300esb.c9
-rw-r--r--include/block/aio.h4
-rw-r--r--include/exec/cpu-all.h23
-rw-r--r--include/exec/cpu-common.h15
-rw-r--r--include/exec/memory.h166
-rw-r--r--include/hw/arm/arm.h2
-rw-r--r--include/hw/arm/aspeed_soc.h4
-rw-r--r--include/hw/arm/exynos4210.h2
-rw-r--r--include/hw/arm/omap.h2
-rw-r--r--include/hw/arm/pxa.h2
-rw-r--r--include/hw/compat.h3
-rw-r--r--include/hw/i386/pc.h12
-rw-r--r--include/hw/m68k/mcf.h2
-rw-r--r--include/hw/mips/cpudevs.h2
-rw-r--r--include/hw/misc/aspeed_scu.h1
-rw-r--r--include/hw/ppc/fdt.h2
-rw-r--r--include/hw/ppc/ppc.h2
-rw-r--r--include/hw/ppc/spapr_cpu_core.h2
-rw-r--r--include/hw/sh4/sh.h2
-rw-r--r--include/qemu/main-loop.h4
-rw-r--r--include/qemu/timer.h2
-rw-r--r--include/qemu/typedefs.h1
-rw-r--r--include/standard-headers/linux/input.h1
-rw-r--r--include/standard-headers/linux/pci_regs.h15
-rw-r--r--linux-headers/asm-arm/kvm.h7
-rw-r--r--linux-headers/asm-x86/unistd_32.h3
-rw-r--r--linux-headers/asm-x86/unistd_64.h3
-rw-r--r--linux-headers/asm-x86/unistd_x32.h3
-rw-r--r--linux-headers/linux/kvm.h7
-rw-r--r--linux-user/main.c7
-rw-r--r--memory_ldst.inc.c709
-rw-r--r--qapi/crypto.json3
-rw-r--r--qemu-timer.c20
-rw-r--r--rules.mak26
-rw-r--r--scripts/analyze-inclusions8
-rw-r--r--slirp/dhcpv6.c2
-rw-r--r--slirp/ip6_icmp.c2
-rw-r--r--slirp/slirp.c2
-rw-r--r--slirp/slirp.h5
-rw-r--r--slirp/tcp_input.c16
-rw-r--r--slirp/tcp_output.c6
-rw-r--r--slirp/tcp_timer.c2
-rw-r--r--slirp/tcpip.h2
-rw-r--r--slirp/tftp.c26
-rw-r--r--slirp/tftp.h8
-rw-r--r--target-m68k/op_helper.c229
-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.c471
-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-xtarget/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.c75
-rw-r--r--tests/Makefile.include2
-rw-r--r--tests/tcg/xtensa/Makefile2
-rw-r--r--tests/test-crypto-cipher.c119
-rw-r--r--tests/test-crypto-hmac.c266
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):
----------------------
diff --git a/Makefile b/Makefile
index 474cc5e66a..214cbad35d 100644
--- a/Makefile
+++ b/Makefile
@@ -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
diff --git a/VERSION b/VERSION
index e3965f4029..e65e2ce44f 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-2.7.94
+2.8.50
diff --git a/configure b/configure
index 3770d7c263..218df87d21 100755
--- a/configure
+++ b/configure
@@ -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);
diff --git a/exec.c b/exec.c
index 08c558eecf..8d4bb0e8c1 100644
--- a/exec.c
+++ b/exec.c
@@ -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, &sectors) >= 0) {
+ if (arg->idebus[0] && ide_get_geometry(arg->idebus[0], 0,
+ &cylinders, &heads, &sectors) >= 0) {
cmos_init_hd(s, 0x19, 0x1b, cylinders, heads, sectors);
val |= 0xf0;
}
- if (ide_get_geometry(arg->idebus[0], 1,
- &cylinders, &heads, &sectors) >= 0) {
+ if (arg->idebus[0] && ide_get_geometry(arg->idebus[0], 1,
+ &cylinders, &heads, &sectors) >= 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, &sectors) >= 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;
}
diff --git a/rules.mak b/rules.mak
index f4839d2c38..ce9e7e6ffe 100644
--- a/rules.mak
+++ b/rules.mak
@@ -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();
+}