aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.cirrus.yml4
-rw-r--r--.gitlab-ci.d/containers.yml76
-rw-r--r--.gitlab-ci.yml113
-rw-r--r--MAINTAINERS60
-rw-r--r--Makefile2
-rw-r--r--block.c1
-rw-r--r--block/backup.c2
-rw-r--r--block/copy-on-read.c33
-rw-r--r--block/io.c11
-rw-r--r--block/meson.build1
-rw-r--r--block/mirror.c6
-rw-r--r--block/monitor/block-hmp-cmds.c31
-rw-r--r--block/rbd.c32
-rw-r--r--block/sheepdog.c3356
-rw-r--r--block/trace-events14
-rw-r--r--block/write-threshold.c91
-rwxr-xr-xconfigure24
-rw-r--r--contrib/vhost-user-input/main.c8
-rw-r--r--default-configs/devices/lm32-softmmu.mak12
-rw-r--r--default-configs/devices/moxie-softmmu.mak5
-rw-r--r--default-configs/devices/unicore32-softmmu.mak6
-rw-r--r--default-configs/targets/lm32-softmmu.mak2
-rw-r--r--default-configs/targets/moxie-softmmu.mak2
-rw-r--r--default-configs/targets/unicore32-softmmu.mak1
-rw-r--r--disas/lm32.c361
-rw-r--r--disas/meson.build2
-rw-r--r--disas/moxie.c360
-rw-r--r--docs/_templates/editpage.html5
-rw-r--r--docs/conf.py52
-rw-r--r--docs/devel/_templates/editpage.html5
-rw-r--r--docs/devel/qgraph.rst58
-rw-r--r--docs/interop/_templates/editpage.html5
-rw-r--r--docs/meson.build5
-rw-r--r--docs/specs/_templates/editpage.html5
-rw-r--r--docs/sphinx-static/theme_overrides.css161
-rw-r--r--docs/system/_templates/editpage.html5
-rw-r--r--docs/system/deprecated.rst33
-rw-r--r--docs/system/device-url-syntax.rst.inc18
-rw-r--r--docs/system/qemu-block-drivers.rst.inc69
-rw-r--r--docs/system/removed-features.rst28
-rw-r--r--docs/tools/_templates/editpage.html5
-rw-r--r--docs/tools/qemu-img.rst31
-rw-r--r--docs/user/_templates/editpage.html5
-rw-r--r--fpu/softfloat-specialize.c.inc11
-rw-r--r--hw/Kconfig3
-rw-r--r--hw/acpi/aml-build.c15
-rw-r--r--hw/arm/virt.c7
-rw-r--r--hw/audio/meson.build1
-rw-r--r--hw/audio/milkymist-ac97.c360
-rw-r--r--hw/audio/trace-events12
-rw-r--r--hw/block/dataplane/virtio-blk.c36
-rw-r--r--hw/block/pflash_cfi02.c10
-rw-r--r--hw/char/lm32_juart.c166
-rw-r--r--hw/char/lm32_uart.c314
-rw-r--r--hw/char/meson.build3
-rw-r--r--hw/char/milkymist-uart.c258
-rw-r--r--hw/char/trace-events17
-rw-r--r--hw/core/numa.c41
-rw-r--r--hw/display/Kconfig4
-rw-r--r--hw/display/meson.build2
-rw-r--r--hw/display/milkymist-tmu2.c551
-rw-r--r--hw/display/milkymist-vgafb.c360
-rw-r--r--hw/display/milkymist-vgafb_template.h74
-rw-r--r--hw/display/trace-events10
-rw-r--r--hw/dma/meson.build1
-rw-r--r--hw/dma/puv3_dma.c119
-rw-r--r--hw/gpio/meson.build1
-rw-r--r--hw/gpio/puv3_gpio.c154
-rw-r--r--hw/i2c/Kconfig4
-rw-r--r--hw/i2c/core.c55
-rw-r--r--hw/i2c/i2c_mux_pca954x.c290
-rw-r--r--hw/i2c/meson.build1
-rw-r--r--hw/i2c/trace-events5
-rw-r--r--hw/i386/acpi-build.c8
-rw-r--r--hw/i386/amd_iommu.c10
-rw-r--r--hw/i386/fw_cfg.c4
-rw-r--r--hw/i386/xen/xen-mapcache.c7
-rw-r--r--hw/input/meson.build1
-rw-r--r--hw/input/milkymist-softusb.c319
-rw-r--r--hw/input/trace-events7
-rw-r--r--hw/input/virtio-input-host.c5
-rw-r--r--hw/intc/lm32_pic.c195
-rw-r--r--hw/intc/meson.build2
-rw-r--r--hw/intc/puv3_intc.c147
-rw-r--r--hw/intc/trace-events9
-rw-r--r--hw/lm32/Kconfig18
-rw-r--r--hw/lm32/lm32.h48
-rw-r--r--hw/lm32/lm32_boards.c332
-rw-r--r--hw/lm32/lm32_hwsetup.h179
-rw-r--r--hw/lm32/meson.build6
-rw-r--r--hw/lm32/milkymist-hw.h133
-rw-r--r--hw/lm32/milkymist.c249
-rw-r--r--hw/mem/pc-dimm.c33
-rw-r--r--hw/meson.build3
-rw-r--r--hw/misc/meson.build4
-rw-r--r--hw/misc/milkymist-hpdmc.c172
-rw-r--r--hw/misc/milkymist-pfpu.c548
-rw-r--r--hw/misc/puv3_pm.c159
-rw-r--r--hw/misc/trace-events10
-rw-r--r--hw/moxie/Kconfig3
-rw-r--r--hw/moxie/meson.build4
-rw-r--r--hw/moxie/moxiesim.c155
-rw-r--r--hw/net/meson.build1
-rw-r--r--hw/net/milkymist-minimac2.c547
-rw-r--r--hw/net/trace-events12
-rw-r--r--hw/scsi/virtio-scsi-dataplane.c56
-rw-r--r--hw/sd/meson.build1
-rw-r--r--hw/sd/milkymist-memcard.c335
-rw-r--r--hw/sd/trace-events4
-rw-r--r--hw/smbios/smbios.c124
-rw-r--r--hw/timer/lm32_timer.c249
-rw-r--r--hw/timer/meson.build3
-rw-r--r--hw/timer/milkymist-sysctl.c361
-rw-r--r--hw/timer/puv3_ost.c166
-rw-r--r--hw/timer/trace-events17
-rw-r--r--hw/unicore32/Kconfig5
-rw-r--r--hw/unicore32/meson.build5
-rw-r--r--hw/unicore32/puv3.c145
-rw-r--r--hw/usb/quirks-ftdi-ids.h6
-rw-r--r--hw/usb/quirks.h1
-rw-r--r--hw/virtio/vhost-vdpa.c4
-rw-r--r--hw/virtio/virtio-balloon.c4
-rw-r--r--hw/virtio/virtio-mem.c3
-rw-r--r--hw/virtio/virtio-mmio.c11
-rw-r--r--include/block/block_int.h15
-rw-r--r--include/block/write-threshold.h27
-rw-r--r--include/disas/dis-asm.h4
-rw-r--r--include/elf.h6
-rw-r--r--include/exec/cpu-common.h1
-rw-r--r--include/exec/memory.h10
-rw-r--r--include/exec/poison.h11
-rw-r--r--include/exec/ramblock.h10
-rw-r--r--include/exec/ramlist.h13
-rw-r--r--include/hw/char/lm32_juart.h13
-rw-r--r--include/hw/display/milkymist_tmu2.h42
-rw-r--r--include/hw/elf_ops.h8
-rw-r--r--include/hw/firmware/smbios.h14
-rw-r--r--include/hw/i2c/i2c.h17
-rw-r--r--include/hw/i2c/i2c_mux_pca954x.h19
-rw-r--r--include/hw/lm32/lm32_pic.h10
-rw-r--r--include/hw/mem/pc-dimm.h5
-rw-r--r--include/hw/unicore32/puv3.h40
-rw-r--r--include/hw/virtio/vhost-vdpa.h2
-rw-r--r--include/hw/virtio/virtio-mmio.h5
-rw-r--r--include/migration/misc.h1
-rw-r--r--include/qemu/job.h2
-rw-r--r--include/sysemu/arch_init.h3
-rw-r--r--include/sysemu/hax.h4
-rw-r--r--include/sysemu/hvf.h4
-rw-r--r--include/sysemu/whpx.h4
-rw-r--r--job.c2
-rw-r--r--meson.build5
-rw-r--r--migration/meson.build3
-rw-r--r--migration/migration.c53
-rw-r--r--migration/migration.h3
-rw-r--r--migration/multifd.c2
-rw-r--r--migration/postcopy-ram.c15
-rw-r--r--migration/ram.c246
-rw-r--r--migration/target.c25
-rw-r--r--monitor/hmp-cmds.c2
-rw-r--r--monitor/qmp.c40
-rw-r--r--pc-bios/s390-ccw/helper.h2
-rw-r--r--pc-bios/s390-ccw/jump2ipl.c4
-rw-r--r--pc-bios/s390-ccw/menu.c8
-rw-r--r--pc-bios/s390-ccw/virtio.c2
-rw-r--r--qapi/block-core.json93
-rw-r--r--qapi/machine.json6
-rw-r--r--qapi/migration.json6
-rw-r--r--qapi/misc-target.json2
-rw-r--r--qapi/transaction.json8
-rw-r--r--qemu-io-cmds.c8
-rw-r--r--qemu-io.c17
-rw-r--r--qemu-options.hx34
-rwxr-xr-xscripts/checkpatch.pl1
-rw-r--r--softmmu/arch_init.c6
-rw-r--r--softmmu/physmem.c26
-rw-r--r--target/i386/hax/hax-mem.c5
-rw-r--r--target/i386/sev.c18
-rw-r--r--target/lm32/README45
-rw-r--r--target/lm32/TODO1
-rw-r--r--target/lm32/cpu-param.h17
-rw-r--r--target/lm32/cpu-qom.h48
-rw-r--r--target/lm32/cpu.c274
-rw-r--r--target/lm32/cpu.h262
-rw-r--r--target/lm32/gdbstub.c92
-rw-r--r--target/lm32/helper.c224
-rw-r--r--target/lm32/helper.h14
-rw-r--r--target/lm32/lm32-semi.c211
-rw-r--r--target/lm32/machine.c33
-rw-r--r--target/lm32/meson.build15
-rw-r--r--target/lm32/op_helper.c148
-rw-r--r--target/lm32/translate.c1237
-rw-r--r--target/meson.build3
-rw-r--r--target/moxie/cpu-param.h17
-rw-r--r--target/moxie/cpu.c161
-rw-r--r--target/moxie/cpu.h123
-rw-r--r--target/moxie/helper.c120
-rw-r--r--target/moxie/helper.h5
-rw-r--r--target/moxie/machine.c19
-rw-r--r--target/moxie/machine.h1
-rw-r--r--target/moxie/meson.build14
-rw-r--r--target/moxie/mmu.c32
-rw-r--r--target/moxie/mmu.h19
-rw-r--r--target/moxie/translate.c892
-rw-r--r--target/unicore32/cpu-param.h17
-rw-r--r--target/unicore32/cpu-qom.h37
-rw-r--r--target/unicore32/cpu.c174
-rw-r--r--target/unicore32/cpu.h168
-rw-r--r--target/unicore32/helper.c183
-rw-r--r--target/unicore32/helper.h62
-rw-r--r--target/unicore32/meson.build14
-rw-r--r--target/unicore32/op_helper.c244
-rw-r--r--target/unicore32/softmmu.c280
-rw-r--r--target/unicore32/translate.c2083
-rw-r--r--target/unicore32/ucf64_helper.c324
-rw-r--r--tests/docker/dockerfiles/alpine.docker2
-rw-r--r--tests/docker/dockerfiles/debian10.docker1
-rw-r--r--tests/docker/dockerfiles/fedora-i386-cross.docker1
-rw-r--r--tests/docker/dockerfiles/fedora-win32-cross.docker1
-rw-r--r--tests/docker/dockerfiles/fedora-win64-cross.docker1
-rw-r--r--tests/docker/dockerfiles/fedora.docker1
-rw-r--r--tests/docker/dockerfiles/opensuse-leap.docker1
-rw-r--r--tests/docker/dockerfiles/ubuntu.docker1
-rw-r--r--tests/docker/dockerfiles/ubuntu1804.docker1
-rw-r--r--tests/docker/dockerfiles/ubuntu2004.docker1
-rw-r--r--tests/migration/guestperf/comparison.py14
-rw-r--r--tests/migration/guestperf/engine.py16
-rw-r--r--tests/migration/guestperf/scenario.py12
-rw-r--r--tests/migration/guestperf/shell.py10
-rwxr-xr-xtests/qemu-iotests/0055
-rwxr-xr-xtests/qemu-iotests/0252
-rwxr-xr-xtests/qemu-iotests/2314
-rw-r--r--tests/qemu-iotests/231.out7
-rw-r--r--tests/qemu-iotests/240.out8
-rw-r--r--tests/qemu-iotests/245.out8
-rwxr-xr-xtests/qemu-iotests/2642
-rw-r--r--tests/qemu-iotests/295.out6
-rw-r--r--tests/qemu-iotests/296.out8
-rwxr-xr-xtests/qemu-iotests/check22
-rw-r--r--tests/qemu-iotests/common.rc4
-rw-r--r--tests/qemu-iotests/iotests.py145
-rw-r--r--tests/qemu-iotests/pylintrc3
-rw-r--r--tests/qemu-iotests/testenv.py22
-rw-r--r--tests/qemu-iotests/testrunner.py37
-rw-r--r--tests/qtest/ahci-test.c4
-rw-r--r--tests/qtest/boot-serial-test.c8
-rw-r--r--tests/qtest/ipmi-bt-test.c6
-rw-r--r--tests/qtest/ipmi-kcs-test.c3
-rw-r--r--tests/qtest/libqos/qgraph.c2
-rw-r--r--tests/qtest/libqtest.c9
-rw-r--r--tests/qtest/machine-none-test.c3
-rw-r--r--tests/qtest/meson.build2
-rw-r--r--tests/qtest/migration-test.c75
-rw-r--r--tests/qtest/npcm7xx_pwm-test.c4
-rw-r--r--tests/qtest/rtc-test.c6
-rw-r--r--tests/qtest/tpm-util.c4
-rw-r--r--tests/tcg/README6
-rwxr-xr-xtests/tcg/configure.sh2
-rw-r--r--tests/tcg/lm32/Makefile106
-rw-r--r--tests/tcg/lm32/crt.S84
-rw-r--r--tests/tcg/lm32/helper.S65
-rw-r--r--tests/tcg/lm32/linker.ld55
-rw-r--r--tests/tcg/lm32/macros.inc90
-rw-r--r--tests/tcg/lm32/test_add.S75
-rw-r--r--tests/tcg/lm32/test_addi.S56
-rw-r--r--tests/tcg/lm32/test_and.S45
-rw-r--r--tests/tcg/lm32/test_andhi.S35
-rw-r--r--tests/tcg/lm32/test_andi.S35
-rw-r--r--tests/tcg/lm32/test_b.S13
-rw-r--r--tests/tcg/lm32/test_be.S48
-rw-r--r--tests/tcg/lm32/test_bg.S78
-rw-r--r--tests/tcg/lm32/test_bge.S78
-rw-r--r--tests/tcg/lm32/test_bgeu.S78
-rw-r--r--tests/tcg/lm32/test_bgu.S78
-rw-r--r--tests/tcg/lm32/test_bi.S23
-rw-r--r--tests/tcg/lm32/test_bne.S48
-rw-r--r--tests/tcg/lm32/test_break.S20
-rw-r--r--tests/tcg/lm32/test_bret.S38
-rw-r--r--tests/tcg/lm32/test_call.S16
-rw-r--r--tests/tcg/lm32/test_calli.S15
-rw-r--r--tests/tcg/lm32/test_cmpe.S40
-rw-r--r--tests/tcg/lm32/test_cmpei.S35
-rw-r--r--tests/tcg/lm32/test_cmpg.S64
-rw-r--r--tests/tcg/lm32/test_cmpge.S64
-rw-r--r--tests/tcg/lm32/test_cmpgei.S70
-rw-r--r--tests/tcg/lm32/test_cmpgeu.S64
-rw-r--r--tests/tcg/lm32/test_cmpgeui.S70
-rw-r--r--tests/tcg/lm32/test_cmpgi.S70
-rw-r--r--tests/tcg/lm32/test_cmpgu.S64
-rw-r--r--tests/tcg/lm32/test_cmpgui.S70
-rw-r--r--tests/tcg/lm32/test_cmpne.S40
-rw-r--r--tests/tcg/lm32/test_cmpnei.S35
-rw-r--r--tests/tcg/lm32/test_divu.S29
-rw-r--r--tests/tcg/lm32/test_eret.S38
-rw-r--r--tests/tcg/lm32/test_lb.S49
-rw-r--r--tests/tcg/lm32/test_lbu.S49
-rw-r--r--tests/tcg/lm32/test_lh.S49
-rw-r--r--tests/tcg/lm32/test_lhu.S49
-rw-r--r--tests/tcg/lm32/test_lw.S32
-rw-r--r--tests/tcg/lm32/test_modu.S35
-rw-r--r--tests/tcg/lm32/test_mul.S70
-rw-r--r--tests/tcg/lm32/test_muli.S45
-rw-r--r--tests/tcg/lm32/test_nor.S51
-rw-r--r--tests/tcg/lm32/test_nori.S35
-rw-r--r--tests/tcg/lm32/test_or.S51
-rw-r--r--tests/tcg/lm32/test_orhi.S35
-rw-r--r--tests/tcg/lm32/test_ori.S35
-rw-r--r--tests/tcg/lm32/test_ret.S14
-rw-r--r--tests/tcg/lm32/test_sb.S32
-rw-r--r--tests/tcg/lm32/test_scall.S24
-rw-r--r--tests/tcg/lm32/test_sextb.S20
-rw-r--r--tests/tcg/lm32/test_sexth.S20
-rw-r--r--tests/tcg/lm32/test_sh.S32
-rw-r--r--tests/tcg/lm32/test_sl.S45
-rw-r--r--tests/tcg/lm32/test_sli.S30
-rw-r--r--tests/tcg/lm32/test_sr.S57
-rw-r--r--tests/tcg/lm32/test_sri.S40
-rw-r--r--tests/tcg/lm32/test_sru.S57
-rw-r--r--tests/tcg/lm32/test_srui.S40
-rw-r--r--tests/tcg/lm32/test_sub.S75
-rw-r--r--tests/tcg/lm32/test_sw.S38
-rw-r--r--tests/tcg/lm32/test_xnor.S51
-rw-r--r--tests/tcg/lm32/test_xnori.S35
-rw-r--r--tests/tcg/lm32/test_xor.S51
-rw-r--r--tests/tcg/lm32/test_xori.S35
-rw-r--r--tests/unit/test-write-threshold.c90
-rw-r--r--util/compatfd.c8
-rw-r--r--util/vfio-helpers.c41
328 files changed, 1874 insertions, 23324 deletions
diff --git a/.cirrus.yml b/.cirrus.yml
index f53c519447..f4bf49b704 100644
--- a/.cirrus.yml
+++ b/.cirrus.yml
@@ -67,7 +67,7 @@ windows_msys2_task:
CIRRUS_SHELL: powershell
MSYS: winsymlinks:nativestrict
MSYSTEM: MINGW64
- MSYS2_URL: https://github.com/msys2/msys2-installer/releases/download/2021-01-05/msys2-base-x86_64-20210105.sfx.exe
+ MSYS2_URL: https://github.com/msys2/msys2-installer/releases/download/2021-04-19/msys2-base-x86_64-20210419.sfx.exe
MSYS2_FINGERPRINT: 0
MSYS2_PACKAGES: "
diffutils git grep make pkg-config sed
@@ -130,7 +130,7 @@ windows_msys2_task:
taskkill /F /FI "MODULES eq msys-2.0.dll"
tasklist
C:\tools\msys64\usr\bin\bash.exe -lc "mv -f /etc/pacman.conf.pacnew /etc/pacman.conf || true"
- C:\tools\msys64\usr\bin\bash.exe -lc "pacman --noconfirm -Suu --overwrite=*"
+ C:\tools\msys64\usr\bin\bash.exe -lc "pacman --noconfirm -Syuu --overwrite=*"
Write-Output "Core install time taken: $((Get-Date).Subtract($start_time))"
$start_time = Get-Date
diff --git a/.gitlab-ci.d/containers.yml b/.gitlab-ci.d/containers.yml
index 33e4046e23..4ef76d1f54 100644
--- a/.gitlab-ci.d/containers.yml
+++ b/.gitlab-ci.d/containers.yml
@@ -1,4 +1,4 @@
-.container_job_template: &container_job_definition
+.container_job_template:
image: docker:stable
stage: containers
services:
@@ -22,230 +22,230 @@
- docker logout
amd64-alpine-container:
- <<: *container_job_definition
+ extends: .container_job_template
variables:
NAME: alpine
amd64-centos7-container:
- <<: *container_job_definition
+ extends: .container_job_template
variables:
NAME: centos7
amd64-centos8-container:
- <<: *container_job_definition
+ extends: .container_job_template
variables:
NAME: centos8
amd64-debian10-container:
- <<: *container_job_definition
+ extends: .container_job_template
variables:
NAME: debian10
amd64-debian11-container:
- <<: *container_job_definition
+ extends: .container_job_template
variables:
NAME: debian11
alpha-debian-cross-container:
- <<: *container_job_definition
+ extends: .container_job_template
stage: containers-layer2
needs: ['amd64-debian10-container']
variables:
NAME: debian-alpha-cross
amd64-debian-cross-container:
- <<: *container_job_definition
+ extends: .container_job_template
stage: containers-layer2
needs: ['amd64-debian10-container']
variables:
NAME: debian-amd64-cross
amd64-debian-user-cross-container:
- <<: *container_job_definition
+ extends: .container_job_template
stage: containers-layer2
needs: ['amd64-debian10-container']
variables:
NAME: debian-all-test-cross
amd64-debian-container:
- <<: *container_job_definition
+ extends: .container_job_template
stage: containers-layer2
needs: ['amd64-debian10-container']
variables:
NAME: debian-amd64
arm64-debian-cross-container:
- <<: *container_job_definition
+ extends: .container_job_template
stage: containers-layer2
needs: ['amd64-debian10-container']
variables:
NAME: debian-arm64-cross
arm64-test-debian-cross-container:
- <<: *container_job_definition
+ extends: .container_job_template
stage: containers-layer2
needs: ['amd64-debian11-container']
variables:
NAME: debian-arm64-test-cross
armel-debian-cross-container:
- <<: *container_job_definition
+ extends: .container_job_template
stage: containers-layer2
needs: ['amd64-debian10-container']
variables:
NAME: debian-armel-cross
armhf-debian-cross-container:
- <<: *container_job_definition
+ extends: .container_job_template
stage: containers-layer2
needs: ['amd64-debian10-container']
variables:
NAME: debian-armhf-cross
hppa-debian-cross-container:
- <<: *container_job_definition
+ extends: .container_job_template
stage: containers-layer2
needs: ['amd64-debian10-container']
variables:
NAME: debian-hppa-cross
m68k-debian-cross-container:
- <<: *container_job_definition
+ extends: .container_job_template
stage: containers-layer2
needs: ['amd64-debian10-container']
variables:
NAME: debian-m68k-cross
mips64-debian-cross-container:
- <<: *container_job_definition
+ extends: .container_job_template
stage: containers-layer2
needs: ['amd64-debian10-container']
variables:
NAME: debian-mips64-cross
mips64el-debian-cross-container:
- <<: *container_job_definition
+ extends: .container_job_template
stage: containers-layer2
needs: ['amd64-debian10-container']
variables:
NAME: debian-mips64el-cross
mips-debian-cross-container:
- <<: *container_job_definition
+ extends: .container_job_template
stage: containers-layer2
needs: ['amd64-debian10-container']
variables:
NAME: debian-mips-cross
mipsel-debian-cross-container:
- <<: *container_job_definition
+ extends: .container_job_template
stage: containers-layer2
needs: ['amd64-debian10-container']
variables:
NAME: debian-mipsel-cross
powerpc-debian-cross-container:
- <<: *container_job_definition
+ extends: .container_job_template
stage: containers-layer2
needs: ['amd64-debian10-container']
variables:
NAME: debian-powerpc-cross
ppc64-debian-cross-container:
- <<: *container_job_definition
+ extends: .container_job_template
stage: containers-layer2
needs: ['amd64-debian10-container']
variables:
NAME: debian-ppc64-cross
ppc64el-debian-cross-container:
- <<: *container_job_definition
+ extends: .container_job_template
stage: containers-layer2
needs: ['amd64-debian10-container']
variables:
NAME: debian-ppc64el-cross
riscv64-debian-cross-container:
- <<: *container_job_definition
+ extends: .container_job_template
stage: containers-layer2
needs: ['amd64-debian10-container']
variables:
NAME: debian-riscv64-cross
s390x-debian-cross-container:
- <<: *container_job_definition
+ extends: .container_job_template
stage: containers-layer2
needs: ['amd64-debian10-container']
variables:
NAME: debian-s390x-cross
sh4-debian-cross-container:
- <<: *container_job_definition
+ extends: .container_job_template
stage: containers-layer2
needs: ['amd64-debian10-container']
variables:
NAME: debian-sh4-cross
sparc64-debian-cross-container:
- <<: *container_job_definition
+ extends: .container_job_template
stage: containers-layer2
needs: ['amd64-debian10-container']
variables:
NAME: debian-sparc64-cross
tricore-debian-cross-container:
- <<: *container_job_definition
+ extends: .container_job_template
stage: containers-layer2
needs: ['amd64-debian10-container']
variables:
NAME: debian-tricore-cross
xtensa-debian-cross-container:
- <<: *container_job_definition
+ extends: .container_job_template
variables:
NAME: debian-xtensa-cross
cris-fedora-cross-container:
- <<: *container_job_definition
+ extends: .container_job_template
variables:
NAME: fedora-cris-cross
amd64-fedora-container:
- <<: *container_job_definition
+ extends: .container_job_template
variables:
NAME: fedora
i386-fedora-cross-container:
- <<: *container_job_definition
+ extends: .container_job_template
variables:
NAME: fedora-i386-cross
win32-fedora-cross-container:
- <<: *container_job_definition
+ extends: .container_job_template
variables:
NAME: fedora-win32-cross
win64-fedora-cross-container:
- <<: *container_job_definition
+ extends: .container_job_template
variables:
NAME: fedora-win64-cross
amd64-ubuntu1804-container:
- <<: *container_job_definition
+ extends: .container_job_template
variables:
NAME: ubuntu1804
amd64-ubuntu2004-container:
- <<: *container_job_definition
+ extends: .container_job_template
variables:
NAME: ubuntu2004
amd64-ubuntu-container:
- <<: *container_job_definition
+ extends: .container_job_template
variables:
NAME: ubuntu
amd64-opensuse-leap-container:
- <<: *container_job_definition
+ extends: .container_job_template
variables:
NAME: opensuse-leap
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index dcb6317aac..24f300aace 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -13,7 +13,7 @@ include:
- local: '/.gitlab-ci.d/containers.yml'
- local: '/.gitlab-ci.d/crossbuilds.yml'
-.native_build_job_template: &native_build_job_definition
+.native_build_job_template:
stage: build
image: $CI_REGISTRY_IMAGE/qemu/$IMAGE:latest
before_script:
@@ -41,7 +41,7 @@ include:
make -j"$JOBS" $MAKE_CHECK_ARGS ;
fi
-.native_test_job_template: &native_test_job_definition
+.native_test_job_template:
stage: test
image: $CI_REGISTRY_IMAGE/qemu/$IMAGE:latest
script:
@@ -83,13 +83,13 @@ include:
- du -chs ${CI_PROJECT_DIR}/avocado-cache
build-system-alpine:
- <<: *native_build_job_definition
+ extends: .native_build_job_template
needs:
- job: amd64-alpine-container
variables:
IMAGE: alpine
TARGETS: aarch64-softmmu alpha-softmmu cris-softmmu hppa-softmmu
- moxie-softmmu microblazeel-softmmu mips64el-softmmu
+ microblazeel-softmmu mips64el-softmmu
MAKE_CHECK_ARGS: check-build
CONFIGURE_ARGS: --enable-docs --enable-trace-backends=log,simple,syslog
artifacts:
@@ -99,7 +99,7 @@ build-system-alpine:
- build
check-system-alpine:
- <<: *native_test_job_definition
+ extends: .native_test_job_template
needs:
- job: build-system-alpine
artifacts: true
@@ -108,7 +108,7 @@ check-system-alpine:
MAKE_CHECK_ARGS: check
acceptance-system-alpine:
- <<: *native_test_job_definition
+ extends: .native_test_job_template
needs:
- job: build-system-alpine
artifacts: true
@@ -118,14 +118,14 @@ acceptance-system-alpine:
<<: *acceptance_definition
build-system-ubuntu:
- <<: *native_build_job_definition
+ extends: .native_build_job_template
needs:
job: amd64-ubuntu2004-container
variables:
IMAGE: ubuntu2004
CONFIGURE_ARGS: --enable-docs --enable-fdt=system --enable-slirp=system
TARGETS: aarch64-softmmu alpha-softmmu cris-softmmu hppa-softmmu
- moxie-softmmu microblazeel-softmmu mips64el-softmmu
+ microblazeel-softmmu mips64el-softmmu
MAKE_CHECK_ARGS: check-build
artifacts:
expire_in: 2 days
@@ -133,7 +133,7 @@ build-system-ubuntu:
- build
check-system-ubuntu:
- <<: *native_test_job_definition
+ extends: .native_test_job_template
needs:
- job: build-system-ubuntu
artifacts: true
@@ -142,7 +142,7 @@ check-system-ubuntu:
MAKE_CHECK_ARGS: check
acceptance-system-ubuntu:
- <<: *native_test_job_definition
+ extends: .native_test_job_template
needs:
- job: build-system-ubuntu
artifacts: true
@@ -152,7 +152,7 @@ acceptance-system-ubuntu:
<<: *acceptance_definition
build-system-debian:
- <<: *native_build_job_definition
+ extends: .native_build_job_template
needs:
job: amd64-debian-container
variables:
@@ -167,7 +167,7 @@ build-system-debian:
- build
check-system-debian:
- <<: *native_test_job_definition
+ extends: .native_test_job_template
needs:
- job: build-system-debian
artifacts: true
@@ -176,7 +176,7 @@ check-system-debian:
MAKE_CHECK_ARGS: check
acceptance-system-debian:
- <<: *native_test_job_definition
+ extends: .native_test_job_template
needs:
- job: build-system-debian
artifacts: true
@@ -186,7 +186,7 @@ acceptance-system-debian:
<<: *acceptance_definition
build-system-fedora:
- <<: *native_build_job_definition
+ extends: .native_build_job_template
needs:
job: amd64-fedora-container
variables:
@@ -202,7 +202,7 @@ build-system-fedora:
- build
check-system-fedora:
- <<: *native_test_job_definition
+ extends: .native_test_job_template
needs:
- job: build-system-fedora
artifacts: true
@@ -211,7 +211,7 @@ check-system-fedora:
MAKE_CHECK_ARGS: check
acceptance-system-fedora:
- <<: *native_test_job_definition
+ extends: .native_test_job_template
needs:
- job: build-system-fedora
artifacts: true
@@ -221,7 +221,7 @@ acceptance-system-fedora:
<<: *acceptance_definition
build-system-centos:
- <<: *native_build_job_definition
+ extends: .native_build_job_template
needs:
job: amd64-centos8-container
variables:
@@ -237,7 +237,7 @@ build-system-centos:
- build
check-system-centos:
- <<: *native_test_job_definition
+ extends: .native_test_job_template
needs:
- job: build-system-centos
artifacts: true
@@ -246,7 +246,7 @@ check-system-centos:
MAKE_CHECK_ARGS: check
acceptance-system-centos:
- <<: *native_test_job_definition
+ extends: .native_test_job_template
needs:
- job: build-system-centos
artifacts: true
@@ -256,7 +256,7 @@ acceptance-system-centos:
<<: *acceptance_definition
build-system-opensuse:
- <<: *native_build_job_definition
+ extends: .native_build_job_template
needs:
job: amd64-opensuse-leap-container
variables:
@@ -270,7 +270,7 @@ build-system-opensuse:
- build
check-system-opensuse:
- <<: *native_test_job_definition
+ extends: .native_test_job_template
needs:
- job: build-system-opensuse
artifacts: true
@@ -279,7 +279,7 @@ check-system-opensuse:
MAKE_CHECK_ARGS: check
acceptance-system-opensuse:
- <<: *native_test_job_definition
+ extends: .native_test_job_template
needs:
- job: build-system-opensuse
artifacts: true
@@ -290,7 +290,7 @@ acceptance-system-opensuse:
build-disabled:
- <<: *native_build_job_definition
+ extends: .native_build_job_template
needs:
job: amd64-fedora-container
variables:
@@ -342,7 +342,6 @@ build-disabled:
--disable-replication
--disable-sdl
--disable-seccomp
- --disable-sheepdog
--disable-slirp
--disable-smartcard
--disable-snappy
@@ -377,7 +376,7 @@ build-disabled:
# Also use a different coroutine implementation (which is only really of
# interest to KVM users, i.e. with TCG disabled)
build-tcg-disabled:
- <<: *native_build_job_definition
+ extends: .native_build_job_template
needs:
job: amd64-centos8-container
variables:
@@ -400,7 +399,7 @@ build-tcg-disabled:
260 261 262 263 264 270 272 273 277 279
build-user:
- <<: *native_build_job_definition
+ extends: .native_build_job_template
needs:
job: amd64-debian-user-cross-container
variables:
@@ -409,7 +408,7 @@ build-user:
MAKE_CHECK_ARGS: check-tcg
build-user-static:
- <<: *native_build_job_definition
+ extends: .native_build_job_template
needs:
job: amd64-debian-user-cross-container
variables:
@@ -419,7 +418,7 @@ build-user-static:
# Only build the softmmu targets we have check-tcg tests for
build-some-softmmu:
- <<: *native_build_job_definition
+ extends: .native_build_job_template
needs:
job: amd64-debian-user-cross-container
variables:
@@ -432,7 +431,7 @@ build-some-softmmu:
# we skip sparc64-linux-user until it has been fixed somewhat
# we skip cris-linux-user as it doesn't use the common run loop
build-user-plugins:
- <<: *native_build_job_definition
+ extends: .native_build_job_template
needs:
job: amd64-debian-user-cross-container
variables:
@@ -442,7 +441,7 @@ build-user-plugins:
timeout: 1h 30m
build-user-centos7:
- <<: *native_build_job_definition
+ extends: .native_build_job_template
needs:
job: amd64-centos7-container
variables:
@@ -451,7 +450,7 @@ build-user-centos7:
MAKE_CHECK_ARGS: check-tcg
build-some-softmmu-plugins:
- <<: *native_build_job_definition
+ extends: .native_build_job_template
needs:
job: amd64-debian-user-cross-container
variables:
@@ -461,7 +460,7 @@ build-some-softmmu-plugins:
MAKE_CHECK_ARGS: check-tcg
clang-system:
- <<: *native_build_job_definition
+ extends: .native_build_job_template
needs:
job: amd64-fedora-container
variables:
@@ -473,7 +472,7 @@ clang-system:
MAKE_CHECK_ARGS: check-qtest check-tcg
clang-user:
- <<: *native_build_job_definition
+ extends: .native_build_job_template
needs:
job: amd64-debian-user-cross-container
variables:
@@ -495,7 +494,7 @@ clang-user:
# Split in three sets of build/check/acceptance to limit the execution time of each
# job
build-cfi-aarch64:
- <<: *native_build_job_definition
+ extends: .native_build_job_template
needs:
- job: amd64-fedora-container
variables:
@@ -513,7 +512,7 @@ build-cfi-aarch64:
- build
check-cfi-aarch64:
- <<: *native_test_job_definition
+ extends: .native_test_job_template
needs:
- job: build-cfi-aarch64
artifacts: true
@@ -522,7 +521,7 @@ check-cfi-aarch64:
MAKE_CHECK_ARGS: check
acceptance-cfi-aarch64:
- <<: *native_test_job_definition
+ extends: .native_test_job_template
needs:
- job: build-cfi-aarch64
artifacts: true
@@ -532,7 +531,7 @@ acceptance-cfi-aarch64:
<<: *acceptance_definition
build-cfi-ppc64-s390x:
- <<: *native_build_job_definition
+ extends: .native_build_job_template
needs:
- job: amd64-fedora-container
variables:
@@ -550,7 +549,7 @@ build-cfi-ppc64-s390x:
- build
check-cfi-ppc64-s390x:
- <<: *native_test_job_definition
+ extends: .native_test_job_template
needs:
- job: build-cfi-ppc64-s390x
artifacts: true
@@ -559,7 +558,7 @@ check-cfi-ppc64-s390x:
MAKE_CHECK_ARGS: check
acceptance-cfi-ppc64-s390x:
- <<: *native_test_job_definition
+ extends: .native_test_job_template
needs:
- job: build-cfi-ppc64-s390x
artifacts: true
@@ -569,7 +568,7 @@ acceptance-cfi-ppc64-s390x:
<<: *acceptance_definition
build-cfi-x86_64:
- <<: *native_build_job_definition
+ extends: .native_build_job_template
needs:
- job: amd64-fedora-container
variables:
@@ -587,7 +586,7 @@ build-cfi-x86_64:
- build
check-cfi-x86_64:
- <<: *native_test_job_definition
+ extends: .native_test_job_template
needs:
- job: build-cfi-x86_64
artifacts: true
@@ -596,7 +595,7 @@ check-cfi-x86_64:
MAKE_CHECK_ARGS: check
acceptance-cfi-x86_64:
- <<: *native_test_job_definition
+ extends: .native_test_job_template
needs:
- job: build-cfi-x86_64
artifacts: true
@@ -606,7 +605,7 @@ acceptance-cfi-x86_64:
<<: *acceptance_definition
tsan-build:
- <<: *native_build_job_definition
+ extends: .native_build_job_template
needs:
job: amd64-ubuntu2004-container
variables:
@@ -618,14 +617,14 @@ tsan-build:
# These targets are on the way out
build-deprecated:
- <<: *native_build_job_definition
+ extends: .native_build_job_template
needs:
job: amd64-debian-user-cross-container
variables:
IMAGE: debian-all-test-cross
CONFIGURE_ARGS: --disable-tools
MAKE_CHECK_ARGS: build-tcg
- TARGETS: ppc64abi32-linux-user lm32-softmmu unicore32-softmmu
+ TARGETS: ppc64abi32-linux-user
artifacts:
expire_in: 2 days
paths:
@@ -634,7 +633,7 @@ build-deprecated:
# We split the check-tcg step as test failures are expected but we still
# want to catch the build breaking.
check-deprecated:
- <<: *native_test_job_definition
+ extends: .native_test_job_template
needs:
- job: build-deprecated
artifacts: true
@@ -645,7 +644,7 @@ check-deprecated:
# gprof/gcov are GCC features
gprof-gcov:
- <<: *native_build_job_definition
+ extends: .native_build_job_template
needs:
job: amd64-ubuntu2004-container
variables:
@@ -658,7 +657,7 @@ gprof-gcov:
- ${CI_PROJECT_DIR}/scripts/ci/coverage-summary.sh
build-oss-fuzz:
- <<: *native_build_job_definition
+ extends: .native_build_job_template
needs:
job: amd64-fedora-container
variables:
@@ -678,13 +677,13 @@ build-oss-fuzz:
- cd build-oss-fuzz && make check-qtest-i386 check-unit
build-tci:
- <<: *native_build_job_definition
+ extends: .native_build_job_template
needs:
job: amd64-debian-user-cross-container
variables:
IMAGE: debian-all-test-cross
script:
- - TARGETS="aarch64 alpha arm hppa m68k microblaze moxie ppc64 s390x x86_64"
+ - TARGETS="aarch64 alpha arm hppa m68k microblaze ppc64 s390x x86_64"
- mkdir build
- cd build
- ../configure --enable-tcg-interpreter
@@ -703,7 +702,7 @@ build-tci:
# Alternate coroutines implementations are only really of interest to KVM users
# However we can't test against KVM on Gitlab-CI so we can only run unit tests
build-coroutine-sigaltstack:
- <<: *native_build_job_definition
+ extends: .native_build_job_template
needs:
job: amd64-ubuntu2004-container
variables:
@@ -717,7 +716,7 @@ build-coroutine-sigaltstack:
# These jobs test old gcrypt and nettle from RHEL7
# which had some API differences.
crypto-old-nettle:
- <<: *native_build_job_definition
+ extends: .native_build_job_template
needs:
job: amd64-centos7-container
variables:
@@ -727,7 +726,7 @@ crypto-old-nettle:
MAKE_CHECK_ARGS: check
crypto-old-gcrypt:
- <<: *native_build_job_definition
+ extends: .native_build_job_template
needs:
job: amd64-centos7-container
variables:
@@ -737,7 +736,7 @@ crypto-old-gcrypt:
MAKE_CHECK_ARGS: check
crypto-only-gnutls:
- <<: *native_build_job_definition
+ extends: .native_build_job_template
needs:
job: amd64-centos7-container
variables:
@@ -749,7 +748,7 @@ crypto-only-gnutls:
# Check our reduced build configurations
build-without-default-devices:
- <<: *native_build_job_definition
+ extends: .native_build_job_template
needs:
job: amd64-centos8-container
variables:
@@ -757,7 +756,7 @@ build-without-default-devices:
CONFIGURE_ARGS: --without-default-devices --disable-user
build-without-default-features:
- <<: *native_build_job_definition
+ extends: .native_build_job_template
needs:
job: amd64-debian-container
variables:
@@ -807,7 +806,7 @@ build-libvhost-user:
# No targets are built here, just tools, docs, and unit tests. This
# also feeds into the eventual documentation deployment steps later
build-tools-and-docs-debian:
- <<: *native_build_job_definition
+ extends: .native_build_job_template
needs:
job: amd64-debian-container
variables:
diff --git a/MAINTAINERS b/MAINTAINERS
index c733c53bf7..78561a223f 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -207,19 +207,6 @@ F: disas/hppa.c
F: hw/net/*i82596*
F: include/hw/net/lasi_82596.h
-LM32 TCG CPUs
-R: Michael Walle <michael@walle.cc>
-S: Orphan
-F: target/lm32/
-F: disas/lm32.c
-F: hw/lm32/
-F: hw/*/lm32_*
-F: hw/*/milkymist-*
-F: include/hw/display/milkymist_tmu2.h
-F: include/hw/char/lm32_juart.h
-F: include/hw/lm32/
-F: tests/tcg/lm32/
-
M68K TCG CPUs
M: Laurent Vivier <laurent@vivier.eu>
S: Maintained
@@ -258,14 +245,6 @@ MIPS TCG CPUs (nanoMIPS ISA)
S: Orphan
F: disas/nanomips.*
-Moxie TCG CPUs
-M: Anthony Green <green@moxielogic.com>
-S: Maintained
-F: target/moxie/
-F: disas/moxie.c
-F: hw/moxie/
-F: default-configs/*/moxie-softmmu.mak
-
NiosII TCG CPUs
M: Chris Wulff <crwulff@gmail.com>
M: Marek Vasut <marex@denx.de>
@@ -338,13 +317,6 @@ F: hw/sparc64/
F: include/hw/sparc/sparc64.h
F: disas/sparc.c
-UniCore32 TCG CPUs
-M: Guan Xuetao <gxt@mprc.pku.edu.cn>
-S: Maintained
-F: target/unicore32/
-F: hw/unicore32/
-F: include/hw/unicore32/
-
X86 TCG CPUs
M: Paolo Bonzini <pbonzini@redhat.com>
M: Richard Henderson <richard.henderson@linaro.org>
@@ -1088,18 +1060,6 @@ F: default-configs/*/hppa-softmmu.mak
F: hw/hppa/
F: pc-bios/hppa-firmware.img
-LM32 Machines
--------------
-EVR32 and uclinux BSP
-R: Michael Walle <michael@walle.cc>
-S: Orphan
-F: hw/lm32/lm32_boards.c
-
-milkymist
-R: Michael Walle <michael@walle.cc>
-S: Orphan
-F: hw/lm32/milkymist.c
-
M68K Machines
-------------
an5206
@@ -1549,14 +1509,6 @@ F: hw/s390x/s390-pci*
F: include/hw/s390x/s390-pci*
L: qemu-s390x@nongnu.org
-UniCore32 Machines
-------------------
-PKUnity-3 SoC initramfs-with-busybox
-M: Guan Xuetao <gxt@mprc.pku.edu.cn>
-S: Maintained
-F: hw/*/puv3*
-F: hw/unicore32/
-
X86 Machines
------------
PC
@@ -2072,6 +2024,12 @@ S: Maintained
F: hw/net/tulip.c
F: hw/net/tulip.h
+pca954x
+M: Patrick Venture <venture@google.com>
+S: Maintained
+F: hw/i2c/i2c_mux_pca954x.c
+F: include/hw/i2c/i2c_mux_pca954x.h
+
Generic Loader
M: Alistair Francis <alistair@alistair23.me>
S: Maintained
@@ -3088,12 +3046,6 @@ L: qemu-block@nongnu.org
S: Supported
F: block/rbd.c
-Sheepdog
-M: Liu Yuan <namei.unix@gmail.com>
-L: qemu-block@nongnu.org
-S: Odd Fixes
-F: block/sheepdog.c
-
VHDX
M: Jeff Cody <codyprime@gmail.com>
L: qemu-block@nongnu.org
diff --git a/Makefile b/Makefile
index bcbbec71a1..4cab10a2a4 100644
--- a/Makefile
+++ b/Makefile
@@ -213,7 +213,7 @@ qemu-%.tar.bz2:
distclean: clean
-$(quiet-@)test -f build.ninja && $(NINJA) $(NINJAFLAGS) -t clean -g || :
- rm -f config-host.mak config-host.h*
+ rm -f config-host.mak config-host.h* config-poison.h
rm -f tests/tcg/config-*.mak
rm -f config-all-disas.mak config.status
rm -f roms/seabios/config.mak roms/vgabios/config.mak
diff --git a/block.c b/block.c
index 9ad725d205..75a82af641 100644
--- a/block.c
+++ b/block.c
@@ -400,7 +400,6 @@ BlockDriverState *bdrv_new(void)
for (i = 0; i < BLOCK_OP_TYPE_MAX; i++) {
QLIST_INIT(&bs->op_blockers[i]);
}
- notifier_with_return_list_init(&bs->before_write_notifiers);
qemu_co_mutex_init(&bs->reqs_lock);
qemu_mutex_init(&bs->dirty_bitmap_mutex);
bs->refcnt = 1;
diff --git a/block/backup.c b/block/backup.c
index 6cf2f974aa..bd3614ce70 100644
--- a/block/backup.c
+++ b/block/backup.c
@@ -331,7 +331,7 @@ static void coroutine_fn backup_set_speed(BlockJob *job, int64_t speed)
}
}
-static void backup_cancel(Job *job)
+static void backup_cancel(Job *job, bool force)
{
BackupBlockJob *s = container_of(job, BackupBlockJob, common.job);
diff --git a/block/copy-on-read.c b/block/copy-on-read.c
index 9cad9e1b8c..c428682272 100644
--- a/block/copy-on-read.c
+++ b/block/copy-on-read.c
@@ -29,7 +29,6 @@
typedef struct BDRVStateCOR {
- bool active;
BlockDriverState *bottom_bs;
bool chain_frozen;
} BDRVStateCOR;
@@ -89,7 +88,6 @@ static int cor_open(BlockDriverState *bs, QDict *options, int flags,
*/
bdrv_ref(bottom_bs);
}
- state->active = true;
state->bottom_bs = bottom_bs;
/*
@@ -112,17 +110,6 @@ static void cor_child_perm(BlockDriverState *bs, BdrvChild *c,
uint64_t perm, uint64_t shared,
uint64_t *nperm, uint64_t *nshared)
{
- BDRVStateCOR *s = bs->opaque;
-
- if (!s->active) {
- /*
- * While the filter is being removed
- */
- *nperm = 0;
- *nshared = BLK_PERM_ALL;
- return;
- }
-
*nperm = perm & PERM_PASSTHROUGH;
*nshared = (shared & PERM_PASSTHROUGH) | PERM_UNCHANGED;
@@ -280,32 +267,14 @@ static BlockDriver bdrv_copy_on_read = {
void bdrv_cor_filter_drop(BlockDriverState *cor_filter_bs)
{
- BdrvChild *child;
- BlockDriverState *bs;
BDRVStateCOR *s = cor_filter_bs->opaque;
- child = bdrv_filter_child(cor_filter_bs);
- if (!child) {
- return;
- }
- bs = child->bs;
-
- /* Retain the BDS until we complete the graph change. */
- bdrv_ref(bs);
- /* Hold a guest back from writing while permissions are being reset. */
- bdrv_drained_begin(bs);
- /* Drop permissions before the graph change. */
- s->active = false;
/* unfreeze, as otherwise bdrv_replace_node() will fail */
if (s->chain_frozen) {
s->chain_frozen = false;
bdrv_unfreeze_backing_chain(cor_filter_bs, s->bottom_bs);
}
- bdrv_child_refresh_perms(cor_filter_bs, child, &error_abort);
- bdrv_replace_node(cor_filter_bs, bs, &error_abort);
-
- bdrv_drained_end(bs);
- bdrv_unref(bs);
+ bdrv_drop_filter(cor_filter_bs, &error_abort);
bdrv_unref(cor_filter_bs);
}
diff --git a/block/io.c b/block/io.c
index 35b6c56efc..1e826ba9e8 100644
--- a/block/io.c
+++ b/block/io.c
@@ -30,6 +30,7 @@
#include "block/blockjob_int.h"
#include "block/block_int.h"
#include "block/coroutines.h"
+#include "block/write-threshold.h"
#include "qemu/cutils.h"
#include "qapi/error.h"
#include "qemu/error-report.h"
@@ -2008,8 +2009,8 @@ bdrv_co_write_req_prepare(BdrvChild *child, int64_t offset, int64_t bytes,
} else {
assert(child->perm & BLK_PERM_WRITE);
}
- return notifier_with_return_list_notify(&bs->before_write_notifiers,
- req);
+ bdrv_write_threshold_check_write(bs, offset, bytes);
+ return 0;
case BDRV_TRACKED_TRUNCATE:
assert(child->perm & BLK_PERM_RESIZE);
return 0;
@@ -3164,12 +3165,6 @@ bool bdrv_qiov_is_aligned(BlockDriverState *bs, QEMUIOVector *qiov)
return true;
}
-void bdrv_add_before_write_notifier(BlockDriverState *bs,
- NotifierWithReturn *notifier)
-{
- notifier_with_return_list_add(&bs->before_write_notifiers, notifier);
-}
-
void bdrv_io_plug(BlockDriverState *bs)
{
BdrvChild *child;
diff --git a/block/meson.build b/block/meson.build
index d21990ec95..e687c54dbc 100644
--- a/block/meson.build
+++ b/block/meson.build
@@ -64,7 +64,6 @@ block_ss.add(when: 'CONFIG_POSIX', if_true: [files('file-posix.c'), coref, iokit
block_ss.add(when: libiscsi, if_true: files('iscsi-opts.c'))
block_ss.add(when: 'CONFIG_LINUX', if_true: files('nvme.c'))
block_ss.add(when: 'CONFIG_REPLICATION', if_true: files('replication.c'))
-block_ss.add(when: 'CONFIG_SHEEPDOG', if_true: files('sheepdog.c'))
block_ss.add(when: ['CONFIG_LINUX_AIO', libaio], if_true: files('linux-aio.c'))
block_ss.add(when: ['CONFIG_LINUX_IO_URING', linux_io_uring], if_true: files('io_uring.c'))
diff --git a/block/mirror.c b/block/mirror.c
index 840b8e8c15..019f6deaa5 100644
--- a/block/mirror.c
+++ b/block/mirror.c
@@ -1178,12 +1178,14 @@ static bool mirror_drained_poll(BlockJob *job)
return !!s->in_flight;
}
-static void mirror_cancel(Job *job)
+static void mirror_cancel(Job *job, bool force)
{
MirrorBlockJob *s = container_of(job, MirrorBlockJob, common.job);
BlockDriverState *target = blk_bs(s->target);
- bdrv_cancel_in_flight(target);
+ if (force || !job_is_ready(job)) {
+ bdrv_cancel_in_flight(target);
+ }
}
static const BlockJobDriver mirror_job_driver = {
diff --git a/block/monitor/block-hmp-cmds.c b/block/monitor/block-hmp-cmds.c
index ebf1033f31..3e6670c963 100644
--- a/block/monitor/block-hmp-cmds.c
+++ b/block/monitor/block-hmp-cmds.c
@@ -557,8 +557,10 @@ void hmp_eject(Monitor *mon, const QDict *qdict)
void hmp_qemu_io(Monitor *mon, const QDict *qdict)
{
- BlockBackend *blk;
+ BlockBackend *blk = NULL;
+ BlockDriverState *bs = NULL;
BlockBackend *local_blk = NULL;
+ AioContext *ctx = NULL;
bool qdev = qdict_get_try_bool(qdict, "qdev", false);
const char *device = qdict_get_str(qdict, "device");
const char *command = qdict_get_str(qdict, "command");
@@ -573,20 +575,24 @@ void hmp_qemu_io(Monitor *mon, const QDict *qdict)
} else {
blk = blk_by_name(device);
if (!blk) {
- BlockDriverState *bs = bdrv_lookup_bs(NULL, device, &err);
- if (bs) {
- blk = local_blk = blk_new(bdrv_get_aio_context(bs),
- 0, BLK_PERM_ALL);
- ret = blk_insert_bs(blk, bs, &err);
- if (ret < 0) {
- goto fail;
- }
- } else {
+ bs = bdrv_lookup_bs(NULL, device, &err);
+ if (!bs) {
goto fail;
}
}
}
+ ctx = blk ? blk_get_aio_context(blk) : bdrv_get_aio_context(bs);
+ aio_context_acquire(ctx);
+
+ if (bs) {
+ blk = local_blk = blk_new(bdrv_get_aio_context(bs), 0, BLK_PERM_ALL);
+ ret = blk_insert_bs(blk, bs, &err);
+ if (ret < 0) {
+ goto fail;
+ }
+ }
+
/*
* Notably absent: Proper permission management. This is sad, but it seems
* almost impossible to achieve without changing the semantics and thereby
@@ -616,6 +622,11 @@ void hmp_qemu_io(Monitor *mon, const QDict *qdict)
fail:
blk_unref(local_blk);
+
+ if (ctx) {
+ aio_context_release(ctx);
+ }
+
hmp_handle_error(mon, err);
}
diff --git a/block/rbd.c b/block/rbd.c
index f098a89c7b..26f64cce7c 100644
--- a/block/rbd.c
+++ b/block/rbd.c
@@ -113,21 +113,31 @@ static int qemu_rbd_connect(rados_t *cluster, rados_ioctx_t *io_ctx,
const char *keypairs, const char *secretid,
Error **errp);
+static char *qemu_rbd_strchr(char *src, char delim)
+{
+ char *p;
+
+ for (p = src; *p; ++p) {
+ if (*p == delim) {
+ return p;
+ }
+ if (*p == '\\' && p[1] != '\0') {
+ ++p;
+ }
+ }
+
+ return NULL;
+}
+
+
static char *qemu_rbd_next_tok(char *src, char delim, char **p)
{
char *end;
*p = NULL;
- for (end = src; *end; ++end) {
- if (*end == delim) {
- break;
- }
- if (*end == '\\' && end[1] != '\0') {
- end++;
- }
- }
- if (*end == delim) {
+ end = qemu_rbd_strchr(src, delim);
+ if (end) {
*p = end + 1;
*end = '\0';
}
@@ -171,7 +181,7 @@ static void qemu_rbd_parse_filename(const char *filename, QDict *options,
qemu_rbd_unescape(found_str);
qdict_put_str(options, "pool", found_str);
- if (strchr(p, '@')) {
+ if (qemu_rbd_strchr(p, '@')) {
image_name = qemu_rbd_next_tok(p, '@', &p);
found_str = qemu_rbd_next_tok(p, ':', &p);
@@ -181,7 +191,7 @@ static void qemu_rbd_parse_filename(const char *filename, QDict *options,
image_name = qemu_rbd_next_tok(p, ':', &p);
}
/* Check for namespace in the image_name */
- if (strchr(image_name, '/')) {
+ if (qemu_rbd_strchr(image_name, '/')) {
found_str = qemu_rbd_next_tok(image_name, '/', &image_name);
qemu_rbd_unescape(found_str);
qdict_put_str(options, "namespace", found_str);
diff --git a/block/sheepdog.c b/block/sheepdog.c
deleted file mode 100644
index a45c73826d..0000000000
--- a/block/sheepdog.c
+++ /dev/null
@@ -1,3356 +0,0 @@
-/*
- * Copyright (C) 2009-2010 Nippon Telegraph and Telephone Corporation.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License version
- * 2 as published by the Free Software Foundation.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- * Contributions after 2012-01-13 are licensed under the terms of the
- * GNU GPL, version 2 or (at your option) any later version.
- */
-
-#include "qemu/osdep.h"
-#include "qemu-common.h"
-#include "qapi/error.h"
-#include "qapi/qapi-visit-sockets.h"
-#include "qapi/qapi-visit-block-core.h"
-#include "qapi/qmp/qdict.h"
-#include "qapi/qobject-input-visitor.h"
-#include "qapi/qobject-output-visitor.h"
-#include "qemu/uri.h"
-#include "qemu/error-report.h"
-#include "qemu/main-loop.h"
-#include "qemu/module.h"
-#include "qemu/option.h"
-#include "qemu/sockets.h"
-#include "block/block_int.h"
-#include "block/qdict.h"
-#include "sysemu/block-backend.h"
-#include "qemu/bitops.h"
-#include "qemu/cutils.h"
-#include "trace.h"
-
-#define SD_PROTO_VER 0x01
-
-#define SD_DEFAULT_ADDR "localhost"
-#define SD_DEFAULT_PORT 7000
-
-#define SD_OP_CREATE_AND_WRITE_OBJ 0x01
-#define SD_OP_READ_OBJ 0x02
-#define SD_OP_WRITE_OBJ 0x03
-/* 0x04 is used internally by Sheepdog */
-
-#define SD_OP_NEW_VDI 0x11
-#define SD_OP_LOCK_VDI 0x12
-#define SD_OP_RELEASE_VDI 0x13
-#define SD_OP_GET_VDI_INFO 0x14
-#define SD_OP_READ_VDIS 0x15
-#define SD_OP_FLUSH_VDI 0x16
-#define SD_OP_DEL_VDI 0x17
-#define SD_OP_GET_CLUSTER_DEFAULT 0x18
-
-#define SD_FLAG_CMD_WRITE 0x01
-#define SD_FLAG_CMD_COW 0x02
-#define SD_FLAG_CMD_CACHE 0x04 /* Writeback mode for cache */
-#define SD_FLAG_CMD_DIRECT 0x08 /* Don't use cache */
-
-#define SD_RES_SUCCESS 0x00 /* Success */
-#define SD_RES_UNKNOWN 0x01 /* Unknown error */
-#define SD_RES_NO_OBJ 0x02 /* No object found */
-#define SD_RES_EIO 0x03 /* I/O error */
-#define SD_RES_VDI_EXIST 0x04 /* Vdi exists already */
-#define SD_RES_INVALID_PARMS 0x05 /* Invalid parameters */
-#define SD_RES_SYSTEM_ERROR 0x06 /* System error */
-#define SD_RES_VDI_LOCKED 0x07 /* Vdi is locked */
-#define SD_RES_NO_VDI 0x08 /* No vdi found */
-#define SD_RES_NO_BASE_VDI 0x09 /* No base vdi found */
-#define SD_RES_VDI_READ 0x0A /* Cannot read requested vdi */
-#define SD_RES_VDI_WRITE 0x0B /* Cannot write requested vdi */
-#define SD_RES_BASE_VDI_READ 0x0C /* Cannot read base vdi */
-#define SD_RES_BASE_VDI_WRITE 0x0D /* Cannot write base vdi */
-#define SD_RES_NO_TAG 0x0E /* Requested tag is not found */
-#define SD_RES_STARTUP 0x0F /* Sheepdog is on starting up */
-#define SD_RES_VDI_NOT_LOCKED 0x10 /* Vdi is not locked */
-#define SD_RES_SHUTDOWN 0x11 /* Sheepdog is shutting down */
-#define SD_RES_NO_MEM 0x12 /* Cannot allocate memory */
-#define SD_RES_FULL_VDI 0x13 /* we already have the maximum vdis */
-#define SD_RES_VER_MISMATCH 0x14 /* Protocol version mismatch */
-#define SD_RES_NO_SPACE 0x15 /* Server has no room for new objects */
-#define SD_RES_WAIT_FOR_FORMAT 0x16 /* Waiting for a format operation */
-#define SD_RES_WAIT_FOR_JOIN 0x17 /* Waiting for other nodes joining */
-#define SD_RES_JOIN_FAILED 0x18 /* Target node had failed to join sheepdog */
-#define SD_RES_HALT 0x19 /* Sheepdog is stopped serving IO request */
-#define SD_RES_READONLY 0x1A /* Object is read-only */
-
-/*
- * Object ID rules
- *
- * 0 - 19 (20 bits): data object space
- * 20 - 31 (12 bits): reserved data object space
- * 32 - 55 (24 bits): vdi object space
- * 56 - 59 ( 4 bits): reserved vdi object space
- * 60 - 63 ( 4 bits): object type identifier space
- */
-
-#define VDI_SPACE_SHIFT 32
-#define VDI_BIT (UINT64_C(1) << 63)
-#define VMSTATE_BIT (UINT64_C(1) << 62)
-#define MAX_DATA_OBJS (UINT64_C(1) << 20)
-#define MAX_CHILDREN 1024
-#define SD_MAX_VDI_LEN 256
-#define SD_MAX_VDI_TAG_LEN 256
-#define SD_NR_VDIS (1U << 24)
-#define SD_DATA_OBJ_SIZE (UINT64_C(1) << 22)
-#define SD_MAX_VDI_SIZE (SD_DATA_OBJ_SIZE * MAX_DATA_OBJS)
-#define SD_DEFAULT_BLOCK_SIZE_SHIFT 22
-/*
- * For erasure coding, we use at most SD_EC_MAX_STRIP for data strips and
- * (SD_EC_MAX_STRIP - 1) for parity strips
- *
- * SD_MAX_COPIES is sum of number of data strips and parity strips.
- */
-#define SD_EC_MAX_STRIP 16
-#define SD_MAX_COPIES (SD_EC_MAX_STRIP * 2 - 1)
-
-#define SD_INODE_SIZE (sizeof(SheepdogInode))
-#define CURRENT_VDI_ID 0
-
-#define LOCK_TYPE_NORMAL 0
-#define LOCK_TYPE_SHARED 1 /* for iSCSI multipath */
-
-typedef struct SheepdogReq {
- uint8_t proto_ver;
- uint8_t opcode;
- uint16_t flags;
- uint32_t epoch;
- uint32_t id;
- uint32_t data_length;
- uint32_t opcode_specific[8];
-} SheepdogReq;
-
-typedef struct SheepdogRsp {
- uint8_t proto_ver;
- uint8_t opcode;
- uint16_t flags;
- uint32_t epoch;
- uint32_t id;
- uint32_t data_length;
- uint32_t result;
- uint32_t opcode_specific[7];
-} SheepdogRsp;
-
-typedef struct SheepdogObjReq {
- uint8_t proto_ver;
- uint8_t opcode;
- uint16_t flags;
- uint32_t epoch;
- uint32_t id;
- uint32_t data_length;
- uint64_t oid;
- uint64_t cow_oid;
- uint8_t copies;
- uint8_t copy_policy;
- uint8_t reserved[6];
- uint64_t offset;
-} SheepdogObjReq;
-
-typedef struct SheepdogObjRsp {
- uint8_t proto_ver;
- uint8_t opcode;
- uint16_t flags;
- uint32_t epoch;
- uint32_t id;
- uint32_t data_length;
- uint32_t result;
- uint8_t copies;
- uint8_t copy_policy;
- uint8_t reserved[2];
- uint32_t pad[6];
-} SheepdogObjRsp;
-
-typedef struct SheepdogVdiReq {
- uint8_t proto_ver;
- uint8_t opcode;
- uint16_t flags;
- uint32_t epoch;
- uint32_t id;
- uint32_t data_length;
- uint64_t vdi_size;
- uint32_t base_vdi_id;
- uint8_t copies;
- uint8_t copy_policy;
- uint8_t store_policy;
- uint8_t block_size_shift;
- uint32_t snapid;
- uint32_t type;
- uint32_t pad[2];
-} SheepdogVdiReq;
-
-typedef struct SheepdogVdiRsp {
- uint8_t proto_ver;
- uint8_t opcode;
- uint16_t flags;
- uint32_t epoch;
- uint32_t id;
- uint32_t data_length;
- uint32_t result;
- uint32_t rsvd;
- uint32_t vdi_id;
- uint32_t pad[5];
-} SheepdogVdiRsp;
-
-typedef struct SheepdogClusterRsp {
- uint8_t proto_ver;
- uint8_t opcode;
- uint16_t flags;
- uint32_t epoch;
- uint32_t id;
- uint32_t data_length;
- uint32_t result;
- uint8_t nr_copies;
- uint8_t copy_policy;
- uint8_t block_size_shift;
- uint8_t __pad1;
- uint32_t __pad2[6];
-} SheepdogClusterRsp;
-
-typedef struct SheepdogInode {
- char name[SD_MAX_VDI_LEN];
- char tag[SD_MAX_VDI_TAG_LEN];
- uint64_t ctime;
- uint64_t snap_ctime;
- uint64_t vm_clock_nsec;
- uint64_t vdi_size;
- uint64_t vm_state_size;
- uint16_t copy_policy;
- uint8_t nr_copies;
- uint8_t block_size_shift;
- uint32_t snap_id;
- uint32_t vdi_id;
- uint32_t parent_vdi_id;
- uint32_t child_vdi_id[MAX_CHILDREN];
- uint32_t data_vdi_id[MAX_DATA_OBJS];
-} SheepdogInode;
-
-#define SD_INODE_HEADER_SIZE offsetof(SheepdogInode, data_vdi_id)
-
-/*
- * 64 bit FNV-1a non-zero initial basis
- */
-#define FNV1A_64_INIT ((uint64_t)0xcbf29ce484222325ULL)
-
-static void deprecation_warning(void)
-{
- static bool warned;
-
- if (!warned) {
- warn_report("the sheepdog block driver is deprecated");
- warned = true;
- }
-}
-
-/*
- * 64 bit Fowler/Noll/Vo FNV-1a hash code
- */
-static inline uint64_t fnv_64a_buf(void *buf, size_t len, uint64_t hval)
-{
- unsigned char *bp = buf;
- unsigned char *be = bp + len;
- while (bp < be) {
- hval ^= (uint64_t) *bp++;
- hval += (hval << 1) + (hval << 4) + (hval << 5) +
- (hval << 7) + (hval << 8) + (hval << 40);
- }
- return hval;
-}
-
-static inline bool is_data_obj_writable(SheepdogInode *inode, unsigned int idx)
-{
- return inode->vdi_id == inode->data_vdi_id[idx];
-}
-
-static inline bool is_data_obj(uint64_t oid)
-{
- return !(VDI_BIT & oid);
-}
-
-static inline uint64_t data_oid_to_idx(uint64_t oid)
-{
- return oid & (MAX_DATA_OBJS - 1);
-}
-
-static inline uint32_t oid_to_vid(uint64_t oid)
-{
- return (oid & ~VDI_BIT) >> VDI_SPACE_SHIFT;
-}
-
-static inline uint64_t vid_to_vdi_oid(uint32_t vid)
-{
- return VDI_BIT | ((uint64_t)vid << VDI_SPACE_SHIFT);
-}
-
-static inline uint64_t vid_to_vmstate_oid(uint32_t vid, uint32_t idx)
-{
- return VMSTATE_BIT | ((uint64_t)vid << VDI_SPACE_SHIFT) | idx;
-}
-
-static inline uint64_t vid_to_data_oid(uint32_t vid, uint32_t idx)
-{
- return ((uint64_t)vid << VDI_SPACE_SHIFT) | idx;
-}
-
-static inline bool is_snapshot(struct SheepdogInode *inode)
-{
- return !!inode->snap_ctime;
-}
-
-static inline size_t count_data_objs(const struct SheepdogInode *inode)
-{
- return DIV_ROUND_UP(inode->vdi_size,
- (1UL << inode->block_size_shift));
-}
-
-typedef struct SheepdogAIOCB SheepdogAIOCB;
-typedef struct BDRVSheepdogState BDRVSheepdogState;
-
-typedef struct AIOReq {
- SheepdogAIOCB *aiocb;
- unsigned int iov_offset;
-
- uint64_t oid;
- uint64_t base_oid;
- uint64_t offset;
- unsigned int data_len;
- uint8_t flags;
- uint32_t id;
- bool create;
-
- QLIST_ENTRY(AIOReq) aio_siblings;
-} AIOReq;
-
-enum AIOCBState {
- AIOCB_WRITE_UDATA,
- AIOCB_READ_UDATA,
- AIOCB_FLUSH_CACHE,
- AIOCB_DISCARD_OBJ,
-};
-
-#define AIOCBOverlapping(x, y) \
- (!(x->max_affect_data_idx < y->min_affect_data_idx \
- || y->max_affect_data_idx < x->min_affect_data_idx))
-
-struct SheepdogAIOCB {
- BDRVSheepdogState *s;
-
- QEMUIOVector *qiov;
-
- int64_t sector_num;
- int nb_sectors;
-
- int ret;
- enum AIOCBState aiocb_type;
-
- Coroutine *coroutine;
- int nr_pending;
-
- uint32_t min_affect_data_idx;
- uint32_t max_affect_data_idx;
-
- /*
- * The difference between affect_data_idx and dirty_data_idx:
- * affect_data_idx represents range of index of all request types.
- * dirty_data_idx represents range of index updated by COW requests.
- * dirty_data_idx is used for updating an inode object.
- */
- uint32_t min_dirty_data_idx;
- uint32_t max_dirty_data_idx;
-
- QLIST_ENTRY(SheepdogAIOCB) aiocb_siblings;
-};
-
-struct BDRVSheepdogState {
- BlockDriverState *bs;
- AioContext *aio_context;
-
- SheepdogInode inode;
-
- char name[SD_MAX_VDI_LEN];
- bool is_snapshot;
- uint32_t cache_flags;
- bool discard_supported;
-
- SocketAddress *addr;
- int fd;
-
- CoMutex lock;
- Coroutine *co_send;
- Coroutine *co_recv;
-
- uint32_t aioreq_seq_num;
-
- /* Every aio request must be linked to either of these queues. */
- QLIST_HEAD(, AIOReq) inflight_aio_head;
- QLIST_HEAD(, AIOReq) failed_aio_head;
-
- CoMutex queue_lock;
- CoQueue overlapping_queue;
- QLIST_HEAD(, SheepdogAIOCB) inflight_aiocb_head;
-};
-
-typedef struct BDRVSheepdogReopenState {
- int fd;
- int cache_flags;
-} BDRVSheepdogReopenState;
-
-static const char *sd_strerror(int err)
-{
- int i;
-
- static const struct {
- int err;
- const char *desc;
- } errors[] = {
- {SD_RES_SUCCESS, "Success"},
- {SD_RES_UNKNOWN, "Unknown error"},
- {SD_RES_NO_OBJ, "No object found"},
- {SD_RES_EIO, "I/O error"},
- {SD_RES_VDI_EXIST, "VDI exists already"},
- {SD_RES_INVALID_PARMS, "Invalid parameters"},
- {SD_RES_SYSTEM_ERROR, "System error"},
- {SD_RES_VDI_LOCKED, "VDI is already locked"},
- {SD_RES_NO_VDI, "No vdi found"},
- {SD_RES_NO_BASE_VDI, "No base VDI found"},
- {SD_RES_VDI_READ, "Failed read the requested VDI"},
- {SD_RES_VDI_WRITE, "Failed to write the requested VDI"},
- {SD_RES_BASE_VDI_READ, "Failed to read the base VDI"},
- {SD_RES_BASE_VDI_WRITE, "Failed to write the base VDI"},
- {SD_RES_NO_TAG, "Failed to find the requested tag"},
- {SD_RES_STARTUP, "The system is still booting"},
- {SD_RES_VDI_NOT_LOCKED, "VDI isn't locked"},
- {SD_RES_SHUTDOWN, "The system is shutting down"},
- {SD_RES_NO_MEM, "Out of memory on the server"},
- {SD_RES_FULL_VDI, "We already have the maximum vdis"},
- {SD_RES_VER_MISMATCH, "Protocol version mismatch"},
- {SD_RES_NO_SPACE, "Server has no space for new objects"},
- {SD_RES_WAIT_FOR_FORMAT, "Sheepdog is waiting for a format operation"},
- {SD_RES_WAIT_FOR_JOIN, "Sheepdog is waiting for other nodes joining"},
- {SD_RES_JOIN_FAILED, "Target node had failed to join sheepdog"},
- {SD_RES_HALT, "Sheepdog is stopped serving IO request"},
- {SD_RES_READONLY, "Object is read-only"},
- };
-
- for (i = 0; i < ARRAY_SIZE(errors); ++i) {
- if (errors[i].err == err) {
- return errors[i].desc;
- }
- }
-
- return "Invalid error code";
-}
-
-/*
- * Sheepdog I/O handling:
- *
- * 1. In sd_co_rw_vector, we send the I/O requests to the server and
- * link the requests to the inflight_list in the
- * BDRVSheepdogState. The function yields while waiting for
- * receiving the response.
- *
- * 2. We receive the response in aio_read_response, the fd handler to
- * the sheepdog connection. We switch back to sd_co_readv/sd_writev
- * after all the requests belonging to the AIOCB are finished. If
- * needed, sd_co_writev will send another requests for the vdi object.
- */
-
-static inline AIOReq *alloc_aio_req(BDRVSheepdogState *s, SheepdogAIOCB *acb,
- uint64_t oid, unsigned int data_len,
- uint64_t offset, uint8_t flags, bool create,
- uint64_t base_oid, unsigned int iov_offset)
-{
- AIOReq *aio_req;
-
- aio_req = g_malloc(sizeof(*aio_req));
- aio_req->aiocb = acb;
- aio_req->iov_offset = iov_offset;
- aio_req->oid = oid;
- aio_req->base_oid = base_oid;
- aio_req->offset = offset;
- aio_req->data_len = data_len;
- aio_req->flags = flags;
- aio_req->id = s->aioreq_seq_num++;
- aio_req->create = create;
-
- acb->nr_pending++;
- return aio_req;
-}
-
-static void wait_for_overlapping_aiocb(BDRVSheepdogState *s, SheepdogAIOCB *acb)
-{
- SheepdogAIOCB *cb;
-
-retry:
- QLIST_FOREACH(cb, &s->inflight_aiocb_head, aiocb_siblings) {
- if (AIOCBOverlapping(acb, cb)) {
- qemu_co_queue_wait(&s->overlapping_queue, &s->queue_lock);
- goto retry;
- }
- }
-}
-
-static void sd_aio_setup(SheepdogAIOCB *acb, BDRVSheepdogState *s,
- QEMUIOVector *qiov, int64_t sector_num, int nb_sectors,
- int type)
-{
- uint32_t object_size;
-
- object_size = (UINT32_C(1) << s->inode.block_size_shift);
-
- acb->s = s;
-
- acb->qiov = qiov;
-
- acb->sector_num = sector_num;
- acb->nb_sectors = nb_sectors;
-
- acb->coroutine = qemu_coroutine_self();
- acb->ret = 0;
- acb->nr_pending = 0;
-
- acb->min_affect_data_idx = acb->sector_num * BDRV_SECTOR_SIZE / object_size;
- acb->max_affect_data_idx = (acb->sector_num * BDRV_SECTOR_SIZE +
- acb->nb_sectors * BDRV_SECTOR_SIZE) / object_size;
-
- acb->min_dirty_data_idx = UINT32_MAX;
- acb->max_dirty_data_idx = 0;
- acb->aiocb_type = type;
-
- if (type == AIOCB_FLUSH_CACHE) {
- return;
- }
-
- qemu_co_mutex_lock(&s->queue_lock);
- wait_for_overlapping_aiocb(s, acb);
- QLIST_INSERT_HEAD(&s->inflight_aiocb_head, acb, aiocb_siblings);
- qemu_co_mutex_unlock(&s->queue_lock);
-}
-
-static SocketAddress *sd_server_config(QDict *options, Error **errp)
-{
- QDict *server = NULL;
- Visitor *iv = NULL;
- SocketAddress *saddr = NULL;
-
- qdict_extract_subqdict(options, &server, "server.");
-
- iv = qobject_input_visitor_new_flat_confused(server, errp);
- if (!iv) {
- goto done;
- }
-
- if (!visit_type_SocketAddress(iv, NULL, &saddr, errp)) {
- goto done;
- }
-
-done:
- visit_free(iv);
- qobject_unref(server);
- return saddr;
-}
-
-/* Return -EIO in case of error, file descriptor on success */
-static int connect_to_sdog(BDRVSheepdogState *s, Error **errp)
-{
- int fd;
-
- fd = socket_connect(s->addr, errp);
-
- if (s->addr->type == SOCKET_ADDRESS_TYPE_INET && fd >= 0) {
- int ret = socket_set_nodelay(fd);
- if (ret < 0) {
- warn_report("can't set TCP_NODELAY: %s", strerror(errno));
- }
- }
-
- if (fd >= 0) {
- qemu_set_nonblock(fd);
- } else {
- fd = -EIO;
- }
-
- return fd;
-}
-
-/* Return 0 on success and -errno in case of error */
-static coroutine_fn int send_co_req(int sockfd, SheepdogReq *hdr, void *data,
- unsigned int *wlen)
-{
- int ret;
-
- ret = qemu_co_send(sockfd, hdr, sizeof(*hdr));
- if (ret != sizeof(*hdr)) {
- error_report("failed to send a req, %s", strerror(errno));
- return -errno;
- }
-
- ret = qemu_co_send(sockfd, data, *wlen);
- if (ret != *wlen) {
- error_report("failed to send a req, %s", strerror(errno));
- return -errno;
- }
-
- return ret;
-}
-
-typedef struct SheepdogReqCo {
- int sockfd;
- BlockDriverState *bs;
- AioContext *aio_context;
- SheepdogReq *hdr;
- void *data;
- unsigned int *wlen;
- unsigned int *rlen;
- int ret;
- bool finished;
- Coroutine *co;
-} SheepdogReqCo;
-
-static void restart_co_req(void *opaque)
-{
- SheepdogReqCo *srco = opaque;
-
- aio_co_wake(srco->co);
-}
-
-static coroutine_fn void do_co_req(void *opaque)
-{
- int ret;
- SheepdogReqCo *srco = opaque;
- int sockfd = srco->sockfd;
- SheepdogReq *hdr = srco->hdr;
- void *data = srco->data;
- unsigned int *wlen = srco->wlen;
- unsigned int *rlen = srco->rlen;
-
- srco->co = qemu_coroutine_self();
- aio_set_fd_handler(srco->aio_context, sockfd, false,
- NULL, restart_co_req, NULL, srco);
-
- ret = send_co_req(sockfd, hdr, data, wlen);
- if (ret < 0) {
- goto out;
- }
-
- aio_set_fd_handler(srco->aio_context, sockfd, false,
- restart_co_req, NULL, NULL, srco);
-
- ret = qemu_co_recv(sockfd, hdr, sizeof(*hdr));
- if (ret != sizeof(*hdr)) {
- error_report("failed to get a rsp, %s", strerror(errno));
- ret = -errno;
- goto out;
- }
-
- if (*rlen > hdr->data_length) {
- *rlen = hdr->data_length;
- }
-
- if (*rlen) {
- ret = qemu_co_recv(sockfd, data, *rlen);
- if (ret != *rlen) {
- error_report("failed to get the data, %s", strerror(errno));
- ret = -errno;
- goto out;
- }
- }
- ret = 0;
-out:
- /* there is at most one request for this sockfd, so it is safe to
- * set each handler to NULL. */
- aio_set_fd_handler(srco->aio_context, sockfd, false,
- NULL, NULL, NULL, NULL);
-
- srco->co = NULL;
- srco->ret = ret;
- /* Set srco->finished before reading bs->wakeup. */
- qatomic_mb_set(&srco->finished, true);
- if (srco->bs) {
- bdrv_wakeup(srco->bs);
- }
-}
-
-/*
- * Send the request to the sheep in a synchronous manner.
- *
- * Return 0 on success, -errno in case of error.
- */
-static int do_req(int sockfd, BlockDriverState *bs, SheepdogReq *hdr,
- void *data, unsigned int *wlen, unsigned int *rlen)
-{
- Coroutine *co;
- SheepdogReqCo srco = {
- .sockfd = sockfd,
- .aio_context = bs ? bdrv_get_aio_context(bs) : qemu_get_aio_context(),
- .bs = bs,
- .hdr = hdr,
- .data = data,
- .wlen = wlen,
- .rlen = rlen,
- .ret = 0,
- .finished = false,
- };
-
- if (qemu_in_coroutine()) {
- do_co_req(&srco);
- } else {
- co = qemu_coroutine_create(do_co_req, &srco);
- if (bs) {
- bdrv_coroutine_enter(bs, co);
- BDRV_POLL_WHILE(bs, !srco.finished);
- } else {
- qemu_coroutine_enter(co);
- while (!srco.finished) {
- aio_poll(qemu_get_aio_context(), true);
- }
- }
- }
-
- return srco.ret;
-}
-
-static void coroutine_fn add_aio_request(BDRVSheepdogState *s, AIOReq *aio_req,
- struct iovec *iov, int niov,
- enum AIOCBState aiocb_type);
-static void coroutine_fn resend_aioreq(BDRVSheepdogState *s, AIOReq *aio_req);
-static int reload_inode(BDRVSheepdogState *s, uint32_t snapid, const char *tag);
-static int get_sheep_fd(BDRVSheepdogState *s, Error **errp);
-static void co_write_request(void *opaque);
-
-static coroutine_fn void reconnect_to_sdog(void *opaque)
-{
- BDRVSheepdogState *s = opaque;
- AIOReq *aio_req, *next;
-
- aio_set_fd_handler(s->aio_context, s->fd, false, NULL,
- NULL, NULL, NULL);
- close(s->fd);
- s->fd = -1;
-
- /* Wait for outstanding write requests to be completed. */
- while (s->co_send != NULL) {
- co_write_request(opaque);
- }
-
- /* Try to reconnect the sheepdog server every one second. */
- while (s->fd < 0) {
- Error *local_err = NULL;
- s->fd = get_sheep_fd(s, &local_err);
- if (s->fd < 0) {
- trace_sheepdog_reconnect_to_sdog();
- error_report_err(local_err);
- qemu_co_sleep_ns(QEMU_CLOCK_REALTIME, NANOSECONDS_PER_SECOND);
- }
- };
-
- /*
- * Now we have to resend all the request in the inflight queue. However,
- * resend_aioreq() can yield and newly created requests can be added to the
- * inflight queue before the coroutine is resumed. To avoid mixing them, we
- * have to move all the inflight requests to the failed queue before
- * resend_aioreq() is called.
- */
- qemu_co_mutex_lock(&s->queue_lock);
- QLIST_FOREACH_SAFE(aio_req, &s->inflight_aio_head, aio_siblings, next) {
- QLIST_REMOVE(aio_req, aio_siblings);
- QLIST_INSERT_HEAD(&s->failed_aio_head, aio_req, aio_siblings);
- }
-
- /* Resend all the failed aio requests. */
- while (!QLIST_EMPTY(&s->failed_aio_head)) {
- aio_req = QLIST_FIRST(&s->failed_aio_head);
- QLIST_REMOVE(aio_req, aio_siblings);
- qemu_co_mutex_unlock(&s->queue_lock);
- resend_aioreq(s, aio_req);
- qemu_co_mutex_lock(&s->queue_lock);
- }
- qemu_co_mutex_unlock(&s->queue_lock);
-}
-
-/*
- * Receive responses of the I/O requests.
- *
- * This function is registered as a fd handler, and called from the
- * main loop when s->fd is ready for reading responses.
- */
-static void coroutine_fn aio_read_response(void *opaque)
-{
- SheepdogObjRsp rsp;
- BDRVSheepdogState *s = opaque;
- int fd = s->fd;
- int ret;
- AIOReq *aio_req = NULL;
- SheepdogAIOCB *acb;
- uint64_t idx;
-
- /* read a header */
- ret = qemu_co_recv(fd, &rsp, sizeof(rsp));
- if (ret != sizeof(rsp)) {
- error_report("failed to get the header, %s", strerror(errno));
- goto err;
- }
-
- /* find the right aio_req from the inflight aio list */
- QLIST_FOREACH(aio_req, &s->inflight_aio_head, aio_siblings) {
- if (aio_req->id == rsp.id) {
- break;
- }
- }
- if (!aio_req) {
- error_report("cannot find aio_req %x", rsp.id);
- goto err;
- }
-
- acb = aio_req->aiocb;
-
- switch (acb->aiocb_type) {
- case AIOCB_WRITE_UDATA:
- if (!is_data_obj(aio_req->oid)) {
- break;
- }
- idx = data_oid_to_idx(aio_req->oid);
-
- if (aio_req->create) {
- /*
- * If the object is newly created one, we need to update
- * the vdi object (metadata object). min_dirty_data_idx
- * and max_dirty_data_idx are changed to include updated
- * index between them.
- */
- if (rsp.result == SD_RES_SUCCESS) {
- s->inode.data_vdi_id[idx] = s->inode.vdi_id;
- acb->max_dirty_data_idx = MAX(idx, acb->max_dirty_data_idx);
- acb->min_dirty_data_idx = MIN(idx, acb->min_dirty_data_idx);
- }
- }
- break;
- case AIOCB_READ_UDATA:
- ret = qemu_co_recvv(fd, acb->qiov->iov, acb->qiov->niov,
- aio_req->iov_offset, rsp.data_length);
- if (ret != rsp.data_length) {
- error_report("failed to get the data, %s", strerror(errno));
- goto err;
- }
- break;
- case AIOCB_FLUSH_CACHE:
- if (rsp.result == SD_RES_INVALID_PARMS) {
- trace_sheepdog_aio_read_response();
- s->cache_flags = SD_FLAG_CMD_DIRECT;
- rsp.result = SD_RES_SUCCESS;
- }
- break;
- case AIOCB_DISCARD_OBJ:
- switch (rsp.result) {
- case SD_RES_INVALID_PARMS:
- error_report("server doesn't support discard command");
- rsp.result = SD_RES_SUCCESS;
- s->discard_supported = false;
- break;
- default:
- break;
- }
- }
-
- /* No more data for this aio_req (reload_inode below uses its own file
- * descriptor handler which doesn't use co_recv).
- */
- s->co_recv = NULL;
-
- qemu_co_mutex_lock(&s->queue_lock);
- QLIST_REMOVE(aio_req, aio_siblings);
- qemu_co_mutex_unlock(&s->queue_lock);
-
- switch (rsp.result) {
- case SD_RES_SUCCESS:
- break;
- case SD_RES_READONLY:
- if (s->inode.vdi_id == oid_to_vid(aio_req->oid)) {
- ret = reload_inode(s, 0, "");
- if (ret < 0) {
- goto err;
- }
- }
- if (is_data_obj(aio_req->oid)) {
- aio_req->oid = vid_to_data_oid(s->inode.vdi_id,
- data_oid_to_idx(aio_req->oid));
- } else {
- aio_req->oid = vid_to_vdi_oid(s->inode.vdi_id);
- }
- resend_aioreq(s, aio_req);
- return;
- default:
- acb->ret = -EIO;
- error_report("%s", sd_strerror(rsp.result));
- break;
- }
-
- g_free(aio_req);
-
- if (!--acb->nr_pending) {
- /*
- * We've finished all requests which belong to the AIOCB, so
- * we can switch back to sd_co_readv/writev now.
- */
- aio_co_wake(acb->coroutine);
- }
-
- return;
-
-err:
- reconnect_to_sdog(opaque);
-}
-
-static void co_read_response(void *opaque)
-{
- BDRVSheepdogState *s = opaque;
-
- if (!s->co_recv) {
- s->co_recv = qemu_coroutine_create(aio_read_response, opaque);
- }
-
- aio_co_enter(s->aio_context, s->co_recv);
-}
-
-static void co_write_request(void *opaque)
-{
- BDRVSheepdogState *s = opaque;
-
- aio_co_wake(s->co_send);
-}
-
-/*
- * Return a socket descriptor to read/write objects.
- *
- * We cannot use this descriptor for other operations because
- * the block driver may be on waiting response from the server.
- */
-static int get_sheep_fd(BDRVSheepdogState *s, Error **errp)
-{
- int fd;
-
- fd = connect_to_sdog(s, errp);
- if (fd < 0) {
- return fd;
- }
-
- aio_set_fd_handler(s->aio_context, fd, false,
- co_read_response, NULL, NULL, s);
- return fd;
-}
-
-/*
- * Parse numeric snapshot ID in @str
- * If @str can't be parsed as number, return false.
- * Else, if the number is zero or too large, set *@snapid to zero and
- * return true.
- * Else, set *@snapid to the number and return true.
- */
-static bool sd_parse_snapid(const char *str, uint32_t *snapid)
-{
- unsigned long ul;
- int ret;
-
- ret = qemu_strtoul(str, NULL, 10, &ul);
- if (ret == -ERANGE) {
- ul = ret = 0;
- }
- if (ret) {
- return false;
- }
- if (ul > UINT32_MAX) {
- ul = 0;
- }
-
- *snapid = ul;
- return true;
-}
-
-static bool sd_parse_snapid_or_tag(const char *str,
- uint32_t *snapid, char tag[])
-{
- if (!sd_parse_snapid(str, snapid)) {
- *snapid = 0;
- if (g_strlcpy(tag, str, SD_MAX_VDI_TAG_LEN) >= SD_MAX_VDI_TAG_LEN) {
- return false;
- }
- } else if (!*snapid) {
- return false;
- } else {
- tag[0] = 0;
- }
- return true;
-}
-
-typedef struct {
- const char *path; /* non-null iff transport is tcp */
- const char *host; /* valid when transport is tcp */
- int port; /* valid when transport is tcp */
- char vdi[SD_MAX_VDI_LEN];
- char tag[SD_MAX_VDI_TAG_LEN];
- uint32_t snap_id;
- /* Remainder is only for sd_config_done() */
- URI *uri;
- QueryParams *qp;
-} SheepdogConfig;
-
-static void sd_config_done(SheepdogConfig *cfg)
-{
- if (cfg->qp) {
- query_params_free(cfg->qp);
- }
- uri_free(cfg->uri);
-}
-
-static void sd_parse_uri(SheepdogConfig *cfg, const char *filename,
- Error **errp)
-{
- Error *err = NULL;
- QueryParams *qp = NULL;
- bool is_unix;
- URI *uri;
-
- memset(cfg, 0, sizeof(*cfg));
-
- cfg->uri = uri = uri_parse(filename);
- if (!uri) {
- error_setg(&err, "invalid URI '%s'", filename);
- goto out;
- }
-
- /* transport */
- if (!g_strcmp0(uri->scheme, "sheepdog")) {
- is_unix = false;
- } else if (!g_strcmp0(uri->scheme, "sheepdog+tcp")) {
- is_unix = false;
- } else if (!g_strcmp0(uri->scheme, "sheepdog+unix")) {
- is_unix = true;
- } else {
- error_setg(&err, "URI scheme must be 'sheepdog', 'sheepdog+tcp',"
- " or 'sheepdog+unix'");
- goto out;
- }
-
- if (uri->path == NULL || !strcmp(uri->path, "/")) {
- error_setg(&err, "missing file path in URI");
- goto out;
- }
- if (g_strlcpy(cfg->vdi, uri->path + 1, SD_MAX_VDI_LEN)
- >= SD_MAX_VDI_LEN) {
- error_setg(&err, "VDI name is too long");
- goto out;
- }
-
- cfg->qp = qp = query_params_parse(uri->query);
-
- if (is_unix) {
- /* sheepdog+unix:///vdiname?socket=path */
- if (uri->server || uri->port) {
- error_setg(&err, "URI scheme %s doesn't accept a server address",
- uri->scheme);
- goto out;
- }
- if (!qp->n) {
- error_setg(&err,
- "URI scheme %s requires query parameter 'socket'",
- uri->scheme);
- goto out;
- }
- if (qp->n != 1 || strcmp(qp->p[0].name, "socket")) {
- error_setg(&err, "unexpected query parameters");
- goto out;
- }
- cfg->path = qp->p[0].value;
- } else {
- /* sheepdog[+tcp]://[host:port]/vdiname */
- if (qp->n) {
- error_setg(&err, "unexpected query parameters");
- goto out;
- }
- cfg->host = uri->server;
- cfg->port = uri->port;
- }
-
- /* snapshot tag */
- if (uri->fragment) {
- if (!sd_parse_snapid_or_tag(uri->fragment,
- &cfg->snap_id, cfg->tag)) {
- error_setg(&err, "'%s' is not a valid snapshot ID",
- uri->fragment);
- goto out;
- }
- } else {
- cfg->snap_id = CURRENT_VDI_ID; /* search current vdi */
- }
-
-out:
- if (err) {
- error_propagate(errp, err);
- sd_config_done(cfg);
- }
-}
-
-/*
- * Parse a filename (old syntax)
- *
- * filename must be one of the following formats:
- * 1. [vdiname]
- * 2. [vdiname]:[snapid]
- * 3. [vdiname]:[tag]
- * 4. [hostname]:[port]:[vdiname]
- * 5. [hostname]:[port]:[vdiname]:[snapid]
- * 6. [hostname]:[port]:[vdiname]:[tag]
- *
- * You can boot from the snapshot images by specifying `snapid` or
- * `tag'.
- *
- * You can run VMs outside the Sheepdog cluster by specifying
- * `hostname' and `port' (experimental).
- */
-static void parse_vdiname(SheepdogConfig *cfg, const char *filename,
- Error **errp)
-{
- Error *err = NULL;
- char *p, *q, *uri;
- const char *host_spec, *vdi_spec;
- int nr_sep;
-
- strstart(filename, "sheepdog:", &filename);
- p = q = g_strdup(filename);
-
- /* count the number of separators */
- nr_sep = 0;
- while (*p) {
- if (*p == ':') {
- nr_sep++;
- }
- p++;
- }
- p = q;
-
- /* use the first two tokens as host_spec. */
- if (nr_sep >= 2) {
- host_spec = p;
- p = strchr(p, ':');
- p++;
- p = strchr(p, ':');
- *p++ = '\0';
- } else {
- host_spec = "";
- }
-
- vdi_spec = p;
-
- p = strchr(vdi_spec, ':');
- if (p) {
- *p++ = '#';
- }
-
- uri = g_strdup_printf("sheepdog://%s/%s", host_spec, vdi_spec);
-
- /*
- * FIXME We to escape URI meta-characters, e.g. "x?y=z"
- * produces "sheepdog://x?y=z". Because of that ...
- */
- sd_parse_uri(cfg, uri, &err);
- if (err) {
- /*
- * ... this can fail, but the error message is misleading.
- * Replace it by the traditional useless one until the
- * escaping is fixed.
- */
- error_free(err);
- error_setg(errp, "Can't parse filename");
- }
-
- g_free(q);
- g_free(uri);
-}
-
-static void sd_parse_filename(const char *filename, QDict *options,
- Error **errp)
-{
- Error *err = NULL;
- SheepdogConfig cfg;
- char buf[32];
-
- if (strstr(filename, "://")) {
- sd_parse_uri(&cfg, filename, &err);
- } else {
- parse_vdiname(&cfg, filename, &err);
- }
- if (err) {
- error_propagate(errp, err);
- return;
- }
-
- if (cfg.path) {
- qdict_set_default_str(options, "server.path", cfg.path);
- qdict_set_default_str(options, "server.type", "unix");
- } else {
- qdict_set_default_str(options, "server.type", "inet");
- qdict_set_default_str(options, "server.host",
- cfg.host ?: SD_DEFAULT_ADDR);
- snprintf(buf, sizeof(buf), "%d", cfg.port ?: SD_DEFAULT_PORT);
- qdict_set_default_str(options, "server.port", buf);
- }
- qdict_set_default_str(options, "vdi", cfg.vdi);
- qdict_set_default_str(options, "tag", cfg.tag);
- if (cfg.snap_id) {
- snprintf(buf, sizeof(buf), "%d", cfg.snap_id);
- qdict_set_default_str(options, "snap-id", buf);
- }
-
- sd_config_done(&cfg);
-}
-
-static int find_vdi_name(BDRVSheepdogState *s, const char *filename,
- uint32_t snapid, const char *tag, uint32_t *vid,
- bool lock, Error **errp)
-{
- int ret, fd;
- SheepdogVdiReq hdr;
- SheepdogVdiRsp *rsp = (SheepdogVdiRsp *)&hdr;
- unsigned int wlen, rlen = 0;
- char buf[SD_MAX_VDI_LEN + SD_MAX_VDI_TAG_LEN] QEMU_NONSTRING;
-
- fd = connect_to_sdog(s, errp);
- if (fd < 0) {
- return fd;
- }
-
- /* This pair of strncpy calls ensures that the buffer is zero-filled,
- * which is desirable since we'll soon be sending those bytes, and
- * don't want the send_req to read uninitialized data.
- */
- strncpy(buf, filename, SD_MAX_VDI_LEN);
- strncpy(buf + SD_MAX_VDI_LEN, tag, SD_MAX_VDI_TAG_LEN);
-
- memset(&hdr, 0, sizeof(hdr));
- if (lock) {
- hdr.opcode = SD_OP_LOCK_VDI;
- hdr.type = LOCK_TYPE_NORMAL;
- } else {
- hdr.opcode = SD_OP_GET_VDI_INFO;
- }
- wlen = SD_MAX_VDI_LEN + SD_MAX_VDI_TAG_LEN;
- hdr.proto_ver = SD_PROTO_VER;
- hdr.data_length = wlen;
- hdr.snapid = snapid;
- hdr.flags = SD_FLAG_CMD_WRITE;
-
- ret = do_req(fd, s->bs, (SheepdogReq *)&hdr, buf, &wlen, &rlen);
- if (ret) {
- error_setg_errno(errp, -ret, "cannot get vdi info");
- goto out;
- }
-
- if (rsp->result != SD_RES_SUCCESS) {
- error_setg(errp, "cannot get vdi info, %s, %s %" PRIu32 " %s",
- sd_strerror(rsp->result), filename, snapid, tag);
- if (rsp->result == SD_RES_NO_VDI) {
- ret = -ENOENT;
- } else if (rsp->result == SD_RES_VDI_LOCKED) {
- ret = -EBUSY;
- } else {
- ret = -EIO;
- }
- goto out;
- }
- *vid = rsp->vdi_id;
-
- ret = 0;
-out:
- closesocket(fd);
- return ret;
-}
-
-static void coroutine_fn add_aio_request(BDRVSheepdogState *s, AIOReq *aio_req,
- struct iovec *iov, int niov,
- enum AIOCBState aiocb_type)
-{
- int nr_copies = s->inode.nr_copies;
- SheepdogObjReq hdr;
- unsigned int wlen = 0;
- int ret;
- uint64_t oid = aio_req->oid;
- unsigned int datalen = aio_req->data_len;
- uint64_t offset = aio_req->offset;
- uint8_t flags = aio_req->flags;
- uint64_t old_oid = aio_req->base_oid;
- bool create = aio_req->create;
-
- qemu_co_mutex_lock(&s->queue_lock);
- QLIST_INSERT_HEAD(&s->inflight_aio_head, aio_req, aio_siblings);
- qemu_co_mutex_unlock(&s->queue_lock);
-
- if (!nr_copies) {
- error_report("bug");
- }
-
- memset(&hdr, 0, sizeof(hdr));
-
- switch (aiocb_type) {
- case AIOCB_FLUSH_CACHE:
- hdr.opcode = SD_OP_FLUSH_VDI;
- break;
- case AIOCB_READ_UDATA:
- hdr.opcode = SD_OP_READ_OBJ;
- hdr.flags = flags;
- break;
- case AIOCB_WRITE_UDATA:
- if (create) {
- hdr.opcode = SD_OP_CREATE_AND_WRITE_OBJ;
- } else {
- hdr.opcode = SD_OP_WRITE_OBJ;
- }
- wlen = datalen;
- hdr.flags = SD_FLAG_CMD_WRITE | flags;
- break;
- case AIOCB_DISCARD_OBJ:
- hdr.opcode = SD_OP_WRITE_OBJ;
- hdr.flags = SD_FLAG_CMD_WRITE | flags;
- s->inode.data_vdi_id[data_oid_to_idx(oid)] = 0;
- offset = offsetof(SheepdogInode,
- data_vdi_id[data_oid_to_idx(oid)]);
- oid = vid_to_vdi_oid(s->inode.vdi_id);
- wlen = datalen = sizeof(uint32_t);
- break;
- }
-
- if (s->cache_flags) {
- hdr.flags |= s->cache_flags;
- }
-
- hdr.oid = oid;
- hdr.cow_oid = old_oid;
- hdr.copies = s->inode.nr_copies;
-
- hdr.data_length = datalen;
- hdr.offset = offset;
-
- hdr.id = aio_req->id;
-
- qemu_co_mutex_lock(&s->lock);
- s->co_send = qemu_coroutine_self();
- aio_set_fd_handler(s->aio_context, s->fd, false,
- co_read_response, co_write_request, NULL, s);
- socket_set_cork(s->fd, 1);
-
- /* send a header */
- ret = qemu_co_send(s->fd, &hdr, sizeof(hdr));
- if (ret != sizeof(hdr)) {
- error_report("failed to send a req, %s", strerror(errno));
- goto out;
- }
-
- if (wlen) {
- ret = qemu_co_sendv(s->fd, iov, niov, aio_req->iov_offset, wlen);
- if (ret != wlen) {
- error_report("failed to send a data, %s", strerror(errno));
- }
- }
-out:
- socket_set_cork(s->fd, 0);
- aio_set_fd_handler(s->aio_context, s->fd, false,
- co_read_response, NULL, NULL, s);
- s->co_send = NULL;
- qemu_co_mutex_unlock(&s->lock);
-}
-
-static int read_write_object(int fd, BlockDriverState *bs, char *buf,
- uint64_t oid, uint8_t copies,
- unsigned int datalen, uint64_t offset,
- bool write, bool create, uint32_t cache_flags)
-{
- SheepdogObjReq hdr;
- SheepdogObjRsp *rsp = (SheepdogObjRsp *)&hdr;
- unsigned int wlen, rlen;
- int ret;
-
- memset(&hdr, 0, sizeof(hdr));
-
- if (write) {
- wlen = datalen;
- rlen = 0;
- hdr.flags = SD_FLAG_CMD_WRITE;
- if (create) {
- hdr.opcode = SD_OP_CREATE_AND_WRITE_OBJ;
- } else {
- hdr.opcode = SD_OP_WRITE_OBJ;
- }
- } else {
- wlen = 0;
- rlen = datalen;
- hdr.opcode = SD_OP_READ_OBJ;
- }
-
- hdr.flags |= cache_flags;
-
- hdr.oid = oid;
- hdr.data_length = datalen;
- hdr.offset = offset;
- hdr.copies = copies;
-
- ret = do_req(fd, bs, (SheepdogReq *)&hdr, buf, &wlen, &rlen);
- if (ret) {
- error_report("failed to send a request to the sheep");
- return ret;
- }
-
- switch (rsp->result) {
- case SD_RES_SUCCESS:
- return 0;
- default:
- error_report("%s", sd_strerror(rsp->result));
- return -EIO;
- }
-}
-
-static int read_object(int fd, BlockDriverState *bs, char *buf,
- uint64_t oid, uint8_t copies,
- unsigned int datalen, uint64_t offset,
- uint32_t cache_flags)
-{
- return read_write_object(fd, bs, buf, oid, copies,
- datalen, offset, false,
- false, cache_flags);
-}
-
-static int write_object(int fd, BlockDriverState *bs, char *buf,
- uint64_t oid, uint8_t copies,
- unsigned int datalen, uint64_t offset, bool create,
- uint32_t cache_flags)
-{
- return read_write_object(fd, bs, buf, oid, copies,
- datalen, offset, true,
- create, cache_flags);
-}
-
-/* update inode with the latest state */
-static int reload_inode(BDRVSheepdogState *s, uint32_t snapid, const char *tag)
-{
- Error *local_err = NULL;
- SheepdogInode *inode;
- int ret = 0, fd;
- uint32_t vid = 0;
-
- fd = connect_to_sdog(s, &local_err);
- if (fd < 0) {
- error_report_err(local_err);
- return -EIO;
- }
-
- inode = g_malloc(SD_INODE_HEADER_SIZE);
-
- ret = find_vdi_name(s, s->name, snapid, tag, &vid, false, &local_err);
- if (ret) {
- error_report_err(local_err);
- goto out;
- }
-
- ret = read_object(fd, s->bs, (char *)inode, vid_to_vdi_oid(vid),
- s->inode.nr_copies, SD_INODE_HEADER_SIZE, 0,
- s->cache_flags);
- if (ret < 0) {
- goto out;
- }
-
- if (inode->vdi_id != s->inode.vdi_id) {
- memcpy(&s->inode, inode, SD_INODE_HEADER_SIZE);
- }
-
-out:
- g_free(inode);
- closesocket(fd);
-
- return ret;
-}
-
-static void coroutine_fn resend_aioreq(BDRVSheepdogState *s, AIOReq *aio_req)
-{
- SheepdogAIOCB *acb = aio_req->aiocb;
-
- aio_req->create = false;
-
- /* check whether this request becomes a CoW one */
- if (acb->aiocb_type == AIOCB_WRITE_UDATA && is_data_obj(aio_req->oid)) {
- int idx = data_oid_to_idx(aio_req->oid);
-
- if (is_data_obj_writable(&s->inode, idx)) {
- goto out;
- }
-
- if (s->inode.data_vdi_id[idx]) {
- aio_req->base_oid = vid_to_data_oid(s->inode.data_vdi_id[idx], idx);
- aio_req->flags |= SD_FLAG_CMD_COW;
- }
- aio_req->create = true;
- }
-out:
- if (is_data_obj(aio_req->oid)) {
- add_aio_request(s, aio_req, acb->qiov->iov, acb->qiov->niov,
- acb->aiocb_type);
- } else {
- struct iovec iov;
- iov.iov_base = &s->inode;
- iov.iov_len = sizeof(s->inode);
- add_aio_request(s, aio_req, &iov, 1, AIOCB_WRITE_UDATA);
- }
-}
-
-static void sd_detach_aio_context(BlockDriverState *bs)
-{
- BDRVSheepdogState *s = bs->opaque;
-
- aio_set_fd_handler(s->aio_context, s->fd, false, NULL,
- NULL, NULL, NULL);
-}
-
-static void sd_attach_aio_context(BlockDriverState *bs,
- AioContext *new_context)
-{
- BDRVSheepdogState *s = bs->opaque;
-
- s->aio_context = new_context;
- aio_set_fd_handler(new_context, s->fd, false,
- co_read_response, NULL, NULL, s);
-}
-
-static QemuOptsList runtime_opts = {
- .name = "sheepdog",
- .head = QTAILQ_HEAD_INITIALIZER(runtime_opts.head),
- .desc = {
- {
- .name = "vdi",
- .type = QEMU_OPT_STRING,
- },
- {
- .name = "snap-id",
- .type = QEMU_OPT_NUMBER,
- },
- {
- .name = "tag",
- .type = QEMU_OPT_STRING,
- },
- { /* end of list */ }
- },
-};
-
-static int sd_open(BlockDriverState *bs, QDict *options, int flags,
- Error **errp)
-{
- int ret, fd;
- uint32_t vid = 0;
- BDRVSheepdogState *s = bs->opaque;
- const char *vdi, *snap_id_str, *tag;
- uint64_t snap_id;
- char *buf = NULL;
- QemuOpts *opts;
-
- deprecation_warning();
-
- s->bs = bs;
- s->aio_context = bdrv_get_aio_context(bs);
-
- opts = qemu_opts_create(&runtime_opts, NULL, 0, &error_abort);
- if (!qemu_opts_absorb_qdict(opts, options, errp)) {
- ret = -EINVAL;
- goto err_no_fd;
- }
-
- s->addr = sd_server_config(options, errp);
- if (!s->addr) {
- ret = -EINVAL;
- goto err_no_fd;
- }
-
- vdi = qemu_opt_get(opts, "vdi");
- snap_id_str = qemu_opt_get(opts, "snap-id");
- snap_id = qemu_opt_get_number(opts, "snap-id", CURRENT_VDI_ID);
- tag = qemu_opt_get(opts, "tag");
-
- if (!vdi) {
- error_setg(errp, "parameter 'vdi' is missing");
- ret = -EINVAL;
- goto err_no_fd;
- }
- if (strlen(vdi) >= SD_MAX_VDI_LEN) {
- error_setg(errp, "value of parameter 'vdi' is too long");
- ret = -EINVAL;
- goto err_no_fd;
- }
-
- if (snap_id > UINT32_MAX) {
- snap_id = 0;
- }
- if (snap_id_str && !snap_id) {
- error_setg(errp, "'snap-id=%s' is not a valid snapshot ID",
- snap_id_str);
- ret = -EINVAL;
- goto err_no_fd;
- }
-
- if (!tag) {
- tag = "";
- }
- if (strlen(tag) >= SD_MAX_VDI_TAG_LEN) {
- error_setg(errp, "value of parameter 'tag' is too long");
- ret = -EINVAL;
- goto err_no_fd;
- }
-
- QLIST_INIT(&s->inflight_aio_head);
- QLIST_INIT(&s->failed_aio_head);
- QLIST_INIT(&s->inflight_aiocb_head);
-
- s->fd = get_sheep_fd(s, errp);
- if (s->fd < 0) {
- ret = s->fd;
- goto err_no_fd;
- }
-
- ret = find_vdi_name(s, vdi, (uint32_t)snap_id, tag, &vid, true, errp);
- if (ret) {
- goto err;
- }
-
- /*
- * QEMU block layer emulates writethrough cache as 'writeback + flush', so
- * we always set SD_FLAG_CMD_CACHE (writeback cache) as default.
- */
- s->cache_flags = SD_FLAG_CMD_CACHE;
- if (flags & BDRV_O_NOCACHE) {
- s->cache_flags = SD_FLAG_CMD_DIRECT;
- }
- s->discard_supported = true;
-
- if (snap_id || tag[0]) {
- trace_sheepdog_open(vid);
- s->is_snapshot = true;
- }
-
- fd = connect_to_sdog(s, errp);
- if (fd < 0) {
- ret = fd;
- goto err;
- }
-
- buf = g_malloc(SD_INODE_SIZE);
- ret = read_object(fd, s->bs, buf, vid_to_vdi_oid(vid),
- 0, SD_INODE_SIZE, 0, s->cache_flags);
-
- closesocket(fd);
-
- if (ret) {
- error_setg(errp, "Can't read snapshot inode");
- goto err;
- }
-
- memcpy(&s->inode, buf, sizeof(s->inode));
-
- bs->total_sectors = s->inode.vdi_size / BDRV_SECTOR_SIZE;
- bs->supported_truncate_flags = BDRV_REQ_ZERO_WRITE;
- pstrcpy(s->name, sizeof(s->name), vdi);
- qemu_co_mutex_init(&s->lock);
- qemu_co_mutex_init(&s->queue_lock);
- qemu_co_queue_init(&s->overlapping_queue);
- qemu_opts_del(opts);
- g_free(buf);
- return 0;
-
-err:
- aio_set_fd_handler(bdrv_get_aio_context(bs), s->fd,
- false, NULL, NULL, NULL, NULL);
- closesocket(s->fd);
-err_no_fd:
- qemu_opts_del(opts);
- g_free(buf);
- return ret;
-}
-
-static int sd_reopen_prepare(BDRVReopenState *state, BlockReopenQueue *queue,
- Error **errp)
-{
- BDRVSheepdogState *s = state->bs->opaque;
- BDRVSheepdogReopenState *re_s;
- int ret = 0;
-
- re_s = state->opaque = g_new0(BDRVSheepdogReopenState, 1);
-
- re_s->cache_flags = SD_FLAG_CMD_CACHE;
- if (state->flags & BDRV_O_NOCACHE) {
- re_s->cache_flags = SD_FLAG_CMD_DIRECT;
- }
-
- re_s->fd = get_sheep_fd(s, errp);
- if (re_s->fd < 0) {
- ret = re_s->fd;
- return ret;
- }
-
- return ret;
-}
-
-static void sd_reopen_commit(BDRVReopenState *state)
-{
- BDRVSheepdogReopenState *re_s = state->opaque;
- BDRVSheepdogState *s = state->bs->opaque;
-
- if (s->fd) {
- aio_set_fd_handler(s->aio_context, s->fd, false,
- NULL, NULL, NULL, NULL);
- closesocket(s->fd);
- }
-
- s->fd = re_s->fd;
- s->cache_flags = re_s->cache_flags;
-
- g_free(state->opaque);
- state->opaque = NULL;
-
- return;
-}
-
-static void sd_reopen_abort(BDRVReopenState *state)
-{
- BDRVSheepdogReopenState *re_s = state->opaque;
- BDRVSheepdogState *s = state->bs->opaque;
-
- if (re_s == NULL) {
- return;
- }
-
- if (re_s->fd) {
- aio_set_fd_handler(s->aio_context, re_s->fd, false,
- NULL, NULL, NULL, NULL);
- closesocket(re_s->fd);
- }
-
- g_free(state->opaque);
- state->opaque = NULL;
-
- return;
-}
-
-static int do_sd_create(BDRVSheepdogState *s, uint32_t *vdi_id, int snapshot,
- Error **errp)
-{
- SheepdogVdiReq hdr;
- SheepdogVdiRsp *rsp = (SheepdogVdiRsp *)&hdr;
- int fd, ret;
- unsigned int wlen, rlen = 0;
- char buf[SD_MAX_VDI_LEN];
-
- fd = connect_to_sdog(s, errp);
- if (fd < 0) {
- return fd;
- }
-
- /* FIXME: would it be better to fail (e.g., return -EIO) when filename
- * does not fit in buf? For now, just truncate and avoid buffer overrun.
- */
- memset(buf, 0, sizeof(buf));
- pstrcpy(buf, sizeof(buf), s->name);
-
- memset(&hdr, 0, sizeof(hdr));
- hdr.opcode = SD_OP_NEW_VDI;
- hdr.base_vdi_id = s->inode.vdi_id;
-
- wlen = SD_MAX_VDI_LEN;
-
- hdr.flags = SD_FLAG_CMD_WRITE;
- hdr.snapid = snapshot;
-
- hdr.data_length = wlen;
- hdr.vdi_size = s->inode.vdi_size;
- hdr.copy_policy = s->inode.copy_policy;
- hdr.copies = s->inode.nr_copies;
- hdr.block_size_shift = s->inode.block_size_shift;
-
- ret = do_req(fd, NULL, (SheepdogReq *)&hdr, buf, &wlen, &rlen);
-
- closesocket(fd);
-
- if (ret) {
- error_setg_errno(errp, -ret, "create failed");
- return ret;
- }
-
- if (rsp->result != SD_RES_SUCCESS) {
- error_setg(errp, "%s, %s", sd_strerror(rsp->result), s->inode.name);
- return -EIO;
- }
-
- if (vdi_id) {
- *vdi_id = rsp->vdi_id;
- }
-
- return 0;
-}
-
-static int sd_prealloc(BlockDriverState *bs, int64_t old_size, int64_t new_size,
- Error **errp)
-{
- BlockBackend *blk = NULL;
- BDRVSheepdogState *base = bs->opaque;
- unsigned long buf_size;
- uint32_t idx, max_idx;
- uint32_t object_size;
- void *buf = NULL;
- int ret;
-
- blk = blk_new_with_bs(bs,
- BLK_PERM_CONSISTENT_READ | BLK_PERM_WRITE | BLK_PERM_RESIZE,
- BLK_PERM_ALL, errp);
-
- if (!blk) {
- ret = -EPERM;
- goto out_with_err_set;
- }
-
- blk_set_allow_write_beyond_eof(blk, true);
-
- object_size = (UINT32_C(1) << base->inode.block_size_shift);
- buf_size = MIN(object_size, SD_DATA_OBJ_SIZE);
- buf = g_malloc0(buf_size);
-
- max_idx = DIV_ROUND_UP(new_size, buf_size);
-
- for (idx = old_size / buf_size; idx < max_idx; idx++) {
- /*
- * The created image can be a cloned image, so we need to read
- * a data from the source image.
- */
- ret = blk_pread(blk, idx * buf_size, buf, buf_size);
- if (ret < 0) {
- goto out;
- }
- ret = blk_pwrite(blk, idx * buf_size, buf, buf_size, 0);
- if (ret < 0) {
- goto out;
- }
- }
-
- ret = 0;
-out:
- if (ret < 0) {
- error_setg_errno(errp, -ret, "Can't pre-allocate");
- }
-out_with_err_set:
- blk_unref(blk);
- g_free(buf);
-
- return ret;
-}
-
-static int sd_create_prealloc(BlockdevOptionsSheepdog *location, int64_t size,
- Error **errp)
-{
- BlockDriverState *bs;
- Visitor *v;
- QObject *obj = NULL;
- QDict *qdict;
- int ret;
-
- v = qobject_output_visitor_new(&obj);
- visit_type_BlockdevOptionsSheepdog(v, NULL, &location, &error_abort);
- visit_free(v);
-
- qdict = qobject_to(QDict, obj);
- qdict_flatten(qdict);
-
- qdict_put_str(qdict, "driver", "sheepdog");
-
- bs = bdrv_open(NULL, NULL, qdict, BDRV_O_PROTOCOL | BDRV_O_RDWR, errp);
- if (bs == NULL) {
- ret = -EIO;
- goto fail;
- }
-
- ret = sd_prealloc(bs, 0, size, errp);
-fail:
- bdrv_unref(bs);
- qobject_unref(qdict);
- return ret;
-}
-
-static int parse_redundancy(BDRVSheepdogState *s, SheepdogRedundancy *opt)
-{
- struct SheepdogInode *inode = &s->inode;
-
- switch (opt->type) {
- case SHEEPDOG_REDUNDANCY_TYPE_FULL:
- if (opt->u.full.copies > SD_MAX_COPIES || opt->u.full.copies < 1) {
- return -EINVAL;
- }
- inode->copy_policy = 0;
- inode->nr_copies = opt->u.full.copies;
- return 0;
-
- case SHEEPDOG_REDUNDANCY_TYPE_ERASURE_CODED:
- {
- int64_t copy = opt->u.erasure_coded.data_strips;
- int64_t parity = opt->u.erasure_coded.parity_strips;
-
- if (copy != 2 && copy != 4 && copy != 8 && copy != 16) {
- return -EINVAL;
- }
-
- if (parity >= SD_EC_MAX_STRIP || parity < 1) {
- return -EINVAL;
- }
-
- /*
- * 4 bits for parity and 4 bits for data.
- * We have to compress upper data bits because it can't represent 16
- */
- inode->copy_policy = ((copy / 2) << 4) + parity;
- inode->nr_copies = copy + parity;
- return 0;
- }
-
- default:
- g_assert_not_reached();
- }
-
- return -EINVAL;
-}
-
-/*
- * Sheepdog support two kinds of redundancy, full replication and erasure
- * coding.
- *
- * # create a fully replicated vdi with x copies
- * -o redundancy=x (1 <= x <= SD_MAX_COPIES)
- *
- * # create a erasure coded vdi with x data strips and y parity strips
- * -o redundancy=x:y (x must be one of {2,4,8,16} and 1 <= y < SD_EC_MAX_STRIP)
- */
-static SheepdogRedundancy *parse_redundancy_str(const char *opt)
-{
- SheepdogRedundancy *redundancy;
- const char *n1, *n2;
- long copy, parity;
- char p[10];
- int ret;
-
- pstrcpy(p, sizeof(p), opt);
- n1 = strtok(p, ":");
- n2 = strtok(NULL, ":");
-
- if (!n1) {
- return NULL;
- }
-
- ret = qemu_strtol(n1, NULL, 10, &copy);
- if (ret < 0) {
- return NULL;
- }
-
- redundancy = g_new0(SheepdogRedundancy, 1);
- if (!n2) {
- *redundancy = (SheepdogRedundancy) {
- .type = SHEEPDOG_REDUNDANCY_TYPE_FULL,
- .u.full.copies = copy,
- };
- } else {
- ret = qemu_strtol(n2, NULL, 10, &parity);
- if (ret < 0) {
- g_free(redundancy);
- return NULL;
- }
-
- *redundancy = (SheepdogRedundancy) {
- .type = SHEEPDOG_REDUNDANCY_TYPE_ERASURE_CODED,
- .u.erasure_coded = {
- .data_strips = copy,
- .parity_strips = parity,
- },
- };
- }
-
- return redundancy;
-}
-
-static int parse_block_size_shift(BDRVSheepdogState *s,
- BlockdevCreateOptionsSheepdog *opts)
-{
- struct SheepdogInode *inode = &s->inode;
- uint64_t object_size;
- int obj_order;
-
- if (opts->has_object_size) {
- object_size = opts->object_size;
-
- if ((object_size - 1) & object_size) { /* not a power of 2? */
- return -EINVAL;
- }
- obj_order = ctz32(object_size);
- if (obj_order < 20 || obj_order > 31) {
- return -EINVAL;
- }
- inode->block_size_shift = (uint8_t)obj_order;
- }
-
- return 0;
-}
-
-static int sd_co_create(BlockdevCreateOptions *options, Error **errp)
-{
- BlockdevCreateOptionsSheepdog *opts = &options->u.sheepdog;
- int ret = 0;
- uint32_t vid = 0;
- char *backing_file = NULL;
- char *buf = NULL;
- BDRVSheepdogState *s;
- uint64_t max_vdi_size;
- bool prealloc = false;
-
- assert(options->driver == BLOCKDEV_DRIVER_SHEEPDOG);
-
- deprecation_warning();
-
- s = g_new0(BDRVSheepdogState, 1);
-
- /* Steal SocketAddress from QAPI, set NULL to prevent double free */
- s->addr = opts->location->server;
- opts->location->server = NULL;
-
- if (strlen(opts->location->vdi) >= sizeof(s->name)) {
- error_setg(errp, "'vdi' string too long");
- ret = -EINVAL;
- goto out;
- }
- pstrcpy(s->name, sizeof(s->name), opts->location->vdi);
-
- s->inode.vdi_size = opts->size;
- backing_file = opts->backing_file;
-
- if (!opts->has_preallocation) {
- opts->preallocation = PREALLOC_MODE_OFF;
- }
- switch (opts->preallocation) {
- case PREALLOC_MODE_OFF:
- prealloc = false;
- break;
- case PREALLOC_MODE_FULL:
- prealloc = true;
- break;
- default:
- error_setg(errp, "Preallocation mode not supported for Sheepdog");
- ret = -EINVAL;
- goto out;
- }
-
- if (opts->has_redundancy) {
- ret = parse_redundancy(s, opts->redundancy);
- if (ret < 0) {
- error_setg(errp, "Invalid redundancy mode");
- goto out;
- }
- }
- ret = parse_block_size_shift(s, opts);
- if (ret < 0) {
- error_setg(errp, "Invalid object_size."
- " obect_size needs to be power of 2"
- " and be limited from 2^20 to 2^31");
- goto out;
- }
-
- if (opts->has_backing_file) {
- BlockBackend *blk;
- BDRVSheepdogState *base;
- BlockDriver *drv;
-
- /* Currently, only Sheepdog backing image is supported. */
- drv = bdrv_find_protocol(opts->backing_file, true, NULL);
- if (!drv || strcmp(drv->protocol_name, "sheepdog") != 0) {
- error_setg(errp, "backing_file must be a sheepdog image");
- ret = -EINVAL;
- goto out;
- }
-
- blk = blk_new_open(opts->backing_file, NULL, NULL,
- BDRV_O_PROTOCOL, errp);
- if (blk == NULL) {
- ret = -EIO;
- goto out;
- }
-
- base = blk_bs(blk)->opaque;
-
- if (!is_snapshot(&base->inode)) {
- error_setg(errp, "cannot clone from a non snapshot vdi");
- blk_unref(blk);
- ret = -EINVAL;
- goto out;
- }
- s->inode.vdi_id = base->inode.vdi_id;
- blk_unref(blk);
- }
-
- s->aio_context = qemu_get_aio_context();
-
- /* if block_size_shift is not specified, get cluster default value */
- if (s->inode.block_size_shift == 0) {
- SheepdogVdiReq hdr;
- SheepdogClusterRsp *rsp = (SheepdogClusterRsp *)&hdr;
- int fd;
- unsigned int wlen = 0, rlen = 0;
-
- fd = connect_to_sdog(s, errp);
- if (fd < 0) {
- ret = fd;
- goto out;
- }
-
- memset(&hdr, 0, sizeof(hdr));
- hdr.opcode = SD_OP_GET_CLUSTER_DEFAULT;
- hdr.proto_ver = SD_PROTO_VER;
-
- ret = do_req(fd, NULL, (SheepdogReq *)&hdr,
- NULL, &wlen, &rlen);
- closesocket(fd);
- if (ret) {
- error_setg_errno(errp, -ret, "failed to get cluster default");
- goto out;
- }
- if (rsp->result == SD_RES_SUCCESS) {
- s->inode.block_size_shift = rsp->block_size_shift;
- } else {
- s->inode.block_size_shift = SD_DEFAULT_BLOCK_SIZE_SHIFT;
- }
- }
-
- max_vdi_size = (UINT64_C(1) << s->inode.block_size_shift) * MAX_DATA_OBJS;
-
- if (s->inode.vdi_size > max_vdi_size) {
- error_setg(errp, "An image is too large."
- " The maximum image size is %"PRIu64 "GB",
- max_vdi_size / 1024 / 1024 / 1024);
- ret = -EINVAL;
- goto out;
- }
-
- ret = do_sd_create(s, &vid, 0, errp);
- if (ret) {
- goto out;
- }
-
- if (prealloc) {
- ret = sd_create_prealloc(opts->location, opts->size, errp);
- }
-out:
- g_free(backing_file);
- g_free(buf);
- g_free(s->addr);
- g_free(s);
- return ret;
-}
-
-static int coroutine_fn sd_co_create_opts(BlockDriver *drv,
- const char *filename,
- QemuOpts *opts,
- Error **errp)
-{
- BlockdevCreateOptions *create_options = NULL;
- QDict *qdict = NULL, *location_qdict;
- Visitor *v;
- char *redundancy = NULL;
- Error *local_err = NULL;
- int ret;
- char *backing_fmt = NULL;
-
- redundancy = qemu_opt_get_del(opts, BLOCK_OPT_REDUNDANCY);
- backing_fmt = qemu_opt_get_del(opts, BLOCK_OPT_BACKING_FMT);
-
- if (backing_fmt && strcmp(backing_fmt, "sheepdog") != 0) {
- error_setg(errp, "backing_file must be a sheepdog image");
- ret = -EINVAL;
- goto fail;
- }
-
- qdict = qemu_opts_to_qdict(opts, NULL);
- qdict_put_str(qdict, "driver", "sheepdog");
-
- location_qdict = qdict_new();
- qdict_put(qdict, "location", location_qdict);
-
- sd_parse_filename(filename, location_qdict, &local_err);
- if (local_err) {
- error_propagate(errp, local_err);
- ret = -EINVAL;
- goto fail;
- }
-
- qdict_flatten(qdict);
-
- /* Change legacy command line options into QMP ones */
- static const QDictRenames opt_renames[] = {
- { BLOCK_OPT_BACKING_FILE, "backing-file" },
- { BLOCK_OPT_OBJECT_SIZE, "object-size" },
- { NULL, NULL },
- };
-
- if (!qdict_rename_keys(qdict, opt_renames, errp)) {
- ret = -EINVAL;
- goto fail;
- }
-
- /* Get the QAPI object */
- v = qobject_input_visitor_new_flat_confused(qdict, errp);
- if (!v) {
- ret = -EINVAL;
- goto fail;
- }
-
- visit_type_BlockdevCreateOptions(v, NULL, &create_options, errp);
- visit_free(v);
- if (!create_options) {
- ret = -EINVAL;
- goto fail;
- }
-
- assert(create_options->driver == BLOCKDEV_DRIVER_SHEEPDOG);
- create_options->u.sheepdog.size =
- ROUND_UP(create_options->u.sheepdog.size, BDRV_SECTOR_SIZE);
-
- if (redundancy) {
- create_options->u.sheepdog.has_redundancy = true;
- create_options->u.sheepdog.redundancy =
- parse_redundancy_str(redundancy);
- if (create_options->u.sheepdog.redundancy == NULL) {
- error_setg(errp, "Invalid redundancy mode");
- ret = -EINVAL;
- goto fail;
- }
- }
-
- ret = sd_co_create(create_options, errp);
-fail:
- qapi_free_BlockdevCreateOptions(create_options);
- qobject_unref(qdict);
- g_free(redundancy);
- g_free(backing_fmt);
- return ret;
-}
-
-static void sd_close(BlockDriverState *bs)
-{
- Error *local_err = NULL;
- BDRVSheepdogState *s = bs->opaque;
- SheepdogVdiReq hdr;
- SheepdogVdiRsp *rsp = (SheepdogVdiRsp *)&hdr;
- unsigned int wlen, rlen = 0;
- int fd, ret;
-
- trace_sheepdog_close(s->name);
-
- fd = connect_to_sdog(s, &local_err);
- if (fd < 0) {
- error_report_err(local_err);
- return;
- }
-
- memset(&hdr, 0, sizeof(hdr));
-
- hdr.opcode = SD_OP_RELEASE_VDI;
- hdr.type = LOCK_TYPE_NORMAL;
- hdr.base_vdi_id = s->inode.vdi_id;
- wlen = strlen(s->name) + 1;
- hdr.data_length = wlen;
- hdr.flags = SD_FLAG_CMD_WRITE;
-
- ret = do_req(fd, s->bs, (SheepdogReq *)&hdr,
- s->name, &wlen, &rlen);
-
- closesocket(fd);
-
- if (!ret && rsp->result != SD_RES_SUCCESS &&
- rsp->result != SD_RES_VDI_NOT_LOCKED) {
- error_report("%s, %s", sd_strerror(rsp->result), s->name);
- }
-
- aio_set_fd_handler(bdrv_get_aio_context(bs), s->fd,
- false, NULL, NULL, NULL, NULL);
- closesocket(s->fd);
- qapi_free_SocketAddress(s->addr);
-}
-
-static int64_t sd_getlength(BlockDriverState *bs)
-{
- BDRVSheepdogState *s = bs->opaque;
-
- return s->inode.vdi_size;
-}
-
-static int coroutine_fn sd_co_truncate(BlockDriverState *bs, int64_t offset,
- bool exact, PreallocMode prealloc,
- BdrvRequestFlags flags, Error **errp)
-{
- BDRVSheepdogState *s = bs->opaque;
- int ret, fd;
- unsigned int datalen;
- uint64_t max_vdi_size;
- int64_t old_size = s->inode.vdi_size;
-
- if (prealloc != PREALLOC_MODE_OFF && prealloc != PREALLOC_MODE_FULL) {
- error_setg(errp, "Unsupported preallocation mode '%s'",
- PreallocMode_str(prealloc));
- return -ENOTSUP;
- }
-
- max_vdi_size = (UINT64_C(1) << s->inode.block_size_shift) * MAX_DATA_OBJS;
- if (offset < old_size) {
- error_setg(errp, "shrinking is not supported");
- return -EINVAL;
- } else if (offset > max_vdi_size) {
- error_setg(errp, "too big image size");
- return -EINVAL;
- }
-
- fd = connect_to_sdog(s, errp);
- if (fd < 0) {
- return fd;
- }
-
- /* we don't need to update entire object */
- datalen = SD_INODE_HEADER_SIZE;
- s->inode.vdi_size = offset;
- ret = write_object(fd, s->bs, (char *)&s->inode,
- vid_to_vdi_oid(s->inode.vdi_id), s->inode.nr_copies,
- datalen, 0, false, s->cache_flags);
- close(fd);
-
- if (ret < 0) {
- error_setg_errno(errp, -ret, "failed to update an inode");
- return ret;
- }
-
- if (prealloc == PREALLOC_MODE_FULL) {
- ret = sd_prealloc(bs, old_size, offset, errp);
- if (ret < 0) {
- return ret;
- }
- }
-
- return 0;
-}
-
-/*
- * This function is called after writing data objects. If we need to
- * update metadata, this sends a write request to the vdi object.
- */
-static void coroutine_fn sd_write_done(SheepdogAIOCB *acb)
-{
- BDRVSheepdogState *s = acb->s;
- struct iovec iov;
- AIOReq *aio_req;
- uint32_t offset, data_len, mn, mx;
-
- mn = acb->min_dirty_data_idx;
- mx = acb->max_dirty_data_idx;
- if (mn <= mx) {
- /* we need to update the vdi object. */
- ++acb->nr_pending;
- offset = sizeof(s->inode) - sizeof(s->inode.data_vdi_id) +
- mn * sizeof(s->inode.data_vdi_id[0]);
- data_len = (mx - mn + 1) * sizeof(s->inode.data_vdi_id[0]);
-
- acb->min_dirty_data_idx = UINT32_MAX;
- acb->max_dirty_data_idx = 0;
-
- iov.iov_base = &s->inode;
- iov.iov_len = sizeof(s->inode);
- aio_req = alloc_aio_req(s, acb, vid_to_vdi_oid(s->inode.vdi_id),
- data_len, offset, 0, false, 0, offset);
- add_aio_request(s, aio_req, &iov, 1, AIOCB_WRITE_UDATA);
- if (--acb->nr_pending) {
- qemu_coroutine_yield();
- }
- }
-}
-
-/* Delete current working VDI on the snapshot chain */
-static bool sd_delete(BDRVSheepdogState *s)
-{
- Error *local_err = NULL;
- unsigned int wlen = SD_MAX_VDI_LEN, rlen = 0;
- SheepdogVdiReq hdr = {
- .opcode = SD_OP_DEL_VDI,
- .base_vdi_id = s->inode.vdi_id,
- .data_length = wlen,
- .flags = SD_FLAG_CMD_WRITE,
- };
- SheepdogVdiRsp *rsp = (SheepdogVdiRsp *)&hdr;
- int fd, ret;
-
- fd = connect_to_sdog(s, &local_err);
- if (fd < 0) {
- error_report_err(local_err);
- return false;
- }
-
- ret = do_req(fd, s->bs, (SheepdogReq *)&hdr,
- s->name, &wlen, &rlen);
- closesocket(fd);
- if (ret) {
- return false;
- }
- switch (rsp->result) {
- case SD_RES_NO_VDI:
- error_report("%s was already deleted", s->name);
- /* fall through */
- case SD_RES_SUCCESS:
- break;
- default:
- error_report("%s, %s", sd_strerror(rsp->result), s->name);
- return false;
- }
-
- return true;
-}
-
-/*
- * Create a writable VDI from a snapshot
- */
-static int sd_create_branch(BDRVSheepdogState *s)
-{
- Error *local_err = NULL;
- int ret, fd;
- uint32_t vid;
- char *buf;
- bool deleted;
-
- trace_sheepdog_create_branch_snapshot(s->inode.vdi_id);
-
- buf = g_malloc(SD_INODE_SIZE);
-
- /*
- * Even If deletion fails, we will just create extra snapshot based on
- * the working VDI which was supposed to be deleted. So no need to
- * false bail out.
- */
- deleted = sd_delete(s);
- ret = do_sd_create(s, &vid, !deleted, &local_err);
- if (ret) {
- error_report_err(local_err);
- goto out;
- }
-
- trace_sheepdog_create_branch_created(vid);
-
- fd = connect_to_sdog(s, &local_err);
- if (fd < 0) {
- error_report_err(local_err);
- ret = fd;
- goto out;
- }
-
- ret = read_object(fd, s->bs, buf, vid_to_vdi_oid(vid),
- s->inode.nr_copies, SD_INODE_SIZE, 0, s->cache_flags);
-
- closesocket(fd);
-
- if (ret < 0) {
- goto out;
- }
-
- memcpy(&s->inode, buf, sizeof(s->inode));
-
- s->is_snapshot = false;
- ret = 0;
- trace_sheepdog_create_branch_new(s->inode.vdi_id);
-
-out:
- g_free(buf);
-
- return ret;
-}
-
-/*
- * Send I/O requests to the server.
- *
- * This function sends requests to the server, links the requests to
- * the inflight_list in BDRVSheepdogState, and exits without
- * waiting the response. The responses are received in the
- * `aio_read_response' function which is called from the main loop as
- * a fd handler.
- *
- * Returns 1 when we need to wait a response, 0 when there is no sent
- * request and -errno in error cases.
- */
-static void coroutine_fn sd_co_rw_vector(SheepdogAIOCB *acb)
-{
- int ret = 0;
- unsigned long len, done = 0, total = acb->nb_sectors * BDRV_SECTOR_SIZE;
- unsigned long idx;
- uint32_t object_size;
- uint64_t oid;
- uint64_t offset;
- BDRVSheepdogState *s = acb->s;
- SheepdogInode *inode = &s->inode;
- AIOReq *aio_req;
-
- if (acb->aiocb_type == AIOCB_WRITE_UDATA && s->is_snapshot) {
- /*
- * In the case we open the snapshot VDI, Sheepdog creates the
- * writable VDI when we do a write operation first.
- */
- ret = sd_create_branch(s);
- if (ret) {
- acb->ret = -EIO;
- return;
- }
- }
-
- object_size = (UINT32_C(1) << inode->block_size_shift);
- idx = acb->sector_num * BDRV_SECTOR_SIZE / object_size;
- offset = (acb->sector_num * BDRV_SECTOR_SIZE) % object_size;
-
- /*
- * Make sure we don't free the aiocb before we are done with all requests.
- * This additional reference is dropped at the end of this function.
- */
- acb->nr_pending++;
-
- while (done != total) {
- uint8_t flags = 0;
- uint64_t old_oid = 0;
- bool create = false;
-
- oid = vid_to_data_oid(inode->data_vdi_id[idx], idx);
-
- len = MIN(total - done, object_size - offset);
-
- switch (acb->aiocb_type) {
- case AIOCB_READ_UDATA:
- if (!inode->data_vdi_id[idx]) {
- qemu_iovec_memset(acb->qiov, done, 0, len);
- goto done;
- }
- break;
- case AIOCB_WRITE_UDATA:
- if (!inode->data_vdi_id[idx]) {
- create = true;
- } else if (!is_data_obj_writable(inode, idx)) {
- /* Copy-On-Write */
- create = true;
- old_oid = oid;
- flags = SD_FLAG_CMD_COW;
- }
- break;
- case AIOCB_DISCARD_OBJ:
- /*
- * We discard the object only when the whole object is
- * 1) allocated 2) trimmed. Otherwise, simply skip it.
- */
- if (len != object_size || inode->data_vdi_id[idx] == 0) {
- goto done;
- }
- break;
- default:
- break;
- }
-
- if (create) {
- trace_sheepdog_co_rw_vector_update(inode->vdi_id, oid,
- vid_to_data_oid(inode->data_vdi_id[idx], idx),
- idx);
- oid = vid_to_data_oid(inode->vdi_id, idx);
- trace_sheepdog_co_rw_vector_new(oid);
- }
-
- aio_req = alloc_aio_req(s, acb, oid, len, offset, flags, create,
- old_oid,
- acb->aiocb_type == AIOCB_DISCARD_OBJ ?
- 0 : done);
- add_aio_request(s, aio_req, acb->qiov->iov, acb->qiov->niov,
- acb->aiocb_type);
- done:
- offset = 0;
- idx++;
- done += len;
- }
- if (--acb->nr_pending) {
- qemu_coroutine_yield();
- }
-}
-
-static void sd_aio_complete(SheepdogAIOCB *acb)
-{
- BDRVSheepdogState *s;
- if (acb->aiocb_type == AIOCB_FLUSH_CACHE) {
- return;
- }
-
- s = acb->s;
- qemu_co_mutex_lock(&s->queue_lock);
- QLIST_REMOVE(acb, aiocb_siblings);
- qemu_co_queue_restart_all(&s->overlapping_queue);
- qemu_co_mutex_unlock(&s->queue_lock);
-}
-
-static coroutine_fn int sd_co_writev(BlockDriverState *bs, int64_t sector_num,
- int nb_sectors, QEMUIOVector *qiov,
- int flags)
-{
- SheepdogAIOCB acb;
- int ret;
- int64_t offset = (sector_num + nb_sectors) * BDRV_SECTOR_SIZE;
- BDRVSheepdogState *s = bs->opaque;
-
- assert(!flags);
- if (offset > s->inode.vdi_size) {
- ret = sd_co_truncate(bs, offset, false, PREALLOC_MODE_OFF, 0, NULL);
- if (ret < 0) {
- return ret;
- }
- }
-
- sd_aio_setup(&acb, s, qiov, sector_num, nb_sectors, AIOCB_WRITE_UDATA);
- sd_co_rw_vector(&acb);
- sd_write_done(&acb);
- sd_aio_complete(&acb);
-
- return acb.ret;
-}
-
-static coroutine_fn int sd_co_readv(BlockDriverState *bs, int64_t sector_num,
- int nb_sectors, QEMUIOVector *qiov)
-{
- SheepdogAIOCB acb;
- BDRVSheepdogState *s = bs->opaque;
-
- sd_aio_setup(&acb, s, qiov, sector_num, nb_sectors, AIOCB_READ_UDATA);
- sd_co_rw_vector(&acb);
- sd_aio_complete(&acb);
-
- return acb.ret;
-}
-
-static int coroutine_fn sd_co_flush_to_disk(BlockDriverState *bs)
-{
- BDRVSheepdogState *s = bs->opaque;
- SheepdogAIOCB acb;
- AIOReq *aio_req;
-
- if (s->cache_flags != SD_FLAG_CMD_CACHE) {
- return 0;
- }
-
- sd_aio_setup(&acb, s, NULL, 0, 0, AIOCB_FLUSH_CACHE);
-
- acb.nr_pending++;
- aio_req = alloc_aio_req(s, &acb, vid_to_vdi_oid(s->inode.vdi_id),
- 0, 0, 0, false, 0, 0);
- add_aio_request(s, aio_req, NULL, 0, acb.aiocb_type);
-
- if (--acb.nr_pending) {
- qemu_coroutine_yield();
- }
-
- sd_aio_complete(&acb);
- return acb.ret;
-}
-
-static int sd_snapshot_create(BlockDriverState *bs, QEMUSnapshotInfo *sn_info)
-{
- Error *local_err = NULL;
- BDRVSheepdogState *s = bs->opaque;
- int ret, fd;
- uint32_t new_vid;
- SheepdogInode *inode;
- unsigned int datalen;
-
- trace_sheepdog_snapshot_create_info(sn_info->name, sn_info->id_str, s->name,
- sn_info->vm_state_size, s->is_snapshot);
-
- if (s->is_snapshot) {
- error_report("You can't create a snapshot of a snapshot VDI, "
- "%s (%" PRIu32 ").", s->name, s->inode.vdi_id);
-
- return -EINVAL;
- }
-
- trace_sheepdog_snapshot_create(sn_info->name, sn_info->id_str);
-
- s->inode.vm_state_size = sn_info->vm_state_size;
- s->inode.vm_clock_nsec = sn_info->vm_clock_nsec;
- /* It appears that inode.tag does not require a NUL terminator,
- * which means this use of strncpy is ok.
- */
- strncpy(s->inode.tag, sn_info->name, sizeof(s->inode.tag));
- /* we don't need to update entire object */
- datalen = SD_INODE_HEADER_SIZE;
- inode = g_malloc(datalen);
-
- /* refresh inode. */
- fd = connect_to_sdog(s, &local_err);
- if (fd < 0) {
- error_report_err(local_err);
- ret = fd;
- goto cleanup;
- }
-
- ret = write_object(fd, s->bs, (char *)&s->inode,
- vid_to_vdi_oid(s->inode.vdi_id), s->inode.nr_copies,
- datalen, 0, false, s->cache_flags);
- if (ret < 0) {
- error_report("failed to write snapshot's inode.");
- goto cleanup;
- }
-
- ret = do_sd_create(s, &new_vid, 1, &local_err);
- if (ret < 0) {
- error_reportf_err(local_err,
- "failed to create inode for snapshot: ");
- goto cleanup;
- }
-
- ret = read_object(fd, s->bs, (char *)inode,
- vid_to_vdi_oid(new_vid), s->inode.nr_copies, datalen, 0,
- s->cache_flags);
-
- if (ret < 0) {
- error_report("failed to read new inode info. %s", strerror(errno));
- goto cleanup;
- }
-
- memcpy(&s->inode, inode, datalen);
- trace_sheepdog_snapshot_create_inode(s->inode.name, s->inode.snap_id,
- s->inode.vdi_id);
-
-cleanup:
- g_free(inode);
- closesocket(fd);
- return ret;
-}
-
-/*
- * We implement rollback(loadvm) operation to the specified snapshot by
- * 1) switch to the snapshot
- * 2) rely on sd_create_branch to delete working VDI and
- * 3) create a new working VDI based on the specified snapshot
- */
-static int sd_snapshot_goto(BlockDriverState *bs, const char *snapshot_id)
-{
- BDRVSheepdogState *s = bs->opaque;
- BDRVSheepdogState *old_s;
- char tag[SD_MAX_VDI_TAG_LEN];
- uint32_t snapid = 0;
- int ret;
-
- if (!sd_parse_snapid_or_tag(snapshot_id, &snapid, tag)) {
- return -EINVAL;
- }
-
- old_s = g_new(BDRVSheepdogState, 1);
-
- memcpy(old_s, s, sizeof(BDRVSheepdogState));
-
- ret = reload_inode(s, snapid, tag);
- if (ret) {
- goto out;
- }
-
- ret = sd_create_branch(s);
- if (ret) {
- goto out;
- }
-
- g_free(old_s);
-
- return 0;
-out:
- /* recover bdrv_sd_state */
- memcpy(s, old_s, sizeof(BDRVSheepdogState));
- g_free(old_s);
-
- error_report("failed to open. recover old bdrv_sd_state.");
-
- return ret;
-}
-
-#define NR_BATCHED_DISCARD 128
-
-static int remove_objects(BDRVSheepdogState *s, Error **errp)
-{
- int fd, i = 0, nr_objs = 0;
- int ret;
- SheepdogInode *inode = &s->inode;
-
- fd = connect_to_sdog(s, errp);
- if (fd < 0) {
- return fd;
- }
-
- nr_objs = count_data_objs(inode);
- while (i < nr_objs) {
- int start_idx, nr_filled_idx;
-
- while (i < nr_objs && !inode->data_vdi_id[i]) {
- i++;
- }
- start_idx = i;
-
- nr_filled_idx = 0;
- while (i < nr_objs && nr_filled_idx < NR_BATCHED_DISCARD) {
- if (inode->data_vdi_id[i]) {
- inode->data_vdi_id[i] = 0;
- nr_filled_idx++;
- }
-
- i++;
- }
-
- ret = write_object(fd, s->bs,
- (char *)&inode->data_vdi_id[start_idx],
- vid_to_vdi_oid(s->inode.vdi_id), inode->nr_copies,
- (i - start_idx) * sizeof(uint32_t),
- offsetof(struct SheepdogInode,
- data_vdi_id[start_idx]),
- false, s->cache_flags);
- if (ret < 0) {
- error_setg(errp, "Failed to discard snapshot inode");
- goto out;
- }
- }
-
- ret = 0;
-out:
- closesocket(fd);
- return ret;
-}
-
-static int sd_snapshot_delete(BlockDriverState *bs,
- const char *snapshot_id,
- const char *name,
- Error **errp)
-{
- /*
- * FIXME should delete the snapshot matching both @snapshot_id and
- * @name, but @name not used here
- */
- unsigned long snap_id = 0;
- char snap_tag[SD_MAX_VDI_TAG_LEN];
- int fd, ret;
- char buf[SD_MAX_VDI_LEN + SD_MAX_VDI_TAG_LEN];
- BDRVSheepdogState *s = bs->opaque;
- unsigned int wlen = SD_MAX_VDI_LEN + SD_MAX_VDI_TAG_LEN, rlen = 0;
- uint32_t vid;
- SheepdogVdiReq hdr = {
- .opcode = SD_OP_DEL_VDI,
- .data_length = wlen,
- .flags = SD_FLAG_CMD_WRITE,
- };
- SheepdogVdiRsp *rsp = (SheepdogVdiRsp *)&hdr;
-
- ret = remove_objects(s, errp);
- if (ret) {
- return ret;
- }
-
- memset(buf, 0, sizeof(buf));
- memset(snap_tag, 0, sizeof(snap_tag));
- pstrcpy(buf, SD_MAX_VDI_LEN, s->name);
- /* TODO Use sd_parse_snapid() once this mess is cleaned up */
- ret = qemu_strtoul(snapshot_id, NULL, 10, &snap_id);
- if (ret || snap_id > UINT32_MAX) {
- /*
- * FIXME Since qemu_strtoul() returns -EINVAL when
- * @snapshot_id is null, @snapshot_id is mandatory. Correct
- * would be to require at least one of @snapshot_id and @name.
- */
- error_setg(errp, "Invalid snapshot ID: %s",
- snapshot_id ? snapshot_id : "<null>");
- return -EINVAL;
- }
-
- if (snap_id) {
- hdr.snapid = (uint32_t) snap_id;
- } else {
- /* FIXME I suspect we should use @name here */
- /* FIXME don't truncate silently */
- pstrcpy(snap_tag, sizeof(snap_tag), snapshot_id);
- pstrcpy(buf + SD_MAX_VDI_LEN, SD_MAX_VDI_TAG_LEN, snap_tag);
- }
-
- ret = find_vdi_name(s, s->name, snap_id, snap_tag, &vid, true, errp);
- if (ret) {
- return ret;
- }
-
- fd = connect_to_sdog(s, errp);
- if (fd < 0) {
- return fd;
- }
-
- ret = do_req(fd, s->bs, (SheepdogReq *)&hdr,
- buf, &wlen, &rlen);
- closesocket(fd);
- if (ret) {
- error_setg_errno(errp, -ret, "Couldn't send request to server");
- return ret;
- }
-
- switch (rsp->result) {
- case SD_RES_NO_VDI:
- error_setg(errp, "Can't find the snapshot");
- return -ENOENT;
- case SD_RES_SUCCESS:
- break;
- default:
- error_setg(errp, "%s", sd_strerror(rsp->result));
- return -EIO;
- }
-
- return 0;
-}
-
-static int sd_snapshot_list(BlockDriverState *bs, QEMUSnapshotInfo **psn_tab)
-{
- Error *local_err = NULL;
- BDRVSheepdogState *s = bs->opaque;
- SheepdogReq req;
- int fd, nr = 1024, ret, max = BITS_TO_LONGS(SD_NR_VDIS) * sizeof(long);
- QEMUSnapshotInfo *sn_tab = NULL;
- unsigned wlen, rlen;
- int found = 0;
- SheepdogInode *inode;
- unsigned long *vdi_inuse;
- unsigned int start_nr;
- uint64_t hval;
- uint32_t vid;
-
- vdi_inuse = g_malloc(max);
- inode = g_malloc(SD_INODE_HEADER_SIZE);
-
- fd = connect_to_sdog(s, &local_err);
- if (fd < 0) {
- error_report_err(local_err);
- ret = fd;
- goto out;
- }
-
- rlen = max;
- wlen = 0;
-
- memset(&req, 0, sizeof(req));
-
- req.opcode = SD_OP_READ_VDIS;
- req.data_length = max;
-
- ret = do_req(fd, s->bs, &req, vdi_inuse, &wlen, &rlen);
-
- closesocket(fd);
- if (ret) {
- goto out;
- }
-
- sn_tab = g_new0(QEMUSnapshotInfo, nr);
-
- /* calculate a vdi id with hash function */
- hval = fnv_64a_buf(s->name, strlen(s->name), FNV1A_64_INIT);
- start_nr = hval & (SD_NR_VDIS - 1);
-
- fd = connect_to_sdog(s, &local_err);
- if (fd < 0) {
- error_report_err(local_err);
- ret = fd;
- goto out;
- }
-
- for (vid = start_nr; found < nr; vid = (vid + 1) % SD_NR_VDIS) {
- if (!test_bit(vid, vdi_inuse)) {
- break;
- }
-
- /* we don't need to read entire object */
- ret = read_object(fd, s->bs, (char *)inode,
- vid_to_vdi_oid(vid),
- 0, SD_INODE_HEADER_SIZE, 0,
- s->cache_flags);
-
- if (ret) {
- continue;
- }
-
- if (!strcmp(inode->name, s->name) && is_snapshot(inode)) {
- sn_tab[found].date_sec = inode->snap_ctime >> 32;
- sn_tab[found].date_nsec = inode->snap_ctime & 0xffffffff;
- sn_tab[found].vm_state_size = inode->vm_state_size;
- sn_tab[found].vm_clock_nsec = inode->vm_clock_nsec;
-
- snprintf(sn_tab[found].id_str, sizeof(sn_tab[found].id_str),
- "%" PRIu32, inode->snap_id);
- pstrcpy(sn_tab[found].name,
- MIN(sizeof(sn_tab[found].name), sizeof(inode->tag)),
- inode->tag);
- found++;
- }
- }
-
- closesocket(fd);
-out:
- *psn_tab = sn_tab;
-
- g_free(vdi_inuse);
- g_free(inode);
-
- if (ret < 0) {
- return ret;
- }
-
- return found;
-}
-
-static int do_load_save_vmstate(BDRVSheepdogState *s, uint8_t *data,
- int64_t pos, int size, int load)
-{
- Error *local_err = NULL;
- bool create;
- int fd, ret = 0, remaining = size;
- unsigned int data_len;
- uint64_t vmstate_oid;
- uint64_t offset;
- uint32_t vdi_index;
- uint32_t vdi_id = load ? s->inode.parent_vdi_id : s->inode.vdi_id;
- uint32_t object_size = (UINT32_C(1) << s->inode.block_size_shift);
-
- fd = connect_to_sdog(s, &local_err);
- if (fd < 0) {
- error_report_err(local_err);
- return fd;
- }
-
- while (remaining) {
- vdi_index = pos / object_size;
- offset = pos % object_size;
-
- data_len = MIN(remaining, object_size - offset);
-
- vmstate_oid = vid_to_vmstate_oid(vdi_id, vdi_index);
-
- create = (offset == 0);
- if (load) {
- ret = read_object(fd, s->bs, (char *)data, vmstate_oid,
- s->inode.nr_copies, data_len, offset,
- s->cache_flags);
- } else {
- ret = write_object(fd, s->bs, (char *)data, vmstate_oid,
- s->inode.nr_copies, data_len, offset, create,
- s->cache_flags);
- }
-
- if (ret < 0) {
- error_report("failed to save vmstate %s", strerror(errno));
- goto cleanup;
- }
-
- pos += data_len;
- data += data_len;
- remaining -= data_len;
- }
- ret = size;
-cleanup:
- closesocket(fd);
- return ret;
-}
-
-static int sd_save_vmstate(BlockDriverState *bs, QEMUIOVector *qiov,
- int64_t pos)
-{
- BDRVSheepdogState *s = bs->opaque;
- void *buf;
- int ret;
-
- buf = qemu_blockalign(bs, qiov->size);
- qemu_iovec_to_buf(qiov, 0, buf, qiov->size);
- ret = do_load_save_vmstate(s, (uint8_t *) buf, pos, qiov->size, 0);
- qemu_vfree(buf);
-
- return ret;
-}
-
-static int sd_load_vmstate(BlockDriverState *bs, QEMUIOVector *qiov,
- int64_t pos)
-{
- BDRVSheepdogState *s = bs->opaque;
- void *buf;
- int ret;
-
- buf = qemu_blockalign(bs, qiov->size);
- ret = do_load_save_vmstate(s, buf, pos, qiov->size, 1);
- qemu_iovec_from_buf(qiov, 0, buf, qiov->size);
- qemu_vfree(buf);
-
- return ret;
-}
-
-
-static coroutine_fn int sd_co_pdiscard(BlockDriverState *bs, int64_t offset,
- int bytes)
-{
- SheepdogAIOCB acb;
- BDRVSheepdogState *s = bs->opaque;
- QEMUIOVector discard_iov;
- struct iovec iov;
- uint32_t zero = 0;
-
- if (!s->discard_supported) {
- return 0;
- }
-
- memset(&discard_iov, 0, sizeof(discard_iov));
- memset(&iov, 0, sizeof(iov));
- iov.iov_base = &zero;
- iov.iov_len = sizeof(zero);
- discard_iov.iov = &iov;
- discard_iov.niov = 1;
- if (!QEMU_IS_ALIGNED(offset | bytes, BDRV_SECTOR_SIZE)) {
- return -ENOTSUP;
- }
- sd_aio_setup(&acb, s, &discard_iov, offset >> BDRV_SECTOR_BITS,
- bytes >> BDRV_SECTOR_BITS, AIOCB_DISCARD_OBJ);
- sd_co_rw_vector(&acb);
- sd_aio_complete(&acb);
-
- return acb.ret;
-}
-
-static coroutine_fn int
-sd_co_block_status(BlockDriverState *bs, bool want_zero, int64_t offset,
- int64_t bytes, int64_t *pnum, int64_t *map,
- BlockDriverState **file)
-{
- BDRVSheepdogState *s = bs->opaque;
- SheepdogInode *inode = &s->inode;
- uint32_t object_size = (UINT32_C(1) << inode->block_size_shift);
- unsigned long start = offset / object_size,
- end = DIV_ROUND_UP(offset + bytes, object_size);
- unsigned long idx;
- *map = offset;
- int ret = BDRV_BLOCK_DATA | BDRV_BLOCK_OFFSET_VALID;
-
- for (idx = start; idx < end; idx++) {
- if (inode->data_vdi_id[idx] == 0) {
- break;
- }
- }
- if (idx == start) {
- /* Get the longest length of unallocated sectors */
- ret = 0;
- for (idx = start + 1; idx < end; idx++) {
- if (inode->data_vdi_id[idx] != 0) {
- break;
- }
- }
- }
-
- *pnum = (idx - start) * object_size;
- if (*pnum > bytes) {
- *pnum = bytes;
- }
- if (ret > 0 && ret & BDRV_BLOCK_OFFSET_VALID) {
- *file = bs;
- }
- return ret;
-}
-
-static int64_t sd_get_allocated_file_size(BlockDriverState *bs)
-{
- BDRVSheepdogState *s = bs->opaque;
- SheepdogInode *inode = &s->inode;
- uint32_t object_size = (UINT32_C(1) << inode->block_size_shift);
- unsigned long i, last = DIV_ROUND_UP(inode->vdi_size, object_size);
- uint64_t size = 0;
-
- for (i = 0; i < last; i++) {
- if (inode->data_vdi_id[i] == 0) {
- continue;
- }
- size += object_size;
- }
- return size;
-}
-
-static QemuOptsList sd_create_opts = {
- .name = "sheepdog-create-opts",
- .head = QTAILQ_HEAD_INITIALIZER(sd_create_opts.head),
- .desc = {
- {
- .name = BLOCK_OPT_SIZE,
- .type = QEMU_OPT_SIZE,
- .help = "Virtual disk size"
- },
- {
- .name = BLOCK_OPT_BACKING_FILE,
- .type = QEMU_OPT_STRING,
- .help = "File name of a base image"
- },
- {
- .name = BLOCK_OPT_BACKING_FMT,
- .type = QEMU_OPT_STRING,
- .help = "Must be 'sheepdog' if present",
- },
- {
- .name = BLOCK_OPT_PREALLOC,
- .type = QEMU_OPT_STRING,
- .help = "Preallocation mode (allowed values: off, full)"
- },
- {
- .name = BLOCK_OPT_REDUNDANCY,
- .type = QEMU_OPT_STRING,
- .help = "Redundancy of the image"
- },
- {
- .name = BLOCK_OPT_OBJECT_SIZE,
- .type = QEMU_OPT_SIZE,
- .help = "Object size of the image"
- },
- { /* end of list */ }
- }
-};
-
-static const char *const sd_strong_runtime_opts[] = {
- "vdi",
- "snap-id",
- "tag",
- "server.",
-
- NULL
-};
-
-static BlockDriver bdrv_sheepdog = {
- .format_name = "sheepdog",
- .protocol_name = "sheepdog",
- .instance_size = sizeof(BDRVSheepdogState),
- .bdrv_parse_filename = sd_parse_filename,
- .bdrv_file_open = sd_open,
- .bdrv_reopen_prepare = sd_reopen_prepare,
- .bdrv_reopen_commit = sd_reopen_commit,
- .bdrv_reopen_abort = sd_reopen_abort,
- .bdrv_close = sd_close,
- .bdrv_co_create = sd_co_create,
- .bdrv_co_create_opts = sd_co_create_opts,
- .bdrv_has_zero_init = bdrv_has_zero_init_1,
- .bdrv_getlength = sd_getlength,
- .bdrv_get_allocated_file_size = sd_get_allocated_file_size,
- .bdrv_co_truncate = sd_co_truncate,
-
- .bdrv_co_readv = sd_co_readv,
- .bdrv_co_writev = sd_co_writev,
- .bdrv_co_flush_to_disk = sd_co_flush_to_disk,
- .bdrv_co_pdiscard = sd_co_pdiscard,
- .bdrv_co_block_status = sd_co_block_status,
-
- .bdrv_snapshot_create = sd_snapshot_create,
- .bdrv_snapshot_goto = sd_snapshot_goto,
- .bdrv_snapshot_delete = sd_snapshot_delete,
- .bdrv_snapshot_list = sd_snapshot_list,
-
- .bdrv_save_vmstate = sd_save_vmstate,
- .bdrv_load_vmstate = sd_load_vmstate,
-
- .bdrv_detach_aio_context = sd_detach_aio_context,
- .bdrv_attach_aio_context = sd_attach_aio_context,
-
- .create_opts = &sd_create_opts,
- .strong_runtime_opts = sd_strong_runtime_opts,
-};
-
-static BlockDriver bdrv_sheepdog_tcp = {
- .format_name = "sheepdog",
- .protocol_name = "sheepdog+tcp",
- .instance_size = sizeof(BDRVSheepdogState),
- .bdrv_parse_filename = sd_parse_filename,
- .bdrv_file_open = sd_open,
- .bdrv_reopen_prepare = sd_reopen_prepare,
- .bdrv_reopen_commit = sd_reopen_commit,
- .bdrv_reopen_abort = sd_reopen_abort,
- .bdrv_close = sd_close,
- .bdrv_co_create = sd_co_create,
- .bdrv_co_create_opts = sd_co_create_opts,
- .bdrv_has_zero_init = bdrv_has_zero_init_1,
- .bdrv_getlength = sd_getlength,
- .bdrv_get_allocated_file_size = sd_get_allocated_file_size,
- .bdrv_co_truncate = sd_co_truncate,
-
- .bdrv_co_readv = sd_co_readv,
- .bdrv_co_writev = sd_co_writev,
- .bdrv_co_flush_to_disk = sd_co_flush_to_disk,
- .bdrv_co_pdiscard = sd_co_pdiscard,
- .bdrv_co_block_status = sd_co_block_status,
-
- .bdrv_snapshot_create = sd_snapshot_create,
- .bdrv_snapshot_goto = sd_snapshot_goto,
- .bdrv_snapshot_delete = sd_snapshot_delete,
- .bdrv_snapshot_list = sd_snapshot_list,
-
- .bdrv_save_vmstate = sd_save_vmstate,
- .bdrv_load_vmstate = sd_load_vmstate,
-
- .bdrv_detach_aio_context = sd_detach_aio_context,
- .bdrv_attach_aio_context = sd_attach_aio_context,
-
- .create_opts = &sd_create_opts,
- .strong_runtime_opts = sd_strong_runtime_opts,
-};
-
-static BlockDriver bdrv_sheepdog_unix = {
- .format_name = "sheepdog",
- .protocol_name = "sheepdog+unix",
- .instance_size = sizeof(BDRVSheepdogState),
- .bdrv_parse_filename = sd_parse_filename,
- .bdrv_file_open = sd_open,
- .bdrv_reopen_prepare = sd_reopen_prepare,
- .bdrv_reopen_commit = sd_reopen_commit,
- .bdrv_reopen_abort = sd_reopen_abort,
- .bdrv_close = sd_close,
- .bdrv_co_create = sd_co_create,
- .bdrv_co_create_opts = sd_co_create_opts,
- .bdrv_has_zero_init = bdrv_has_zero_init_1,
- .bdrv_getlength = sd_getlength,
- .bdrv_get_allocated_file_size = sd_get_allocated_file_size,
- .bdrv_co_truncate = sd_co_truncate,
-
- .bdrv_co_readv = sd_co_readv,
- .bdrv_co_writev = sd_co_writev,
- .bdrv_co_flush_to_disk = sd_co_flush_to_disk,
- .bdrv_co_pdiscard = sd_co_pdiscard,
- .bdrv_co_block_status = sd_co_block_status,
-
- .bdrv_snapshot_create = sd_snapshot_create,
- .bdrv_snapshot_goto = sd_snapshot_goto,
- .bdrv_snapshot_delete = sd_snapshot_delete,
- .bdrv_snapshot_list = sd_snapshot_list,
-
- .bdrv_save_vmstate = sd_save_vmstate,
- .bdrv_load_vmstate = sd_load_vmstate,
-
- .bdrv_detach_aio_context = sd_detach_aio_context,
- .bdrv_attach_aio_context = sd_attach_aio_context,
-
- .create_opts = &sd_create_opts,
- .strong_runtime_opts = sd_strong_runtime_opts,
-};
-
-static void bdrv_sheepdog_init(void)
-{
- bdrv_register(&bdrv_sheepdog);
- bdrv_register(&bdrv_sheepdog_tcp);
- bdrv_register(&bdrv_sheepdog_unix);
-}
-block_init(bdrv_sheepdog_init);
diff --git a/block/trace-events b/block/trace-events
index 1a12d634e2..31062ed437 100644
--- a/block/trace-events
+++ b/block/trace-events
@@ -207,19 +207,5 @@ file_FindEjectableOpticalMedia(const char *media) "Matching using %s"
file_setup_cdrom(const char *partition) "Using %s as optical disc"
file_hdev_is_sg(int type, int version) "SG device found: type=%d, version=%d"
-# sheepdog.c
-sheepdog_reconnect_to_sdog(void) "Wait for connection to be established"
-sheepdog_aio_read_response(void) "disable cache since the server doesn't support it"
-sheepdog_open(uint32_t vid) "0x%" PRIx32 " snapshot inode was open"
-sheepdog_close(const char *name) "%s"
-sheepdog_create_branch_snapshot(uint32_t vdi) "0x%" PRIx32 " is snapshot"
-sheepdog_create_branch_created(uint32_t vdi) "0x%" PRIx32 " is created"
-sheepdog_create_branch_new(uint32_t vdi) "0x%" PRIx32 " was newly created"
-sheepdog_co_rw_vector_update(uint32_t vdi, uint64_t oid, uint64_t data, long idx) "update ino (%" PRIu32 ") %" PRIu64 " %" PRIu64 " %ld"
-sheepdog_co_rw_vector_new(uint64_t oid) "new oid 0x%" PRIx64
-sheepdog_snapshot_create_info(const char *sn_name, const char *id, const char *name, int64_t size, int is_snapshot) "sn_info: name %s id_str %s s: name %s vm_state_size %" PRId64 " " "is_snapshot %d"
-sheepdog_snapshot_create(const char *sn_name, const char *id) "%s %s"
-sheepdog_snapshot_create_inode(const char *name, uint32_t snap, uint32_t vdi) "s->inode: name %s snap_id 0x%" PRIx32 " vdi 0x%" PRIx32
-
# ssh.c
sftp_error(const char *op, const char *ssh_err, int ssh_err_code, int sftp_err_code) "%s failed: %s (libssh error code: %d, sftp error code: %d)"
diff --git a/block/write-threshold.c b/block/write-threshold.c
index 85b78dc2a9..35cafbc22d 100644
--- a/block/write-threshold.c
+++ b/block/write-threshold.c
@@ -12,9 +12,7 @@
#include "qemu/osdep.h"
#include "block/block_int.h"
-#include "qemu/coroutine.h"
#include "block/write-threshold.h"
-#include "qemu/notify.h"
#include "qapi/error.h"
#include "qapi/qapi-commands-block-core.h"
#include "qapi/qapi-events-block-core.h"
@@ -24,82 +22,9 @@ uint64_t bdrv_write_threshold_get(const BlockDriverState *bs)
return bs->write_threshold_offset;
}
-bool bdrv_write_threshold_is_set(const BlockDriverState *bs)
-{
- return bs->write_threshold_offset > 0;
-}
-
-static void write_threshold_disable(BlockDriverState *bs)
-{
- if (bdrv_write_threshold_is_set(bs)) {
- notifier_with_return_remove(&bs->write_threshold_notifier);
- bs->write_threshold_offset = 0;
- }
-}
-
-uint64_t bdrv_write_threshold_exceeded(const BlockDriverState *bs,
- const BdrvTrackedRequest *req)
-{
- if (bdrv_write_threshold_is_set(bs)) {
- if (req->offset > bs->write_threshold_offset) {
- return (req->offset - bs->write_threshold_offset) + req->bytes;
- }
- if ((req->offset + req->bytes) > bs->write_threshold_offset) {
- return (req->offset + req->bytes) - bs->write_threshold_offset;
- }
- }
- return 0;
-}
-
-static int coroutine_fn before_write_notify(NotifierWithReturn *notifier,
- void *opaque)
-{
- BdrvTrackedRequest *req = opaque;
- BlockDriverState *bs = req->bs;
- uint64_t amount = 0;
-
- amount = bdrv_write_threshold_exceeded(bs, req);
- if (amount > 0) {
- qapi_event_send_block_write_threshold(
- bs->node_name,
- amount,
- bs->write_threshold_offset);
-
- /* autodisable to avoid flooding the monitor */
- write_threshold_disable(bs);
- }
-
- return 0; /* should always let other notifiers run */
-}
-
-static void write_threshold_register_notifier(BlockDriverState *bs)
-{
- bs->write_threshold_notifier.notify = before_write_notify;
- bdrv_add_before_write_notifier(bs, &bs->write_threshold_notifier);
-}
-
-static void write_threshold_update(BlockDriverState *bs,
- int64_t threshold_bytes)
-{
- bs->write_threshold_offset = threshold_bytes;
-}
-
void bdrv_write_threshold_set(BlockDriverState *bs, uint64_t threshold_bytes)
{
- if (bdrv_write_threshold_is_set(bs)) {
- if (threshold_bytes > 0) {
- write_threshold_update(bs, threshold_bytes);
- } else {
- write_threshold_disable(bs);
- }
- } else {
- if (threshold_bytes > 0) {
- /* avoid multiple registration */
- write_threshold_register_notifier(bs);
- write_threshold_update(bs, threshold_bytes);
- }
- /* discard bogus disable request */
- }
+ bs->write_threshold_offset = threshold_bytes;
}
void qmp_block_set_write_threshold(const char *node_name,
@@ -122,3 +47,17 @@ void qmp_block_set_write_threshold(const char *node_name,
aio_context_release(aio_context);
}
+
+void bdrv_write_threshold_check_write(BlockDriverState *bs, int64_t offset,
+ int64_t bytes)
+{
+ int64_t end = offset + bytes;
+ uint64_t wtr = bs->write_threshold_offset;
+
+ if (wtr > 0 && end > wtr) {
+ qapi_event_send_block_write_threshold(bs->node_name, end - wtr, wtr);
+
+ /* autodisable to avoid flooding the monitor */
+ bdrv_write_threshold_set(bs, 0);
+ }
+}
diff --git a/configure b/configure
index 6fea3210bd..0e4233fd8a 100755
--- a/configure
+++ b/configure
@@ -447,7 +447,6 @@ vdi=${default_feature:-yes}
vvfat=${default_feature:-yes}
qed=${default_feature:-yes}
parallels=${default_feature:-yes}
-sheepdog="no"
libxml2="$default_feature"
debug_mutex="no"
libpmem="$default_feature"
@@ -1478,10 +1477,6 @@ for opt do
;;
--enable-parallels) parallels="yes"
;;
- --disable-sheepdog) sheepdog="no"
- ;;
- --enable-sheepdog) sheepdog="yes"
- ;;
--disable-vhost-user) vhost_user="no"
;;
--enable-vhost-user) vhost_user="yes"
@@ -1668,7 +1663,7 @@ if [ "$ARCH" = "unknown" ]; then
fi
default_target_list=""
-deprecated_targets_list=ppc64abi32-linux-user,lm32-softmmu,unicore32-softmmu
+deprecated_targets_list=ppc64abi32-linux-user
deprecated_features=""
mak_wilds=""
@@ -1916,7 +1911,6 @@ disabled with --disable-FEATURE, default is enabled if available
vvfat vvfat image format support
qed qed image format support
parallels parallels image format support
- sheepdog sheepdog block driver support (deprecated)
crypto-afalg Linux AF_ALG crypto backend driver
capstone capstone disassembler support
debug-mutex mutex debugging support
@@ -3623,7 +3617,7 @@ case "$fdt" in
esac
##########################################
-# opengl probe (for sdl2, gtk, milkymist-tmu2)
+# opengl probe (for sdl2, gtk)
gbm="no"
if $pkg_config gbm; then
@@ -6108,10 +6102,6 @@ fi
if test "$parallels" = "yes" ; then
echo "CONFIG_PARALLELS=y" >> $config_host_mak
fi
-if test "$sheepdog" = "yes" ; then
- add_to deprecated_features "sheepdog"
- echo "CONFIG_SHEEPDOG=y" >> $config_host_mak
-fi
if test "$have_mlockall" = "yes" ; then
echo "HAVE_MLOCKALL=y" >> $config_host_mak
fi
@@ -6286,14 +6276,13 @@ fi
# UNLINK is used to remove symlinks from older development versions
# that might get into the way when doing "git update" without doing
# a "make distclean" in between.
-DIRS="tests tests/tcg tests/tcg/lm32 tests/qapi-schema tests/qtest/libqos"
+DIRS="tests tests/tcg tests/qapi-schema tests/qtest/libqos"
DIRS="$DIRS tests/qtest tests/qemu-iotests tests/vm tests/fp tests/qgraph"
DIRS="$DIRS docs docs/interop fsdev scsi"
DIRS="$DIRS pc-bios/optionrom pc-bios/s390-ccw"
DIRS="$DIRS roms/seabios"
DIRS="$DIRS contrib/plugins/"
LINKS="Makefile"
-LINKS="$LINKS tests/tcg/lm32/Makefile"
LINKS="$LINKS tests/tcg/Makefile.target"
LINKS="$LINKS pc-bios/optionrom/Makefile"
LINKS="$LINKS pc-bios/s390-ccw/Makefile"
@@ -6484,6 +6473,13 @@ if test -n "${deprecated_features}"; then
echo " features: ${deprecated_features}"
fi
+# Create list of config switches that should be poisoned in common code...
+# but filter out CONFIG_TCG and CONFIG_USER_ONLY which are special.
+sed -n -e '/CONFIG_TCG/d' -e '/CONFIG_USER_ONLY/d' \
+ -e '/^#define / { s///; s/ .*//; s/^/#pragma GCC poison /p; }' \
+ *-config-devices.h *-config-target.h | \
+ sort -u > config-poison.h
+
# Save the configure command line for later reuse.
cat <<EOD >config.status
#!/bin/sh
diff --git a/contrib/vhost-user-input/main.c b/contrib/vhost-user-input/main.c
index c15d18c33f..081230da54 100644
--- a/contrib/vhost-user-input/main.c
+++ b/contrib/vhost-user-input/main.c
@@ -6,12 +6,13 @@
#include "qemu/osdep.h"
-#include <linux/input.h>
+#include <sys/ioctl.h>
#include "qemu/iov.h"
#include "qemu/bswap.h"
#include "qemu/sockets.h"
#include "libvhost-user-glib.h"
+#include "standard-headers/linux/input.h"
#include "standard-headers/linux/virtio_input.h"
#include "qapi/error.h"
@@ -113,13 +114,16 @@ vi_evdev_watch(VuDev *dev, int condition, void *data)
static void vi_handle_status(VuInput *vi, virtio_input_event *event)
{
struct input_event evdev;
+ struct timeval tval;
int rc;
- if (gettimeofday(&evdev.time, NULL)) {
+ if (gettimeofday(&tval, NULL)) {
perror("vi_handle_status: gettimeofday");
return;
}
+ evdev.input_event_sec = tval.tv_sec;
+ evdev.input_event_usec = tval.tv_usec;
evdev.type = le16toh(event->type);
evdev.code = le16toh(event->code);
evdev.value = le32toh(event->value);
diff --git a/default-configs/devices/lm32-softmmu.mak b/default-configs/devices/lm32-softmmu.mak
deleted file mode 100644
index 1bce3f6e8b..0000000000
--- a/default-configs/devices/lm32-softmmu.mak
+++ /dev/null
@@ -1,12 +0,0 @@
-# Default configuration for lm32-softmmu
-
-# Uncomment the following lines to disable these optional devices:
-#
-#CONFIG_MILKYMIST_TMU2=n # disabling it actually causes compile-time failures
-
-CONFIG_SEMIHOSTING=y
-
-# Boards:
-#
-CONFIG_LM32_EVR=y
-CONFIG_MILKYMIST=y
diff --git a/default-configs/devices/moxie-softmmu.mak b/default-configs/devices/moxie-softmmu.mak
deleted file mode 100644
index bd50da3c58..0000000000
--- a/default-configs/devices/moxie-softmmu.mak
+++ /dev/null
@@ -1,5 +0,0 @@
-# Default configuration for moxie-softmmu
-
-# Boards:
-#
-CONFIG_MOXIESIM=y
diff --git a/default-configs/devices/unicore32-softmmu.mak b/default-configs/devices/unicore32-softmmu.mak
deleted file mode 100644
index 899288e3d7..0000000000
--- a/default-configs/devices/unicore32-softmmu.mak
+++ /dev/null
@@ -1,6 +0,0 @@
-# Default configuration for unicore32-softmmu
-
-# Boards:
-#
-CONFIG_PUV3=y
-CONFIG_SEMIHOSTING=y
diff --git a/default-configs/targets/lm32-softmmu.mak b/default-configs/targets/lm32-softmmu.mak
deleted file mode 100644
index 55e7184a3d..0000000000
--- a/default-configs/targets/lm32-softmmu.mak
+++ /dev/null
@@ -1,2 +0,0 @@
-TARGET_ARCH=lm32
-TARGET_WORDS_BIGENDIAN=y
diff --git a/default-configs/targets/moxie-softmmu.mak b/default-configs/targets/moxie-softmmu.mak
deleted file mode 100644
index 183e6b0ebd..0000000000
--- a/default-configs/targets/moxie-softmmu.mak
+++ /dev/null
@@ -1,2 +0,0 @@
-TARGET_ARCH=moxie
-TARGET_WORDS_BIGENDIAN=y
diff --git a/default-configs/targets/unicore32-softmmu.mak b/default-configs/targets/unicore32-softmmu.mak
deleted file mode 100644
index 57331e94fe..0000000000
--- a/default-configs/targets/unicore32-softmmu.mak
+++ /dev/null
@@ -1 +0,0 @@
-TARGET_ARCH=unicore32
diff --git a/disas/lm32.c b/disas/lm32.c
deleted file mode 100644
index 4fbb124534..0000000000
--- a/disas/lm32.c
+++ /dev/null
@@ -1,361 +0,0 @@
-/*
- * Simple LatticeMico32 disassembler.
- *
- * Copyright (c) 2012 Michael Walle <michael@walle.cc>
- *
- * 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.1 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 "disas/dis-asm.h"
-
-typedef enum {
- LM32_OP_SRUI = 0, LM32_OP_NORI, LM32_OP_MULI, LM32_OP_SH, LM32_OP_LB,
- LM32_OP_SRI, LM32_OP_XORI, LM32_OP_LH, LM32_OP_ANDI, LM32_OP_XNORI,
- LM32_OP_LW, LM32_OP_LHU, LM32_OP_SB, LM32_OP_ADDI, LM32_OP_ORI,
- LM32_OP_SLI, LM32_OP_LBU, LM32_OP_BE, LM32_OP_BG, LM32_OP_BGE,
- LM32_OP_BGEU, LM32_OP_BGU, LM32_OP_SW, LM32_OP_BNE, LM32_OP_ANDHI,
- LM32_OP_CMPEI, LM32_OP_CMPGI, LM32_OP_CMPGEI, LM32_OP_CMPGEUI,
- LM32_OP_CMPGUI, LM32_OP_ORHI, LM32_OP_CMPNEI, LM32_OP_SRU, LM32_OP_NOR,
- LM32_OP_MUL, LM32_OP_DIVU, LM32_OP_RCSR, LM32_OP_SR, LM32_OP_XOR,
- LM32_OP_ILL0, LM32_OP_AND, LM32_OP_XNOR, LM32_OP_ILL1, LM32_OP_SCALL,
- LM32_OP_SEXTB, LM32_OP_ADD, LM32_OP_OR, LM32_OP_SL, LM32_OP_B,
- LM32_OP_MODU, LM32_OP_SUB, LM32_OP_ILL2, LM32_OP_WCSR, LM32_OP_ILL3,
- LM32_OP_CALL, LM32_OP_SEXTH, LM32_OP_BI, LM32_OP_CMPE, LM32_OP_CMPG,
- LM32_OP_CMPGE, LM32_OP_CMPGEU, LM32_OP_CMPGU, LM32_OP_CALLI, LM32_OP_CMPNE,
-} Lm32Opcode;
-
-typedef enum {
- FMT_INVALID = 0, FMT_RRI5, FMT_RRI16, FMT_IMM26, FMT_LOAD, FMT_STORE,
- FMT_RRR, FMT_R, FMT_RNR, FMT_CRN, FMT_CNR, FMT_BREAK,
-} Lm32OpcodeFmt;
-
-typedef enum {
- LM32_CSR_IE = 0, LM32_CSR_IM, LM32_CSR_IP, LM32_CSR_ICC, LM32_CSR_DCC,
- LM32_CSR_CC, LM32_CSR_CFG, LM32_CSR_EBA, LM32_CSR_DC, LM32_CSR_DEBA,
- LM32_CSR_CFG2, LM32_CSR_JTX = 0xe, LM32_CSR_JRX, LM32_CSR_BP0,
- LM32_CSR_BP1, LM32_CSR_BP2, LM32_CSR_BP3, LM32_CSR_WP0 = 0x18,
- LM32_CSR_WP1, LM32_CSR_WP2, LM32_CSR_WP3,
-} Lm32CsrNum;
-
-typedef struct {
- int csr;
- const char *name;
-} Lm32CsrInfo;
-
-static const Lm32CsrInfo lm32_csr_info[] = {
- {LM32_CSR_IE, "ie", },
- {LM32_CSR_IM, "im", },
- {LM32_CSR_IP, "ip", },
- {LM32_CSR_ICC, "icc", },
- {LM32_CSR_DCC, "dcc", },
- {LM32_CSR_CC, "cc", },
- {LM32_CSR_CFG, "cfg", },
- {LM32_CSR_EBA, "eba", },
- {LM32_CSR_DC, "dc", },
- {LM32_CSR_DEBA, "deba", },
- {LM32_CSR_CFG2, "cfg2", },
- {LM32_CSR_JTX, "jtx", },
- {LM32_CSR_JRX, "jrx", },
- {LM32_CSR_BP0, "bp0", },
- {LM32_CSR_BP1, "bp1", },
- {LM32_CSR_BP2, "bp2", },
- {LM32_CSR_BP3, "bp3", },
- {LM32_CSR_WP0, "wp0", },
- {LM32_CSR_WP1, "wp1", },
- {LM32_CSR_WP2, "wp2", },
- {LM32_CSR_WP3, "wp3", },
-};
-
-static const Lm32CsrInfo *find_csr_info(int csr)
-{
- const Lm32CsrInfo *info;
- int i;
-
- for (i = 0; i < ARRAY_SIZE(lm32_csr_info); i++) {
- info = &lm32_csr_info[i];
- if (csr == info->csr) {
- return info;
- }
- }
-
- return NULL;
-}
-
-typedef struct {
- int reg;
- const char *name;
-} Lm32RegInfo;
-
-typedef enum {
- LM32_REG_R0 = 0, LM32_REG_R1, LM32_REG_R2, LM32_REG_R3, LM32_REG_R4,
- LM32_REG_R5, LM32_REG_R6, LM32_REG_R7, LM32_REG_R8, LM32_REG_R9,
- LM32_REG_R10, LM32_REG_R11, LM32_REG_R12, LM32_REG_R13, LM32_REG_R14,
- LM32_REG_R15, LM32_REG_R16, LM32_REG_R17, LM32_REG_R18, LM32_REG_R19,
- LM32_REG_R20, LM32_REG_R21, LM32_REG_R22, LM32_REG_R23, LM32_REG_R24,
- LM32_REG_R25, LM32_REG_GP, LM32_REG_FP, LM32_REG_SP, LM32_REG_RA,
- LM32_REG_EA, LM32_REG_BA,
-} Lm32RegNum;
-
-static const Lm32RegInfo lm32_reg_info[] = {
- {LM32_REG_R0, "r0", },
- {LM32_REG_R1, "r1", },
- {LM32_REG_R2, "r2", },
- {LM32_REG_R3, "r3", },
- {LM32_REG_R4, "r4", },
- {LM32_REG_R5, "r5", },
- {LM32_REG_R6, "r6", },
- {LM32_REG_R7, "r7", },
- {LM32_REG_R8, "r8", },
- {LM32_REG_R9, "r9", },
- {LM32_REG_R10, "r10", },
- {LM32_REG_R11, "r11", },
- {LM32_REG_R12, "r12", },
- {LM32_REG_R13, "r13", },
- {LM32_REG_R14, "r14", },
- {LM32_REG_R15, "r15", },
- {LM32_REG_R16, "r16", },
- {LM32_REG_R17, "r17", },
- {LM32_REG_R18, "r18", },
- {LM32_REG_R19, "r19", },
- {LM32_REG_R20, "r20", },
- {LM32_REG_R21, "r21", },
- {LM32_REG_R22, "r22", },
- {LM32_REG_R23, "r23", },
- {LM32_REG_R24, "r24", },
- {LM32_REG_R25, "r25", },
- {LM32_REG_GP, "gp", },
- {LM32_REG_FP, "fp", },
- {LM32_REG_SP, "sp", },
- {LM32_REG_RA, "ra", },
- {LM32_REG_EA, "ea", },
- {LM32_REG_BA, "ba", },
-};
-
-static const Lm32RegInfo *find_reg_info(int reg)
-{
- assert(ARRAY_SIZE(lm32_reg_info) == 32);
- return &lm32_reg_info[reg & 0x1f];
-}
-
-typedef struct {
- struct {
- uint32_t code;
- uint32_t mask;
- } op;
- const char *name;
- const char *args_fmt;
-} Lm32OpcodeInfo;
-
-static const Lm32OpcodeInfo lm32_opcode_info[] = {
- /* pseudo instructions */
- {{0x34000000, 0xffffffff}, "nop", NULL},
- {{0xac000002, 0xffffffff}, "break", NULL},
- {{0xac000003, 0xffffffff}, "scall", NULL},
- {{0xc3e00000, 0xffffffff}, "bret", NULL},
- {{0xc3c00000, 0xffffffff}, "eret", NULL},
- {{0xc3a00000, 0xffffffff}, "ret", NULL},
- {{0xa4000000, 0xfc1f07ff}, "not", "%2, %0"},
- {{0xb8000000, 0xfc1f07ff}, "mv", "%2, %0"},
- {{0x71e00000, 0xffe00000}, "mvhi", "%1, %u"},
- {{0x34000000, 0xffe00000}, "mvi", "%1, %s"},
-
-#define _O(op) {op << 26, 0x3f << 26}
- /* regular opcodes */
- {_O(LM32_OP_ADD), "add", "%2, %0, %1" },
- {_O(LM32_OP_ADDI), "addi", "%1, %0, %s" },
- {_O(LM32_OP_AND), "and", "%2, %0, %1" },
- {_O(LM32_OP_ANDHI), "andhi", "%1, %0, %u" },
- {_O(LM32_OP_ANDI), "andi", "%1, %0, %u" },
- {_O(LM32_OP_B), "b", "%0", },
- {_O(LM32_OP_BE), "be", "%1, %0, %r" },
- {_O(LM32_OP_BG), "bg", "%1, %0, %r" },
- {_O(LM32_OP_BGE), "bge", "%1, %0, %r" },
- {_O(LM32_OP_BGEU), "bgeu", "%1, %0, %r" },
- {_O(LM32_OP_BGU), "bgu", "%1, %0, %r" },
- {_O(LM32_OP_BI), "bi", "%R", },
- {_O(LM32_OP_BNE), "bne", "%1, %0, %r" },
- {_O(LM32_OP_CALL), "call", "%0", },
- {_O(LM32_OP_CALLI), "calli", "%R", },
- {_O(LM32_OP_CMPE), "cmpe", "%2, %0, %1" },
- {_O(LM32_OP_CMPEI), "cmpei", "%1, %0, %s" },
- {_O(LM32_OP_CMPG), "cmpg", "%2, %0, %1" },
- {_O(LM32_OP_CMPGE), "cmpge", "%2, %0, %1" },
- {_O(LM32_OP_CMPGEI), "cmpgei", "%1, %0, %s" },
- {_O(LM32_OP_CMPGEU), "cmpgeu", "%2, %0, %1" },
- {_O(LM32_OP_CMPGEUI), "cmpgeui", "%1, %0, %s" },
- {_O(LM32_OP_CMPGI), "cmpgi", "%1, %0, %s" },
- {_O(LM32_OP_CMPGU), "cmpgu", "%2, %0, %1" },
- {_O(LM32_OP_CMPGUI), "cmpgui", "%1, %0, %s" },
- {_O(LM32_OP_CMPNE), "cmpne", "%2, %0, %1" },
- {_O(LM32_OP_CMPNEI), "cmpnei", "%1, %0, %s" },
- {_O(LM32_OP_DIVU), "divu", "%2, %0, %1" },
- {_O(LM32_OP_LB), "lb", "%1, (%0+%s)" },
- {_O(LM32_OP_LBU), "lbu", "%1, (%0+%s)" },
- {_O(LM32_OP_LH), "lh", "%1, (%0+%s)" },
- {_O(LM32_OP_LHU), "lhu", "%1, (%0+%s)" },
- {_O(LM32_OP_LW), "lw", "%1, (%0+%s)" },
- {_O(LM32_OP_MODU), "modu", "%2, %0, %1" },
- {_O(LM32_OP_MULI), "muli", "%1, %0, %s" },
- {_O(LM32_OP_MUL), "mul", "%2, %0, %1" },
- {_O(LM32_OP_NORI), "nori", "%1, %0, %u" },
- {_O(LM32_OP_NOR), "nor", "%2, %0, %1" },
- {_O(LM32_OP_ORHI), "orhi", "%1, %0, %u" },
- {_O(LM32_OP_ORI), "ori", "%1, %0, %u" },
- {_O(LM32_OP_OR), "or", "%2, %0, %1" },
- {_O(LM32_OP_RCSR), "rcsr", "%2, %c", },
- {_O(LM32_OP_SB), "sb", "(%0+%s), %1" },
- {_O(LM32_OP_SEXTB), "sextb", "%2, %0", },
- {_O(LM32_OP_SEXTH), "sexth", "%2, %0", },
- {_O(LM32_OP_SH), "sh", "(%0+%s), %1" },
- {_O(LM32_OP_SLI), "sli", "%1, %0, %h" },
- {_O(LM32_OP_SL), "sl", "%2, %0, %1" },
- {_O(LM32_OP_SRI), "sri", "%1, %0, %h" },
- {_O(LM32_OP_SR), "sr", "%2, %0, %1" },
- {_O(LM32_OP_SRUI), "srui", "%1, %0, %d" },
- {_O(LM32_OP_SRU), "sru", "%2, %0, %s" },
- {_O(LM32_OP_SUB), "sub", "%2, %0, %s" },
- {_O(LM32_OP_SW), "sw", "(%0+%s), %1" },
- {_O(LM32_OP_WCSR), "wcsr", "%c, %1", },
- {_O(LM32_OP_XNORI), "xnori", "%1, %0, %u" },
- {_O(LM32_OP_XNOR), "xnor", "%2, %0, %1" },
- {_O(LM32_OP_XORI), "xori", "%1, %0, %u" },
- {_O(LM32_OP_XOR), "xor", "%2, %0, %1" },
-#undef _O
-};
-
-static const Lm32OpcodeInfo *find_opcode_info(uint32_t opcode)
-{
- const Lm32OpcodeInfo *info;
- int i;
- for (i = 0; i < ARRAY_SIZE(lm32_opcode_info); i++) {
- info = &lm32_opcode_info[i];
- if ((opcode & info->op.mask) == info->op.code) {
- return info;
- }
- }
-
- return NULL;
-}
-
-int print_insn_lm32(bfd_vma memaddr, struct disassemble_info *info)
-{
- fprintf_function fprintf_fn = info->fprintf_func;
- void *stream = info->stream;
- int rc;
- uint8_t insn[4];
- const Lm32OpcodeInfo *opc_info;
- uint32_t op;
- const char *args_fmt;
-
- rc = info->read_memory_func(memaddr, insn, 4, info);
- if (rc != 0) {
- info->memory_error_func(rc, memaddr, info);
- return -1;
- }
-
- fprintf_fn(stream, "%02x %02x %02x %02x ",
- insn[0], insn[1], insn[2], insn[3]);
-
- op = bfd_getb32(insn);
- opc_info = find_opcode_info(op);
- if (opc_info) {
- fprintf_fn(stream, "%-8s ", opc_info->name);
- args_fmt = opc_info->args_fmt;
- while (args_fmt && *args_fmt) {
- if (*args_fmt == '%') {
- switch (*(++args_fmt)) {
- case '0': {
- uint8_t r0;
- const char *r0_name;
- r0 = (op >> 21) & 0x1f;
- r0_name = find_reg_info(r0)->name;
- fprintf_fn(stream, "%s", r0_name);
- break;
- }
- case '1': {
- uint8_t r1;
- const char *r1_name;
- r1 = (op >> 16) & 0x1f;
- r1_name = find_reg_info(r1)->name;
- fprintf_fn(stream, "%s", r1_name);
- break;
- }
- case '2': {
- uint8_t r2;
- const char *r2_name;
- r2 = (op >> 11) & 0x1f;
- r2_name = find_reg_info(r2)->name;
- fprintf_fn(stream, "%s", r2_name);
- break;
- }
- case 'c': {
- uint8_t csr;
- const Lm32CsrInfo *info;
- csr = (op >> 21) & 0x1f;
- info = find_csr_info(csr);
- if (info) {
- fprintf_fn(stream, "%s", info->name);
- } else {
- fprintf_fn(stream, "0x%x", csr);
- }
- break;
- }
- case 'u': {
- uint16_t u16;
- u16 = op & 0xffff;
- fprintf_fn(stream, "0x%x", u16);
- break;
- }
- case 's': {
- int16_t s16;
- s16 = (int16_t)(op & 0xffff);
- fprintf_fn(stream, "%d", s16);
- break;
- }
- case 'r': {
- uint32_t rela;
- rela = memaddr + (((int16_t)(op & 0xffff)) << 2);
- fprintf_fn(stream, "%x", rela);
- break;
- }
- case 'R': {
- uint32_t rela;
- int32_t imm26;
- imm26 = (int32_t)((op & 0x3ffffff) << 6) >> 4;
- rela = memaddr + imm26;
- fprintf_fn(stream, "%x", rela);
- break;
- }
- case 'h': {
- uint8_t u5;
- u5 = (op & 0x1f);
- fprintf_fn(stream, "%d", u5);
- break;
- }
- default:
- break;
- }
- } else {
- fprintf_fn(stream, "%c", *args_fmt);
- }
- args_fmt++;
- }
- } else {
- fprintf_fn(stream, ".word 0x%x", op);
- }
-
- return 4;
-}
diff --git a/disas/meson.build b/disas/meson.build
index 4c8da01877..449f99e1de 100644
--- a/disas/meson.build
+++ b/disas/meson.build
@@ -9,11 +9,9 @@ common_ss.add(when: 'CONFIG_CRIS_DIS', if_true: files('cris.c'))
common_ss.add(when: 'CONFIG_HEXAGON_DIS', if_true: files('hexagon.c'))
common_ss.add(when: 'CONFIG_HPPA_DIS', if_true: files('hppa.c'))
common_ss.add(when: 'CONFIG_I386_DIS', if_true: files('i386.c'))
-common_ss.add(when: 'CONFIG_LM32_DIS', if_true: files('lm32.c'))
common_ss.add(when: 'CONFIG_M68K_DIS', if_true: files('m68k.c'))
common_ss.add(when: 'CONFIG_MICROBLAZE_DIS', if_true: files('microblaze.c'))
common_ss.add(when: 'CONFIG_MIPS_DIS', if_true: files('mips.c'))
-common_ss.add(when: 'CONFIG_MOXIE_DIS', if_true: files('moxie.c'))
common_ss.add(when: 'CONFIG_NANOMIPS_DIS', if_true: files('nanomips.cpp'))
common_ss.add(when: 'CONFIG_NIOS2_DIS', if_true: files('nios2.c'))
common_ss.add(when: 'CONFIG_PPC_DIS', if_true: files('ppc.c'))
diff --git a/disas/moxie.c b/disas/moxie.c
deleted file mode 100644
index e94ab4c33d..0000000000
--- a/disas/moxie.c
+++ /dev/null
@@ -1,360 +0,0 @@
-/* Disassemble moxie instructions.
- Copyright (c) 2009 Free Software Foundation, Inc.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, see <http://www.gnu.org/licenses/>. */
-
-#include "qemu/osdep.h"
-#define STATIC_TABLE
-#define DEFINE_TABLE
-
-#include "disas/dis-asm.h"
-
-static void *stream;
-
-/* Form 1 instructions come in different flavors:
-
- Some have no arguments (MOXIE_F1_NARG)
- Some only use the A operand (MOXIE_F1_A)
- Some use A and B registers (MOXIE_F1_AB)
- Some use A and consume a 4 byte immediate value (MOXIE_F1_A4)
- Some use just a 4 byte immediate value (MOXIE_F1_4)
- Some use just a 4 byte memory address (MOXIE_F1_M)
- Some use B and an indirect A (MOXIE_F1_AiB)
- Some use A and an indirect B (MOXIE_F1_ABi)
- Some consume a 4 byte immediate value and use X (MOXIE_F1_4A)
- Some use B and an indirect A plus 4 bytes (MOXIE_F1_AiB4)
- Some use A and an indirect B plus 4 bytes (MOXIE_F1_ABi4)
-
- Form 2 instructions also come in different flavors:
-
- Some have no arguments (MOXIE_F2_NARG)
- Some use the A register and an 8-bit value (MOXIE_F2_A8V)
-
- Form 3 instructions also come in different flavors:
-
- Some have no arguments (MOXIE_F3_NARG)
- Some have a 10-bit PC relative operand (MOXIE_F3_PCREL). */
-
-#define MOXIE_F1_NARG 0x100
-#define MOXIE_F1_A 0x101
-#define MOXIE_F1_AB 0x102
-/* #define MOXIE_F1_ABC 0x103 */
-#define MOXIE_F1_A4 0x104
-#define MOXIE_F1_4 0x105
-#define MOXIE_F1_AiB 0x106
-#define MOXIE_F1_ABi 0x107
-#define MOXIE_F1_4A 0x108
-#define MOXIE_F1_AiB4 0x109
-#define MOXIE_F1_ABi4 0x10a
-#define MOXIE_F1_M 0x10b
-
-#define MOXIE_F2_NARG 0x200
-#define MOXIE_F2_A8V 0x201
-
-#define MOXIE_F3_NARG 0x300
-#define MOXIE_F3_PCREL 0x301
-
-typedef struct moxie_opc_info_t {
- short opcode;
- unsigned itype;
- const char * name;
-} moxie_opc_info_t;
-
-extern const moxie_opc_info_t moxie_form1_opc_info[64];
-extern const moxie_opc_info_t moxie_form2_opc_info[4];
-extern const moxie_opc_info_t moxie_form3_opc_info[16];
-
-/* The moxie processor's 16-bit instructions come in two forms:
-
- FORM 1 instructions start with a 0 bit...
-
- 0oooooooaaaabbbb
- 0 F
-
- ooooooo - form 1 opcode number
- aaaa - operand A
- bbbb - operand B
-
- FORM 2 instructions start with bits "10"...
-
- 10ooaaaavvvvvvvv
- 0 F
-
- oo - form 2 opcode number
- aaaa - operand A
- vvvvvvvv - 8-bit immediate value
-
- FORM 3 instructions start with a bits "11"...
-
- 11oooovvvvvvvvvv
- 0 F
-
- oooo - form 3 opcode number
- vvvvvvvvvv - 10-bit immediate value. */
-
-const moxie_opc_info_t moxie_form1_opc_info[64] =
- {
- { 0x00, MOXIE_F1_NARG, "nop" },
- { 0x01, MOXIE_F1_A4, "ldi.l" },
- { 0x02, MOXIE_F1_AB, "mov" },
- { 0x03, MOXIE_F1_M, "jsra" },
- { 0x04, MOXIE_F1_NARG, "ret" },
- { 0x05, MOXIE_F1_AB, "add.l" },
- { 0x06, MOXIE_F1_AB, "push" },
- { 0x07, MOXIE_F1_AB, "pop" },
- { 0x08, MOXIE_F1_A4, "lda.l" },
- { 0x09, MOXIE_F1_4A, "sta.l" },
- { 0x0a, MOXIE_F1_ABi, "ld.l" },
- { 0x0b, MOXIE_F1_AiB, "st.l" },
- { 0x0c, MOXIE_F1_ABi4, "ldo.l" },
- { 0x0d, MOXIE_F1_AiB4, "sto.l" },
- { 0x0e, MOXIE_F1_AB, "cmp" },
- { 0x0f, MOXIE_F1_NARG, "bad" },
- { 0x10, MOXIE_F1_NARG, "bad" },
- { 0x11, MOXIE_F1_NARG, "bad" },
- { 0x12, MOXIE_F1_NARG, "bad" },
- { 0x13, MOXIE_F1_NARG, "bad" },
- { 0x14, MOXIE_F1_NARG, "bad" },
- { 0x15, MOXIE_F1_NARG, "bad" },
- { 0x16, MOXIE_F1_NARG, "bad" },
- { 0x17, MOXIE_F1_NARG, "bad" },
- { 0x18, MOXIE_F1_NARG, "bad" },
- { 0x19, MOXIE_F1_A, "jsr" },
- { 0x1a, MOXIE_F1_M, "jmpa" },
- { 0x1b, MOXIE_F1_A4, "ldi.b" },
- { 0x1c, MOXIE_F1_ABi, "ld.b" },
- { 0x1d, MOXIE_F1_A4, "lda.b" },
- { 0x1e, MOXIE_F1_AiB, "st.b" },
- { 0x1f, MOXIE_F1_4A, "sta.b" },
- { 0x20, MOXIE_F1_A4, "ldi.s" },
- { 0x21, MOXIE_F1_ABi, "ld.s" },
- { 0x22, MOXIE_F1_A4, "lda.s" },
- { 0x23, MOXIE_F1_AiB, "st.s" },
- { 0x24, MOXIE_F1_4A, "sta.s" },
- { 0x25, MOXIE_F1_A, "jmp" },
- { 0x26, MOXIE_F1_AB, "and" },
- { 0x27, MOXIE_F1_AB, "lshr" },
- { 0x28, MOXIE_F1_AB, "ashl" },
- { 0x29, MOXIE_F1_AB, "sub.l" },
- { 0x2a, MOXIE_F1_AB, "neg" },
- { 0x2b, MOXIE_F1_AB, "or" },
- { 0x2c, MOXIE_F1_AB, "not" },
- { 0x2d, MOXIE_F1_AB, "ashr" },
- { 0x2e, MOXIE_F1_AB, "xor" },
- { 0x2f, MOXIE_F1_AB, "mul.l" },
- { 0x30, MOXIE_F1_4, "swi" },
- { 0x31, MOXIE_F1_AB, "div.l" },
- { 0x32, MOXIE_F1_AB, "udiv.l" },
- { 0x33, MOXIE_F1_AB, "mod.l" },
- { 0x34, MOXIE_F1_AB, "umod.l" },
- { 0x35, MOXIE_F1_NARG, "brk" },
- { 0x36, MOXIE_F1_ABi4, "ldo.b" },
- { 0x37, MOXIE_F1_AiB4, "sto.b" },
- { 0x38, MOXIE_F1_ABi4, "ldo.s" },
- { 0x39, MOXIE_F1_AiB4, "sto.s" },
- { 0x3a, MOXIE_F1_NARG, "bad" },
- { 0x3b, MOXIE_F1_NARG, "bad" },
- { 0x3c, MOXIE_F1_NARG, "bad" },
- { 0x3d, MOXIE_F1_NARG, "bad" },
- { 0x3e, MOXIE_F1_NARG, "bad" },
- { 0x3f, MOXIE_F1_NARG, "bad" }
- };
-
-const moxie_opc_info_t moxie_form2_opc_info[4] =
- {
- { 0x00, MOXIE_F2_A8V, "inc" },
- { 0x01, MOXIE_F2_A8V, "dec" },
- { 0x02, MOXIE_F2_A8V, "gsr" },
- { 0x03, MOXIE_F2_A8V, "ssr" }
- };
-
-const moxie_opc_info_t moxie_form3_opc_info[16] =
- {
- { 0x00, MOXIE_F3_PCREL,"beq" },
- { 0x01, MOXIE_F3_PCREL,"bne" },
- { 0x02, MOXIE_F3_PCREL,"blt" },
- { 0x03, MOXIE_F3_PCREL,"bgt" },
- { 0x04, MOXIE_F3_PCREL,"bltu" },
- { 0x05, MOXIE_F3_PCREL,"bgtu" },
- { 0x06, MOXIE_F3_PCREL,"bge" },
- { 0x07, MOXIE_F3_PCREL,"ble" },
- { 0x08, MOXIE_F3_PCREL,"bgeu" },
- { 0x09, MOXIE_F3_PCREL,"bleu" },
- { 0x0a, MOXIE_F3_NARG, "bad" },
- { 0x0b, MOXIE_F3_NARG, "bad" },
- { 0x0c, MOXIE_F3_NARG, "bad" },
- { 0x0d, MOXIE_F3_NARG, "bad" },
- { 0x0e, MOXIE_F3_NARG, "bad" },
- { 0x0f, MOXIE_F3_NARG, "bad" }
- };
-
-/* Macros to extract operands from the instruction word. */
-#define OP_A(i) ((i >> 4) & 0xf)
-#define OP_B(i) (i & 0xf)
-#define INST2OFFSET(o) ((((signed short)((o & ((1<<10)-1))<<6))>>6)<<1)
-
-static const char * reg_names[16] =
- { "$fp", "$sp", "$r0", "$r1", "$r2", "$r3", "$r4", "$r5",
- "$r6", "$r7", "$r8", "$r9", "$r10", "$r11", "$r12", "$r13" };
-
-int
-print_insn_moxie(bfd_vma addr, struct disassemble_info * info)
-{
- int length = 2;
- int status;
- stream = info->stream;
- const moxie_opc_info_t * opcode;
- bfd_byte buffer[4];
- unsigned short iword;
- fprintf_function fpr = info->fprintf_func;
-
- if ((status = info->read_memory_func(addr, buffer, 2, info)))
- goto fail;
- iword = (bfd_getb16(buffer) >> 16);
-
- /* Form 1 instructions have the high bit set to 0. */
- if ((iword & (1<<15)) == 0) {
- /* Extract the Form 1 opcode. */
- opcode = &moxie_form1_opc_info[iword >> 8];
- switch (opcode->itype) {
- case MOXIE_F1_NARG:
- fpr(stream, "%s", opcode->name);
- break;
- case MOXIE_F1_A:
- fpr(stream, "%s\t%s", opcode->name,
- reg_names[OP_A(iword)]);
- break;
- case MOXIE_F1_AB:
- fpr(stream, "%s\t%s, %s", opcode->name,
- reg_names[OP_A(iword)],
- reg_names[OP_B(iword)]);
- break;
- case MOXIE_F1_A4:
- {
- unsigned imm;
- if ((status = info->read_memory_func(addr + 2, buffer, 4, info)))
- goto fail;
- imm = bfd_getb32(buffer);
- fpr(stream, "%s\t%s, 0x%x", opcode->name,
- reg_names[OP_A(iword)], imm);
- length = 6;
- }
- break;
- case MOXIE_F1_4:
- {
- unsigned imm;
- if ((status = info->read_memory_func(addr + 2, buffer, 4, info)))
- goto fail;
- imm = bfd_getb32(buffer);
- fpr(stream, "%s\t0x%x", opcode->name, imm);
- length = 6;
- }
- break;
- case MOXIE_F1_M:
- {
- unsigned imm;
- if ((status = info->read_memory_func(addr + 2, buffer, 4, info)))
- goto fail;
- imm = bfd_getb32(buffer);
- fpr(stream, "%s\t", opcode->name);
- info->print_address_func((bfd_vma) imm, info);
- length = 6;
- }
- break;
- case MOXIE_F1_AiB:
- fpr (stream, "%s\t(%s), %s", opcode->name,
- reg_names[OP_A(iword)], reg_names[OP_B(iword)]);
- break;
- case MOXIE_F1_ABi:
- fpr(stream, "%s\t%s, (%s)", opcode->name,
- reg_names[OP_A(iword)], reg_names[OP_B(iword)]);
- break;
- case MOXIE_F1_4A:
- {
- unsigned imm;
- if ((status = info->read_memory_func(addr + 2, buffer, 4, info)))
- goto fail;
- imm = bfd_getb32(buffer);
- fpr(stream, "%s\t0x%x, %s",
- opcode->name, imm, reg_names[OP_A(iword)]);
- length = 6;
- }
- break;
- case MOXIE_F1_AiB4:
- {
- unsigned imm;
- if ((status = info->read_memory_func(addr+2, buffer, 4, info)))
- goto fail;
- imm = bfd_getb32(buffer);
- fpr(stream, "%s\t0x%x(%s), %s", opcode->name,
- imm,
- reg_names[OP_A(iword)],
- reg_names[OP_B(iword)]);
- length = 6;
- }
- break;
- case MOXIE_F1_ABi4:
- {
- unsigned imm;
- if ((status = info->read_memory_func(addr+2, buffer, 4, info)))
- goto fail;
- imm = bfd_getb32(buffer);
- fpr(stream, "%s\t%s, 0x%x(%s)",
- opcode->name,
- reg_names[OP_A(iword)],
- imm,
- reg_names[OP_B(iword)]);
- length = 6;
- }
- break;
- default:
- abort();
- }
- }
- else if ((iword & (1<<14)) == 0) {
- /* Extract the Form 2 opcode. */
- opcode = &moxie_form2_opc_info[(iword >> 12) & 3];
- switch (opcode->itype) {
- case MOXIE_F2_A8V:
- fpr(stream, "%s\t%s, 0x%x",
- opcode->name,
- reg_names[(iword >> 8) & 0xf],
- iword & ((1 << 8) - 1));
- break;
- case MOXIE_F2_NARG:
- fpr(stream, "%s", opcode->name);
- break;
- default:
- abort();
- }
- } else {
- /* Extract the Form 3 opcode. */
- opcode = &moxie_form3_opc_info[(iword >> 10) & 15];
- switch (opcode->itype) {
- case MOXIE_F3_PCREL:
- fpr(stream, "%s\t", opcode->name);
- info->print_address_func((bfd_vma) (addr + INST2OFFSET(iword) + 2),
- info);
- break;
- default:
- abort();
- }
- }
-
- return length;
-
- fail:
- info->memory_error_func(status, addr, info);
- return -1;
-}
diff --git a/docs/_templates/editpage.html b/docs/_templates/editpage.html
deleted file mode 100644
index 4319b0f5ac..0000000000
--- a/docs/_templates/editpage.html
+++ /dev/null
@@ -1,5 +0,0 @@
-<div id="editpage">
- <ul>
- <li><a href="https://gitlab.com/qemu-project/qemu/-/blob/master/docs/{{pagename}}.rst">Page source</a></li>
- </ul>
-</div>
diff --git a/docs/conf.py b/docs/conf.py
index 2ee6111872..00cf66ab54 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -29,6 +29,7 @@
import os
import sys
import sphinx
+from distutils.version import LooseVersion
from sphinx.errors import ConfigError
# Make Sphinx fail cleanly if using an old Python, rather than obscurely
@@ -150,38 +151,47 @@ with open(os.path.join(qemu_docdir, 'defs.rst.inc')) as f:
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
#
-html_theme = 'alabaster'
+try:
+ import sphinx_rtd_theme
+except ImportError:
+ raise ConfigError(
+ 'The Sphinx \'sphinx_rtd_theme\' HTML theme was not found.\n'
+ )
+
+html_theme = 'sphinx_rtd_theme'
# Theme options are theme-specific and customize the look and feel of a theme
# further. For a list of options available for each theme, see the
# documentation.
-# We initialize this to empty here, so the per-manual conf.py can just
-# add individual key/value entries.
-html_theme_options = {
-}
+if LooseVersion(sphinx_rtd_theme.__version__) >= LooseVersion("0.4.3"):
+ html_theme_options = {
+ "style_nav_header_background": "#802400",
+ }
+
+html_logo = os.path.join(qemu_docdir, "../ui/icons/qemu_128x128.png")
+
+html_favicon = os.path.join(qemu_docdir, "../ui/icons/qemu_32x32.png")
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
-# QEMU doesn't yet have any static files, so comment this out so we don't
-# get a warning about a missing directory.
-# If we do ever add this then it would probably be better to call the
-# subdirectory sphinx_static, as the Linux kernel does.
-# html_static_path = ['_static']
+html_static_path = [os.path.join(qemu_docdir, "sphinx-static")]
+
+html_css_files = [
+ 'theme_overrides.css',
+]
+
+html_context = {
+ "display_gitlab": True,
+ "gitlab_user": "qemu-project",
+ "gitlab_repo": "qemu",
+ "gitlab_version": "master",
+ "conf_py_path": "/docs/", # Path in the checkout to the docs root
+}
# Custom sidebar templates, must be a dictionary that maps document names
# to template names.
-#
-# This is required for the alabaster theme
-# refs: http://alabaster.readthedocs.io/en/latest/installation.html#sidebars
-html_sidebars = {
- '**': [
- 'about.html',
- 'editpage.html',
- 'navigation.html',
- 'searchbox.html',
- ]
-}
+#html_sidebars = {}
# Don't copy the rST source files to the HTML output directory,
# and don't put links to the sources into the output HTML.
diff --git a/docs/devel/_templates/editpage.html b/docs/devel/_templates/editpage.html
deleted file mode 100644
index a86d22bca8..0000000000
--- a/docs/devel/_templates/editpage.html
+++ /dev/null
@@ -1,5 +0,0 @@
-<div id="editpage">
- <ul>
- <li><a href="https://gitlab.com/qemu-project/qemu/-/blob/master/docs/devel/{{pagename}}.rst">Page source</a></li>
- </ul>
-</div>
diff --git a/docs/devel/qgraph.rst b/docs/devel/qgraph.rst
index a9aff167ad..318534d4b0 100644
--- a/docs/devel/qgraph.rst
+++ b/docs/devel/qgraph.rst
@@ -92,6 +92,64 @@ The basic framework steps are the following:
Depending on the QEMU binary used, only some drivers/machines will be
available and only test that are reached by them will be executed.
+Troubleshooting unavailable tests
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+If there is no path from an available machine to a test then that test will be
+unavailable and won't execute. This can happen if a test or driver did not set
+up its qgraph node correctly. It can also happen if the necessary machine type
+or device is missing from the QEMU binary because it was compiled out or
+otherwise.
+
+It is possible to troubleshoot unavailable tests by running::
+
+ $ QTEST_QEMU_BINARY=build/qemu-system-x86_64 build/tests/qtest/qos-test --verbose
+ # ALL QGRAPH EDGES: {
+ # src='virtio-net'
+ # |-> dest='virtio-net-tests/vhost-user/multiqueue' type=2 (node=0x559142109e30)
+ # |-> dest='virtio-net-tests/vhost-user/migrate' type=2 (node=0x559142109d00)
+ # src='virtio-net-pci'
+ # |-> dest='virtio-net' type=1 (node=0x55914210d740)
+ # src='pci-bus'
+ # |-> dest='virtio-net-pci' type=2 (node=0x55914210d880)
+ # src='pci-bus-pc'
+ # |-> dest='pci-bus' type=1 (node=0x559142103f40)
+ # src='i440FX-pcihost'
+ # |-> dest='pci-bus-pc' type=0 (node=0x55914210ac70)
+ # src='x86_64/pc'
+ # |-> dest='i440FX-pcihost' type=0 (node=0x5591421117f0)
+ # src=''
+ # |-> dest='x86_64/pc' type=0 (node=0x559142111600)
+ # |-> dest='arm/raspi2' type=0 (node=0x559142110740)
+ ...
+ # }
+ # ALL QGRAPH NODES: {
+ # name='virtio-net-tests/announce-self' type=3 cmd_line='(null)' [available]
+ # name='arm/raspi2' type=0 cmd_line='-M raspi2 ' [UNAVAILABLE]
+ ...
+ # }
+
+The ``virtio-net-tests/announce-self`` test is listed as "available" in the
+"ALL QGRAPH NODES" output. This means the test will execute. We can follow the
+qgraph path in the "ALL QGRAPH EDGES" output as follows: '' -> 'x86_64/pc' ->
+'i440FX-pcihost' -> 'pci-bus-pc' -> 'pci-bus' -> 'virtio-net-pci' ->
+'virtio-net'. The root of the qgraph is '' and the depth first search begins
+there.
+
+The ``arm/raspi`` machine node is listed as "UNAVAILABLE". Although it is
+reachable from the root via '' -> 'arm/raspi2' the node is unavailable because
+the QEMU binary did not list it when queried by the framework. This is expected
+because we used the ``qemu-system-x86_64`` binary which does not support ARM
+machine types.
+
+If a test is unexpectedly listed as "UNAVAILABLE", first check that the "ALL
+QGRAPH EDGES" output reports edge connectivity from the root ('') to the test.
+If there is no connectivity then the qgraph nodes were not set up correctly and
+the driver or test code is incorrect. If there is connectivity, check the
+availability of each node in the path in the "ALL QGRAPH NODES" output. The
+first unavailable node in the path is the reason why the test is unavailable.
+Typically this is because the QEMU binary lacks support for the necessary
+machine type or device.
+
Creating a new driver and its interface
"""""""""""""""""""""""""""""""""""""""""
diff --git a/docs/interop/_templates/editpage.html b/docs/interop/_templates/editpage.html
deleted file mode 100644
index 215e562681..0000000000
--- a/docs/interop/_templates/editpage.html
+++ /dev/null
@@ -1,5 +0,0 @@
-<div id="editpage">
- <ul>
- <li><a href="https://gitlab.com/qemu-project/qemu/-/blob/master/docs/interop/{{pagename}}.rst">Page source</a></li>
- </ul>
-</div>
diff --git a/docs/meson.build b/docs/meson.build
index f84306ba7e..855e3916e9 100644
--- a/docs/meson.build
+++ b/docs/meson.build
@@ -27,10 +27,9 @@ if sphinx_build.found()
build_docs = (sphinx_build_test_out.returncode() == 0)
if not build_docs
- warning('@0@ is either too old or uses too old a Python version'
- .format(sphinx_build.full_path()))
+ warning('@0@: @1@'.format(sphinx_build.full_path(), sphinx_build_test_out.stderr()))
if get_option('docs').enabled()
- error('Install a Python 3 version of python-sphinx')
+ error('Install a Python 3 version of python-sphinx and the readthedoc theme')
endif
endif
endif
diff --git a/docs/specs/_templates/editpage.html b/docs/specs/_templates/editpage.html
deleted file mode 100644
index aaa468aa98..0000000000
--- a/docs/specs/_templates/editpage.html
+++ /dev/null
@@ -1,5 +0,0 @@
-<div id="editpage">
- <ul>
- <li><a href="https://gitlab.com/qemu-project/qemu/-/blob/master/docs/specs/{{pagename}}.rst">Page source</a></li>
- </ul>
-</div>
diff --git a/docs/sphinx-static/theme_overrides.css b/docs/sphinx-static/theme_overrides.css
new file mode 100644
index 0000000000..c70ef95128
--- /dev/null
+++ b/docs/sphinx-static/theme_overrides.css
@@ -0,0 +1,161 @@
+/* -*- coding: utf-8; mode: css -*-
+ *
+ * Sphinx HTML theme customization: read the doc
+ * Based on Linux Documentation/sphinx-static/theme_overrides.css
+ */
+
+/* Improve contrast and increase size for easier reading. */
+
+body {
+ font-family: serif;
+ color: black;
+ font-size: 100%;
+}
+
+h1, h2, .rst-content .toctree-wrapper p.caption, h3, h4, h5, h6, legend {
+ font-family: sans-serif;
+}
+
+.rst-content dl:not(.docutils) dt {
+ border-top: none;
+ border-left: solid 3px #ccc;
+ background-color: #f0f0f0;
+ color: black;
+}
+
+.wy-nav-top {
+ background: #802400;
+}
+
+.wy-side-nav-search input[type="text"] {
+ border-color: #f60;
+}
+
+.wy-menu-vertical p.caption {
+ color: white;
+}
+
+.wy-menu-vertical li.current a {
+ color: #505050;
+}
+
+.wy-menu-vertical li.on a, .wy-menu-vertical li.current > a {
+ color: #303030;
+}
+
+.fa-gitlab {
+ box-shadow: 0 4px 8px 0 rgba(0,0,0,0.2), 0 3px 10px 0 rgba(0,0,0,0.19);
+ border-radius: 5px;
+}
+
+div[class^="highlight"] pre {
+ font-family: monospace;
+ color: black;
+ font-size: 100%;
+}
+
+.wy-menu-vertical {
+ font-family: sans-serif;
+}
+
+.c {
+ font-style: normal;
+}
+
+p {
+ font-size: 100%;
+}
+
+/* Interim: Code-blocks with line nos - lines and line numbers don't line up.
+ * see: https://github.com/rtfd/sphinx_rtd_theme/issues/419
+ */
+
+div[class^="highlight"] pre {
+ line-height: normal;
+}
+.rst-content .highlight > pre {
+ line-height: normal;
+}
+
+/* Keep fields from being strangely far apart due to inheirited table CSS. */
+.rst-content table.field-list th.field-name {
+ padding-top: 1px;
+ padding-bottom: 1px;
+}
+.rst-content table.field-list td.field-body {
+ padding-top: 1px;
+ padding-bottom: 1px;
+}
+
+@media screen {
+
+ /* content column
+ *
+ * RTD theme's default is 800px as max width for the content, but we have
+ * tables with tons of columns, which need the full width of the view-port.
+ */
+
+ .wy-nav-content{max-width: none; }
+
+ /* table:
+ *
+ * - Sequences of whitespace should collapse into a single whitespace.
+ * - make the overflow auto (scrollbar if needed)
+ * - align caption "left" ("center" is unsuitable on vast tables)
+ */
+
+ .wy-table-responsive table td { white-space: normal; }
+ .wy-table-responsive { overflow: auto; }
+ .rst-content table.docutils caption { text-align: left; font-size: 100%; }
+
+ /* captions:
+ *
+ * - captions should have 100% (not 85%) font size
+ * - hide the permalink symbol as long as link is not hovered
+ */
+
+ .toc-title {
+ font-size: 150%;
+ font-weight: bold;
+ }
+
+ caption, .wy-table caption, .rst-content table.field-list caption {
+ font-size: 100%;
+ }
+ caption a.headerlink { opacity: 0; }
+ caption a.headerlink:hover { opacity: 1; }
+
+ /* Menu selection and keystrokes */
+
+ span.menuselection {
+ color: blue;
+ font-family: "Courier New", Courier, monospace
+ }
+
+ code.kbd, code.kbd span {
+ color: white;
+ background-color: darkblue;
+ font-weight: bold;
+ font-family: "Courier New", Courier, monospace
+ }
+
+ /* fix bottom margin of lists items */
+
+ .rst-content .section ul li:last-child, .rst-content .section ul li p:last-child {
+ margin-bottom: 12px;
+ }
+
+ /* inline literal: drop the borderbox, padding and red color */
+
+ code, .rst-content tt, .rst-content code {
+ color: inherit;
+ border: none;
+ padding: unset;
+ background: inherit;
+ font-size: 85%;
+ }
+
+ .rst-content tt.literal,.rst-content tt.literal,.rst-content code.literal {
+ color: inherit;
+ }
+}
diff --git a/docs/system/_templates/editpage.html b/docs/system/_templates/editpage.html
deleted file mode 100644
index 6586b2e257..0000000000
--- a/docs/system/_templates/editpage.html
+++ /dev/null
@@ -1,5 +0,0 @@
-<div id="editpage">
- <ul>
- <li><a href="https://gitlab.com/qemu-project/qemu/-/blob/master/docs/system/{{pagename}}.rst">Page source</a></li>
- </ul>
-</div>
diff --git a/docs/system/deprecated.rst b/docs/system/deprecated.rst
index f9169077ae..abbf8243a3 100644
--- a/docs/system/deprecated.rst
+++ b/docs/system/deprecated.rst
@@ -198,30 +198,6 @@ from Linux upstream kernel, declare it deprecated.
System emulator CPUS
--------------------
-``moxie`` CPU (since 5.2.0)
-'''''''''''''''''''''''''''
-
-The ``moxie`` guest CPU support is deprecated and will be removed in
-a future version of QEMU. It's unclear whether anybody is still using
-CPU emulation in QEMU, and there are no test images available to make
-sure that the code is still working.
-
-``lm32`` CPUs (since 5.2.0)
-'''''''''''''''''''''''''''
-
-The ``lm32`` guest CPU support is deprecated and will be removed in
-a future version of QEMU. The only public user of this architecture
-was the milkymist project, which has been dead for years; there was
-never an upstream Linux port.
-
-``unicore32`` CPUs (since 5.2.0)
-''''''''''''''''''''''''''''''''
-
-The ``unicore32`` guest CPU support is deprecated and will be removed in
-a future version of QEMU. Support for this CPU was removed from the
-upstream Linux kernel, and there is no available upstream toolchain
-to build binaries for it.
-
``Icelake-Client`` CPU Model (since 5.2.0)
''''''''''''''''''''''''''''''''''''''''''
@@ -293,15 +269,6 @@ The above, converted to the current supported format::
json:{"file.driver":"rbd", "file.pool":"rbd", "file.image":"name"}
-``sheepdog`` driver (since 5.2.0)
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-The ``sheepdog`` block device driver is deprecated. The corresponding upstream
-server project is no longer actively maintained. Users are recommended to switch
-to an alternative distributed block device driver such as RBD. The
-``qemu-img convert`` command can be used to liberate existing data by moving
-it out of sheepdog volumes into an alternative storage backend.
-
linux-user mode CPUs
--------------------
diff --git a/docs/system/device-url-syntax.rst.inc b/docs/system/device-url-syntax.rst.inc
index 6f6ec8366b..d15a021508 100644
--- a/docs/system/device-url-syntax.rst.inc
+++ b/docs/system/device-url-syntax.rst.inc
@@ -85,24 +85,6 @@ These are specified using a special URL syntax.
Currently authentication must be done using ssh-agent. Other
authentication methods may be supported in future.
-``Sheepdog``
- Sheepdog is a distributed storage system for QEMU. QEMU supports
- using either local sheepdog devices or remote networked devices.
-
- Syntax for specifying a sheepdog device
-
- ::
-
- sheepdog[+tcp|+unix]://[host:port]/vdiname[?socket=path][#snapid|#tag]
-
- Example
-
- .. parsed-literal::
-
- |qemu_system| --drive file=sheepdog://192.0.2.1:30000/MyVirtualMachine
-
- See also https://sheepdog.github.io/sheepdog/.
-
``GlusterFS``
GlusterFS is a user space distributed file system. QEMU supports the
use of GlusterFS volumes for hosting VM disk images using TCP, Unix
diff --git a/docs/system/qemu-block-drivers.rst.inc b/docs/system/qemu-block-drivers.rst.inc
index 60a064b232..16225710eb 100644
--- a/docs/system/qemu-block-drivers.rst.inc
+++ b/docs/system/qemu-block-drivers.rst.inc
@@ -547,75 +547,6 @@ also available. Here are some example of the older syntax:
|qemu_system| linux2.img -hdb nbd:unix:/tmp/my_socket
|qemu_system| -cdrom nbd:localhost:10809:exportname=debian-500-ppc-netinst
-
-
-Sheepdog disk images
-~~~~~~~~~~~~~~~~~~~~
-
-Sheepdog is a distributed storage system for QEMU. It provides highly
-available block level storage volumes that can be attached to
-QEMU-based virtual machines.
-
-You can create a Sheepdog disk image with the command:
-
-.. parsed-literal::
-
- qemu-img create sheepdog:///IMAGE SIZE
-
-where *IMAGE* is the Sheepdog image name and *SIZE* is its
-size.
-
-To import the existing *FILENAME* to Sheepdog, you can use a
-convert command.
-
-.. parsed-literal::
-
- qemu-img convert FILENAME sheepdog:///IMAGE
-
-You can boot from the Sheepdog disk image with the command:
-
-.. parsed-literal::
-
- |qemu_system| sheepdog:///IMAGE
-
-You can also create a snapshot of the Sheepdog image like qcow2.
-
-.. parsed-literal::
-
- qemu-img snapshot -c TAG sheepdog:///IMAGE
-
-where *TAG* is a tag name of the newly created snapshot.
-
-To boot from the Sheepdog snapshot, specify the tag name of the
-snapshot.
-
-.. parsed-literal::
-
- |qemu_system| sheepdog:///IMAGE#TAG
-
-You can create a cloned image from the existing snapshot.
-
-.. parsed-literal::
-
- qemu-img create -b sheepdog:///BASE#TAG sheepdog:///IMAGE
-
-where *BASE* is an image name of the source snapshot and *TAG*
-is its tag name.
-
-You can use an unix socket instead of an inet socket:
-
-.. parsed-literal::
-
- |qemu_system| sheepdog+unix:///IMAGE?socket=PATH
-
-If the Sheepdog daemon doesn't run on the local host, you need to
-specify one of the Sheepdog servers to connect to.
-
-.. parsed-literal::
-
- qemu-img create sheepdog://HOSTNAME:PORT/IMAGE SIZE
- |qemu_system| sheepdog://HOSTNAME:PORT/IMAGE
-
iSCSI LUNs
~~~~~~~~~~
diff --git a/docs/system/removed-features.rst b/docs/system/removed-features.rst
index c21e6fa5ee..5a462ac568 100644
--- a/docs/system/removed-features.rst
+++ b/docs/system/removed-features.rst
@@ -291,6 +291,27 @@ via the CPU ``mmu`` option when using the ``rv32`` or ``rv64`` CPUs.
The ``max-cpu-compat`` property of the ``pseries`` machine type should be used
instead.
+``moxie`` CPU (removed in 6.1)
+''''''''''''''''''''''''''''''
+
+Nobody was using this CPU emulation in QEMU, and there were no test images
+available to make sure that the code is still working, so it has been removed
+without replacement.
+
+``lm32`` CPUs (removed in 6.1.0)
+''''''''''''''''''''''''''''''''
+
+The only public user of this architecture was the milkymist project,
+which has been dead for years; there was never an upstream Linux
+port. Removed without replacement.
+
+``unicore32`` CPUs (since 6.1.0)
+''''''''''''''''''''''''''''''''
+
+Support for this CPU was removed from the upstream Linux kernel, and
+there is no available upstream toolchain to build binaries for it.
+Removed without replacement.
+
System emulator machines
------------------------
@@ -467,3 +488,10 @@ VXHS backend (removed in 5.1)
'''''''''''''''''''''''''''''
The VXHS code did not compile since v2.12.0. It was removed in 5.1.
+
+``sheepdog`` driver (removed in 6.0)
+''''''''''''''''''''''''''''''''''''
+
+The corresponding upstream server project is no longer maintained.
+Users are recommended to switch to an alternative distributed block
+device driver such as RBD.
diff --git a/docs/tools/_templates/editpage.html b/docs/tools/_templates/editpage.html
deleted file mode 100644
index 2a9c8fc92b..0000000000
--- a/docs/tools/_templates/editpage.html
+++ /dev/null
@@ -1,5 +0,0 @@
-<div id="editpage">
- <ul>
- <li><a href="https://gitlab.com/qemu-project/qemu/-/blob/master/docs/tools/{{pagename}}.rst">Page source</a></li>
- </ul>
-</div>
diff --git a/docs/tools/qemu-img.rst b/docs/tools/qemu-img.rst
index c9efcfaefc..cfe1147879 100644
--- a/docs/tools/qemu-img.rst
+++ b/docs/tools/qemu-img.rst
@@ -866,6 +866,37 @@ Supported image file formats:
issue ``lsattr filename`` to check if the NOCOW flag is set or not
(Capital 'C' is NOCOW flag).
+ ``data_file``
+ Filename where all guest data will be stored. If this option is used,
+ the qcow2 file will only contain the image's metadata.
+
+ Note: Data loss will occur if the given filename already exists when
+ using this option with ``qemu-img create`` since ``qemu-img`` will create
+ the data file anew, overwriting the file's original contents. To simply
+ update the reference to point to the given pre-existing file, use
+ ``qemu-img amend``.
+
+ ``data_file_raw``
+ If this option is set to ``on``, QEMU will always keep the external data
+ file consistent as a standalone read-only raw image.
+
+ It does this by forwarding all write accesses to the qcow2 file through to
+ the raw data file, including their offsets. Therefore, data that is visible
+ on the qcow2 node (i.e., to the guest) at some offset is visible at the same
+ offset in the raw data file. This results in a read-only raw image. Writes
+ that bypass the qcow2 metadata may corrupt the qcow2 metadata because the
+ out-of-band writes may result in the metadata falling out of sync with the
+ raw image.
+
+ If this option is ``off``, QEMU will use the data file to store data in an
+ arbitrary manner. The file’s content will not make sense without the
+ accompanying qcow2 metadata. Where data is written will have no relation to
+ its offset as seen by the guest, and some writes (specifically zero writes)
+ may not be forwarded to the data file at all, but will only be handled by
+ modifying qcow2 metadata.
+
+ This option can only be enabled if ``data_file`` is set.
+
``Other``
QEMU also supports various other image file formats for
diff --git a/docs/user/_templates/editpage.html b/docs/user/_templates/editpage.html
deleted file mode 100644
index 1f5ee01e60..0000000000
--- a/docs/user/_templates/editpage.html
+++ /dev/null
@@ -1,5 +0,0 @@
-<div id="editpage">
- <ul>
- <li><a href="https://gitlab.com/qemu-project/qemu/-/blob/master/docs/user/{{pagename}}.rst">Page source</a></li>
- </ul>
-</div>
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
index 78f699d6f8..e19809c04b 100644
--- a/fpu/softfloat-specialize.c.inc
+++ b/fpu/softfloat-specialize.c.inc
@@ -103,7 +103,7 @@ static inline bool snan_bit_is_one(float_status *status)
{
#if defined(TARGET_MIPS)
return status->snan_bit_is_one;
-#elif defined(TARGET_HPPA) || defined(TARGET_UNICORE32) || defined(TARGET_SH4)
+#elif defined(TARGET_HPPA) || defined(TARGET_SH4)
return 1;
#else
return 0;
@@ -149,11 +149,10 @@ static FloatParts parts_default_nan(float_status *status)
sign = 1;
frac = ~0ULL;
#else
- /* This case is true for Alpha, ARM, MIPS, OpenRISC, PPC, RISC-V,
- * S390, SH4, TriCore, and Xtensa. I cannot find documentation
- * for Unicore32; the choice from the original commit is unchanged.
- * Our other supported targets, CRIS, LM32, Moxie, Nios2, and Tile,
- * do not have floating-point.
+ /*
+ * This case is true for Alpha, ARM, MIPS, OpenRISC, PPC, RISC-V,
+ * S390, SH4, TriCore, and Xtensa. Our other supported targets,
+ * CRIS, Nios2, and Tile, do not have floating-point.
*/
if (snan_bit_is_one(status)) {
/* set all bits other than msb */
diff --git a/hw/Kconfig b/hw/Kconfig
index ff40bd3f7b..aa10357adf 100644
--- a/hw/Kconfig
+++ b/hw/Kconfig
@@ -47,11 +47,9 @@ source avr/Kconfig
source cris/Kconfig
source hppa/Kconfig
source i386/Kconfig
-source lm32/Kconfig
source m68k/Kconfig
source microblaze/Kconfig
source mips/Kconfig
-source moxie/Kconfig
source nios2/Kconfig
source openrisc/Kconfig
source ppc/Kconfig
@@ -62,7 +60,6 @@ source sh4/Kconfig
source sparc/Kconfig
source sparc64/Kconfig
source tricore/Kconfig
-source unicore32/Kconfig
source xtensa/Kconfig
# Symbols used by multiple targets
diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c
index d33ce8954a..f0035d2b4a 100644
--- a/hw/acpi/aml-build.c
+++ b/hw/acpi/aml-build.c
@@ -1830,6 +1830,7 @@ build_rsdt(GArray *table_data, BIOSLinker *linker, GArray *table_offsets,
int i;
unsigned rsdt_entries_offset;
AcpiRsdtDescriptorRev1 *rsdt;
+ int rsdt_start = table_data->len;
const unsigned table_data_len = (sizeof(uint32_t) * table_offsets->len);
const unsigned rsdt_entry_size = sizeof(rsdt->table_offset_entry[0]);
const size_t rsdt_len = sizeof(*rsdt) + table_data_len;
@@ -1846,7 +1847,8 @@ build_rsdt(GArray *table_data, BIOSLinker *linker, GArray *table_offsets,
ACPI_BUILD_TABLE_FILE, ref_tbl_offset);
}
build_header(linker, table_data,
- (void *)rsdt, "RSDT", rsdt_len, 1, oem_id, oem_table_id);
+ (void *)(table_data->data + rsdt_start),
+ "RSDT", rsdt_len, 1, oem_id, oem_table_id);
}
/* Build xsdt table */
@@ -1857,6 +1859,7 @@ build_xsdt(GArray *table_data, BIOSLinker *linker, GArray *table_offsets,
int i;
unsigned xsdt_entries_offset;
AcpiXsdtDescriptorRev2 *xsdt;
+ int xsdt_start = table_data->len;
const unsigned table_data_len = (sizeof(uint64_t) * table_offsets->len);
const unsigned xsdt_entry_size = sizeof(xsdt->table_offset_entry[0]);
const size_t xsdt_len = sizeof(*xsdt) + table_data_len;
@@ -1873,7 +1876,8 @@ build_xsdt(GArray *table_data, BIOSLinker *linker, GArray *table_offsets,
ACPI_BUILD_TABLE_FILE, ref_tbl_offset);
}
build_header(linker, table_data,
- (void *)xsdt, "XSDT", xsdt_len, 1, oem_id, oem_table_id);
+ (void *)(table_data->data + xsdt_start),
+ "XSDT", xsdt_len, 1, oem_id, oem_table_id);
}
void build_srat_memory(AcpiSratMemoryAffinity *numamem, uint64_t base,
@@ -2053,10 +2057,9 @@ void build_tpm2(GArray *table_data, BIOSLinker *linker, GArray *tcpalog,
uint64_t control_area_start_address;
TPMIf *tpmif = tpm_find();
uint32_t start_method;
- void *tpm2_ptr;
tpm2_start = table_data->len;
- tpm2_ptr = acpi_data_push(table_data, sizeof(AcpiTableHeader));
+ acpi_data_push(table_data, sizeof(AcpiTableHeader));
/* Platform Class */
build_append_int_noprefix(table_data, TPM2_ACPI_CLASS_CLIENT, 2);
@@ -2095,8 +2098,8 @@ void build_tpm2(GArray *table_data, BIOSLinker *linker, GArray *tcpalog,
log_addr_offset, 8,
ACPI_BUILD_TPMLOG_FILE, 0);
build_header(linker, table_data,
- tpm2_ptr, "TPM2", table_data->len - tpm2_start, 4, oem_id,
- oem_table_id);
+ (void *)(table_data->data + tpm2_start),
+ "TPM2", table_data->len - tpm2_start, 4, oem_id, oem_table_id);
}
Aml *build_crs(PCIHostState *host, CrsRangeSet *range_set, uint32_t io_offset,
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 0a78532018..840758666d 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -50,6 +50,7 @@
#include "sysemu/tpm.h"
#include "sysemu/kvm.h"
#include "hw/loader.h"
+#include "qapi/error.h"
#include "qemu/bitops.h"
#include "qemu/error-report.h"
#include "qemu/module.h"
@@ -1521,8 +1522,10 @@ static void virt_build_smbios(VirtMachineState *vms)
vmc->smbios_old_sys_ver ? "1.0" : mc->name, false,
true, SMBIOS_ENTRY_POINT_30);
- smbios_get_tables(MACHINE(vms), NULL, 0, &smbios_tables, &smbios_tables_len,
- &smbios_anchor, &smbios_anchor_len);
+ smbios_get_tables(MACHINE(vms), NULL, 0,
+ &smbios_tables, &smbios_tables_len,
+ &smbios_anchor, &smbios_anchor_len,
+ &error_fatal);
if (smbios_anchor) {
fw_cfg_add_file(vms->fw_cfg, "etc/smbios/smbios-tables",
diff --git a/hw/audio/meson.build b/hw/audio/meson.build
index 32c42bdebe..e48a9fc73d 100644
--- a/hw/audio/meson.build
+++ b/hw/audio/meson.build
@@ -7,7 +7,6 @@ softmmu_ss.add(when: 'CONFIG_ES1370', if_true: files('es1370.c'))
softmmu_ss.add(when: 'CONFIG_GUS', if_true: files('gus.c', 'gusemu_hal.c', 'gusemu_mixer.c'))
softmmu_ss.add(when: 'CONFIG_HDA', if_true: files('intel-hda.c', 'hda-codec.c'))
softmmu_ss.add(when: 'CONFIG_MARVELL_88W8618', if_true: files('marvell_88w8618.c'))
-softmmu_ss.add(when: 'CONFIG_MILKYMIST', if_true: files('milkymist-ac97.c'))
softmmu_ss.add(when: 'CONFIG_PCSPK', if_true: files('pcspk.c'))
softmmu_ss.add(when: 'CONFIG_PL041', if_true: files('pl041.c', 'lm4549.c'))
softmmu_ss.add(when: 'CONFIG_SB16', if_true: files('sb16.c'))
diff --git a/hw/audio/milkymist-ac97.c b/hw/audio/milkymist-ac97.c
deleted file mode 100644
index 7d2e057038..0000000000
--- a/hw/audio/milkymist-ac97.c
+++ /dev/null
@@ -1,360 +0,0 @@
-/*
- * QEMU model of the Milkymist System Controller.
- *
- * Copyright (c) 2010 Michael Walle <michael@walle.cc>
- *
- * 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.1 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/>.
- *
- *
- * Specification available at:
- * http://milkymist.walle.cc/socdoc/ac97.pdf
- */
-
-#include "qemu/osdep.h"
-#include "hw/irq.h"
-#include "hw/sysbus.h"
-#include "migration/vmstate.h"
-#include "trace.h"
-#include "audio/audio.h"
-#include "qemu/error-report.h"
-#include "qemu/module.h"
-#include "qom/object.h"
-
-enum {
- R_AC97_CTRL = 0,
- R_AC97_ADDR,
- R_AC97_DATAOUT,
- R_AC97_DATAIN,
- R_D_CTRL,
- R_D_ADDR,
- R_D_REMAINING,
- R_RESERVED,
- R_U_CTRL,
- R_U_ADDR,
- R_U_REMAINING,
- R_MAX
-};
-
-enum {
- AC97_CTRL_RQEN = (1<<0),
- AC97_CTRL_WRITE = (1<<1),
-};
-
-enum {
- CTRL_EN = (1<<0),
-};
-
-#define TYPE_MILKYMIST_AC97 "milkymist-ac97"
-OBJECT_DECLARE_SIMPLE_TYPE(MilkymistAC97State, MILKYMIST_AC97)
-
-struct MilkymistAC97State {
- SysBusDevice parent_obj;
-
- MemoryRegion regs_region;
-
- QEMUSoundCard card;
- SWVoiceIn *voice_in;
- SWVoiceOut *voice_out;
-
- uint32_t regs[R_MAX];
-
- qemu_irq crrequest_irq;
- qemu_irq crreply_irq;
- qemu_irq dmar_irq;
- qemu_irq dmaw_irq;
-};
-
-static void update_voices(MilkymistAC97State *s)
-{
- if (s->regs[R_D_CTRL] & CTRL_EN) {
- AUD_set_active_out(s->voice_out, 1);
- } else {
- AUD_set_active_out(s->voice_out, 0);
- }
-
- if (s->regs[R_U_CTRL] & CTRL_EN) {
- AUD_set_active_in(s->voice_in, 1);
- } else {
- AUD_set_active_in(s->voice_in, 0);
- }
-}
-
-static uint64_t ac97_read(void *opaque, hwaddr addr,
- unsigned size)
-{
- MilkymistAC97State *s = opaque;
- uint32_t r = 0;
-
- addr >>= 2;
- switch (addr) {
- case R_AC97_CTRL:
- case R_AC97_ADDR:
- case R_AC97_DATAOUT:
- case R_AC97_DATAIN:
- case R_D_CTRL:
- case R_D_ADDR:
- case R_D_REMAINING:
- case R_U_CTRL:
- case R_U_ADDR:
- case R_U_REMAINING:
- r = s->regs[addr];
- break;
-
- default:
- error_report("milkymist_ac97: read access to unknown register 0x"
- TARGET_FMT_plx, addr << 2);
- break;
- }
-
- trace_milkymist_ac97_memory_read(addr << 2, r);
-
- return r;
-}
-
-static void ac97_write(void *opaque, hwaddr addr, uint64_t value,
- unsigned size)
-{
- MilkymistAC97State *s = opaque;
-
- trace_milkymist_ac97_memory_write(addr, value);
-
- addr >>= 2;
- switch (addr) {
- case R_AC97_CTRL:
- /* always raise an IRQ according to the direction */
- if (value & AC97_CTRL_RQEN) {
- if (value & AC97_CTRL_WRITE) {
- trace_milkymist_ac97_pulse_irq_crrequest();
- qemu_irq_pulse(s->crrequest_irq);
- } else {
- trace_milkymist_ac97_pulse_irq_crreply();
- qemu_irq_pulse(s->crreply_irq);
- }
- }
-
- /* RQEN is self clearing */
- s->regs[addr] = value & ~AC97_CTRL_RQEN;
- break;
- case R_D_CTRL:
- case R_U_CTRL:
- s->regs[addr] = value;
- update_voices(s);
- break;
- case R_AC97_ADDR:
- case R_AC97_DATAOUT:
- case R_AC97_DATAIN:
- case R_D_ADDR:
- case R_D_REMAINING:
- case R_U_ADDR:
- case R_U_REMAINING:
- s->regs[addr] = value;
- break;
-
- default:
- error_report("milkymist_ac97: write access to unknown register 0x"
- TARGET_FMT_plx, addr);
- break;
- }
-
-}
-
-static const MemoryRegionOps ac97_mmio_ops = {
- .read = ac97_read,
- .write = ac97_write,
- .valid = {
- .min_access_size = 4,
- .max_access_size = 4,
- },
- .endianness = DEVICE_NATIVE_ENDIAN,
-};
-
-static void ac97_in_cb(void *opaque, int avail_b)
-{
- MilkymistAC97State *s = opaque;
- uint8_t buf[4096];
- uint32_t remaining = s->regs[R_U_REMAINING];
- int temp = MIN(remaining, avail_b);
- uint32_t addr = s->regs[R_U_ADDR];
- int transferred = 0;
-
- trace_milkymist_ac97_in_cb(avail_b, remaining);
-
- /* prevent from raising an IRQ */
- if (temp == 0) {
- return;
- }
-
- while (temp) {
- int acquired, to_copy;
-
- to_copy = MIN(temp, sizeof(buf));
- acquired = AUD_read(s->voice_in, buf, to_copy);
- if (!acquired) {
- break;
- }
-
- cpu_physical_memory_write(addr, buf, acquired);
-
- temp -= acquired;
- addr += acquired;
- transferred += acquired;
- }
-
- trace_milkymist_ac97_in_cb_transferred(transferred);
-
- s->regs[R_U_ADDR] = addr;
- s->regs[R_U_REMAINING] -= transferred;
-
- if ((s->regs[R_U_CTRL] & CTRL_EN) && (s->regs[R_U_REMAINING] == 0)) {
- trace_milkymist_ac97_pulse_irq_dmaw();
- qemu_irq_pulse(s->dmaw_irq);
- }
-}
-
-static void ac97_out_cb(void *opaque, int free_b)
-{
- MilkymistAC97State *s = opaque;
- uint8_t buf[4096];
- uint32_t remaining = s->regs[R_D_REMAINING];
- int temp = MIN(remaining, free_b);
- uint32_t addr = s->regs[R_D_ADDR];
- int transferred = 0;
-
- trace_milkymist_ac97_out_cb(free_b, remaining);
-
- /* prevent from raising an IRQ */
- if (temp == 0) {
- return;
- }
-
- while (temp) {
- int copied, to_copy;
-
- to_copy = MIN(temp, sizeof(buf));
- cpu_physical_memory_read(addr, buf, to_copy);
- copied = AUD_write(s->voice_out, buf, to_copy);
- if (!copied) {
- break;
- }
- temp -= copied;
- addr += copied;
- transferred += copied;
- }
-
- trace_milkymist_ac97_out_cb_transferred(transferred);
-
- s->regs[R_D_ADDR] = addr;
- s->regs[R_D_REMAINING] -= transferred;
-
- if ((s->regs[R_D_CTRL] & CTRL_EN) && (s->regs[R_D_REMAINING] == 0)) {
- trace_milkymist_ac97_pulse_irq_dmar();
- qemu_irq_pulse(s->dmar_irq);
- }
-}
-
-static void milkymist_ac97_reset(DeviceState *d)
-{
- MilkymistAC97State *s = MILKYMIST_AC97(d);
- int i;
-
- for (i = 0; i < R_MAX; i++) {
- s->regs[i] = 0;
- }
-
- AUD_set_active_in(s->voice_in, 0);
- AUD_set_active_out(s->voice_out, 0);
-}
-
-static int ac97_post_load(void *opaque, int version_id)
-{
- MilkymistAC97State *s = opaque;
-
- update_voices(s);
-
- return 0;
-}
-
-static void milkymist_ac97_init(Object *obj)
-{
- MilkymistAC97State *s = MILKYMIST_AC97(obj);
- SysBusDevice *dev = SYS_BUS_DEVICE(obj);
-
- sysbus_init_irq(dev, &s->crrequest_irq);
- sysbus_init_irq(dev, &s->crreply_irq);
- sysbus_init_irq(dev, &s->dmar_irq);
- sysbus_init_irq(dev, &s->dmaw_irq);
-
- memory_region_init_io(&s->regs_region, obj, &ac97_mmio_ops, s,
- "milkymist-ac97", R_MAX * 4);
- sysbus_init_mmio(dev, &s->regs_region);
-}
-
-static void milkymist_ac97_realize(DeviceState *dev, Error **errp)
-{
- MilkymistAC97State *s = MILKYMIST_AC97(dev);
- struct audsettings as;
-
- AUD_register_card("Milkymist AC'97", &s->card);
-
- as.freq = 48000;
- as.nchannels = 2;
- as.fmt = AUDIO_FORMAT_S16;
- as.endianness = 1;
-
- s->voice_in = AUD_open_in(&s->card, s->voice_in,
- "mm_ac97.in", s, ac97_in_cb, &as);
- s->voice_out = AUD_open_out(&s->card, s->voice_out,
- "mm_ac97.out", s, ac97_out_cb, &as);
-}
-
-static const VMStateDescription vmstate_milkymist_ac97 = {
- .name = "milkymist-ac97",
- .version_id = 1,
- .minimum_version_id = 1,
- .post_load = ac97_post_load,
- .fields = (VMStateField[]) {
- VMSTATE_UINT32_ARRAY(regs, MilkymistAC97State, R_MAX),
- VMSTATE_END_OF_LIST()
- }
-};
-
-static Property milkymist_ac97_properties[] = {
- DEFINE_AUDIO_PROPERTIES(MilkymistAC97State, card),
- DEFINE_PROP_END_OF_LIST(),
-};
-
-static void milkymist_ac97_class_init(ObjectClass *klass, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(klass);
-
- dc->realize = milkymist_ac97_realize;
- dc->reset = milkymist_ac97_reset;
- dc->vmsd = &vmstate_milkymist_ac97;
- device_class_set_props(dc, milkymist_ac97_properties);
-}
-
-static const TypeInfo milkymist_ac97_info = {
- .name = TYPE_MILKYMIST_AC97,
- .parent = TYPE_SYS_BUS_DEVICE,
- .instance_size = sizeof(MilkymistAC97State),
- .instance_init = milkymist_ac97_init,
- .class_init = milkymist_ac97_class_init,
-};
-
-static void milkymist_ac97_register_types(void)
-{
- type_register_static(&milkymist_ac97_info);
-}
-
-type_init(milkymist_ac97_register_types)
diff --git a/hw/audio/trace-events b/hw/audio/trace-events
index 60556b4a97..432e10712f 100644
--- a/hw/audio/trace-events
+++ b/hw/audio/trace-events
@@ -6,18 +6,6 @@ cs4231_mem_readl_reg(uint32_t reg, uint32_t ret) "read reg %d: 0x%08x"
cs4231_mem_writel_reg(uint32_t reg, uint32_t old, uint32_t val) "write reg %d: 0x%08x -> 0x%08x"
cs4231_mem_writel_dreg(uint32_t reg, uint32_t old, uint32_t val) "write dreg %d: 0x%02x -> 0x%02x"
-# milkymist-ac97.c
-milkymist_ac97_memory_read(uint32_t addr, uint32_t value) "addr 0x%08x value 0x%08x"
-milkymist_ac97_memory_write(uint32_t addr, uint32_t value) "addr 0x%08x value 0x%08x"
-milkymist_ac97_pulse_irq_crrequest(void) "Pulse IRQ CR request"
-milkymist_ac97_pulse_irq_crreply(void) "Pulse IRQ CR reply"
-milkymist_ac97_pulse_irq_dmaw(void) "Pulse IRQ DMA write"
-milkymist_ac97_pulse_irq_dmar(void) "Pulse IRQ DMA read"
-milkymist_ac97_in_cb(int avail, uint32_t remaining) "avail %d remaining %u"
-milkymist_ac97_in_cb_transferred(int transferred) "transferred %d"
-milkymist_ac97_out_cb(int free, uint32_t remaining) "free %d remaining %u"
-milkymist_ac97_out_cb_transferred(int transferred) "transferred %d"
-
# hda-codec.c
hda_audio_running(const char *stream, int nr, bool running) "st %s, nr %d, run %d"
hda_audio_format(const char *stream, int chan, const char *fmt, int freq) "st %s, %d x %s @ %d Hz"
diff --git a/hw/block/dataplane/virtio-blk.c b/hw/block/dataplane/virtio-blk.c
index e9050c8987..cd81893d1d 100644
--- a/hw/block/dataplane/virtio-blk.c
+++ b/hw/block/dataplane/virtio-blk.c
@@ -198,19 +198,30 @@ int virtio_blk_data_plane_start(VirtIODevice *vdev)
goto fail_guest_notifiers;
}
+ memory_region_transaction_begin();
+
/* Set up virtqueue notify */
for (i = 0; i < nvqs; i++) {
r = virtio_bus_set_host_notifier(VIRTIO_BUS(qbus), i, true);
if (r != 0) {
+ int j = i;
+
fprintf(stderr, "virtio-blk failed to set host notifier (%d)\n", r);
while (i--) {
virtio_bus_set_host_notifier(VIRTIO_BUS(qbus), i, false);
+ }
+
+ memory_region_transaction_commit();
+
+ while (j--) {
virtio_bus_cleanup_host_notifier(VIRTIO_BUS(qbus), i);
}
- goto fail_guest_notifiers;
+ goto fail_host_notifiers;
}
}
+ memory_region_transaction_commit();
+
s->starting = false;
vblk->dataplane_started = true;
trace_virtio_blk_data_plane_start(s);
@@ -221,7 +232,7 @@ int virtio_blk_data_plane_start(VirtIODevice *vdev)
aio_context_release(old_context);
if (r < 0) {
error_report_err(local_err);
- goto fail_guest_notifiers;
+ goto fail_aio_context;
}
/* Process queued requests before the ones in vring */
@@ -245,6 +256,20 @@ int virtio_blk_data_plane_start(VirtIODevice *vdev)
aio_context_release(s->ctx);
return 0;
+ fail_aio_context:
+ memory_region_transaction_begin();
+
+ for (i = 0; i < nvqs; i++) {
+ virtio_bus_set_host_notifier(VIRTIO_BUS(qbus), i, false);
+ }
+
+ memory_region_transaction_commit();
+
+ for (i = 0; i < nvqs; i++) {
+ virtio_bus_cleanup_host_notifier(VIRTIO_BUS(qbus), i);
+ }
+ fail_host_notifiers:
+ k->set_guest_notifiers(qbus->parent, nvqs, false);
fail_guest_notifiers:
/*
* If we failed to set up the guest notifiers queued requests will be
@@ -305,8 +330,15 @@ void virtio_blk_data_plane_stop(VirtIODevice *vdev)
aio_context_release(s->ctx);
+ memory_region_transaction_begin();
+
for (i = 0; i < nvqs; i++) {
virtio_bus_set_host_notifier(VIRTIO_BUS(qbus), i, false);
+ }
+
+ memory_region_transaction_commit();
+
+ for (i = 0; i < nvqs; i++) {
virtio_bus_cleanup_host_notifier(VIRTIO_BUS(qbus), i);
}
diff --git a/hw/block/pflash_cfi02.c b/hw/block/pflash_cfi02.c
index 25c053693c..02c514fb6e 100644
--- a/hw/block/pflash_cfi02.c
+++ b/hw/block/pflash_cfi02.c
@@ -173,7 +173,6 @@ static void pflash_setup_mappings(PFlashCFI02 *pfl)
"pflash-alias", &pfl->orig_mem, 0, size);
memory_region_add_subregion(&pfl->mem, i * size, &pfl->mem_mappings[i]);
}
- pfl->rom_mode = true;
}
static void pflash_reset_state_machine(PFlashCFI02 *pfl)
@@ -917,8 +916,13 @@ static void pflash_cfi02_realize(DeviceState *dev, Error **errp)
/* Allocate memory for a bitmap for sectors being erased. */
pfl->sector_erase_map = bitmap_new(pfl->total_sectors);
- pflash_setup_mappings(pfl);
- sysbus_init_mmio(SYS_BUS_DEVICE(dev), &pfl->mem);
+ pfl->rom_mode = true;
+ if (pfl->mappings > 1) {
+ pflash_setup_mappings(pfl);
+ sysbus_init_mmio(SYS_BUS_DEVICE(dev), &pfl->mem);
+ } else {
+ sysbus_init_mmio(SYS_BUS_DEVICE(dev), &pfl->orig_mem);
+ }
timer_init_ns(&pfl->timer, QEMU_CLOCK_VIRTUAL, pflash_timer, pfl);
pfl->status = 0;
diff --git a/hw/char/lm32_juart.c b/hw/char/lm32_juart.c
deleted file mode 100644
index ce30279650..0000000000
--- a/hw/char/lm32_juart.c
+++ /dev/null
@@ -1,166 +0,0 @@
-/*
- * LatticeMico32 JTAG UART model.
- *
- * Copyright (c) 2010 Michael Walle <michael@walle.cc>
- *
- * 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.1 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 "hw/sysbus.h"
-#include "migration/vmstate.h"
-#include "qemu/module.h"
-#include "trace.h"
-#include "chardev/char-fe.h"
-
-#include "hw/char/lm32_juart.h"
-#include "hw/qdev-properties.h"
-#include "hw/qdev-properties-system.h"
-#include "qom/object.h"
-
-enum {
- LM32_JUART_MIN_SAVE_VERSION = 0,
- LM32_JUART_CURRENT_SAVE_VERSION = 0,
- LM32_JUART_MAX_SAVE_VERSION = 0,
-};
-
-enum {
- JTX_FULL = (1<<8),
-};
-
-enum {
- JRX_FULL = (1<<8),
-};
-
-OBJECT_DECLARE_SIMPLE_TYPE(LM32JuartState, LM32_JUART)
-
-struct LM32JuartState {
- SysBusDevice parent_obj;
-
- CharBackend chr;
-
- uint32_t jtx;
- uint32_t jrx;
-};
-
-uint32_t lm32_juart_get_jtx(DeviceState *d)
-{
- LM32JuartState *s = LM32_JUART(d);
-
- trace_lm32_juart_get_jtx(s->jtx);
- return s->jtx;
-}
-
-uint32_t lm32_juart_get_jrx(DeviceState *d)
-{
- LM32JuartState *s = LM32_JUART(d);
-
- trace_lm32_juart_get_jrx(s->jrx);
- return s->jrx;
-}
-
-void lm32_juart_set_jtx(DeviceState *d, uint32_t jtx)
-{
- LM32JuartState *s = LM32_JUART(d);
- unsigned char ch = jtx & 0xff;
-
- trace_lm32_juart_set_jtx(s->jtx);
-
- s->jtx = jtx;
- /* XXX this blocks entire thread. Rewrite to use
- * qemu_chr_fe_write and background I/O callbacks */
- qemu_chr_fe_write_all(&s->chr, &ch, 1);
-}
-
-void lm32_juart_set_jrx(DeviceState *d, uint32_t jtx)
-{
- LM32JuartState *s = LM32_JUART(d);
-
- trace_lm32_juart_set_jrx(s->jrx);
- s->jrx &= ~JRX_FULL;
-}
-
-static void juart_rx(void *opaque, const uint8_t *buf, int size)
-{
- LM32JuartState *s = opaque;
-
- s->jrx = *buf | JRX_FULL;
-}
-
-static int juart_can_rx(void *opaque)
-{
- LM32JuartState *s = opaque;
-
- return !(s->jrx & JRX_FULL);
-}
-
-static void juart_event(void *opaque, QEMUChrEvent event)
-{
-}
-
-static void juart_reset(DeviceState *d)
-{
- LM32JuartState *s = LM32_JUART(d);
-
- s->jtx = 0;
- s->jrx = 0;
-}
-
-static void lm32_juart_realize(DeviceState *dev, Error **errp)
-{
- LM32JuartState *s = LM32_JUART(dev);
-
- qemu_chr_fe_set_handlers(&s->chr, juart_can_rx, juart_rx,
- juart_event, NULL, s, NULL, true);
-}
-
-static const VMStateDescription vmstate_lm32_juart = {
- .name = "lm32-juart",
- .version_id = 1,
- .minimum_version_id = 1,
- .fields = (VMStateField[]) {
- VMSTATE_UINT32(jtx, LM32JuartState),
- VMSTATE_UINT32(jrx, LM32JuartState),
- VMSTATE_END_OF_LIST()
- }
-};
-
-static Property lm32_juart_properties[] = {
- DEFINE_PROP_CHR("chardev", LM32JuartState, chr),
- DEFINE_PROP_END_OF_LIST(),
-};
-
-static void lm32_juart_class_init(ObjectClass *klass, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(klass);
-
- dc->reset = juart_reset;
- dc->vmsd = &vmstate_lm32_juart;
- device_class_set_props(dc, lm32_juart_properties);
- dc->realize = lm32_juart_realize;
-}
-
-static const TypeInfo lm32_juart_info = {
- .name = TYPE_LM32_JUART,
- .parent = TYPE_SYS_BUS_DEVICE,
- .instance_size = sizeof(LM32JuartState),
- .class_init = lm32_juart_class_init,
-};
-
-static void lm32_juart_register_types(void)
-{
- type_register_static(&lm32_juart_info);
-}
-
-type_init(lm32_juart_register_types)
diff --git a/hw/char/lm32_uart.c b/hw/char/lm32_uart.c
deleted file mode 100644
index d8e0331311..0000000000
--- a/hw/char/lm32_uart.c
+++ /dev/null
@@ -1,314 +0,0 @@
-/*
- * QEMU model of the LatticeMico32 UART block.
- *
- * Copyright (c) 2010 Michael Walle <michael@walle.cc>
- *
- * 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.1 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/>.
- *
- *
- * Specification available at:
- * http://www.latticesemi.com/documents/mico32uart.pdf
- */
-
-
-#include "qemu/osdep.h"
-#include "hw/irq.h"
-#include "hw/qdev-properties.h"
-#include "hw/qdev-properties-system.h"
-#include "hw/sysbus.h"
-#include "migration/vmstate.h"
-#include "trace.h"
-#include "chardev/char-fe.h"
-#include "qemu/error-report.h"
-#include "qemu/module.h"
-#include "qom/object.h"
-
-enum {
- R_RXTX = 0,
- R_IER,
- R_IIR,
- R_LCR,
- R_MCR,
- R_LSR,
- R_MSR,
- R_DIV,
- R_MAX
-};
-
-enum {
- IER_RBRI = (1<<0),
- IER_THRI = (1<<1),
- IER_RLSI = (1<<2),
- IER_MSI = (1<<3),
-};
-
-enum {
- IIR_STAT = (1<<0),
- IIR_ID0 = (1<<1),
- IIR_ID1 = (1<<2),
-};
-
-enum {
- LCR_WLS0 = (1<<0),
- LCR_WLS1 = (1<<1),
- LCR_STB = (1<<2),
- LCR_PEN = (1<<3),
- LCR_EPS = (1<<4),
- LCR_SP = (1<<5),
- LCR_SB = (1<<6),
-};
-
-enum {
- MCR_DTR = (1<<0),
- MCR_RTS = (1<<1),
-};
-
-enum {
- LSR_DR = (1<<0),
- LSR_OE = (1<<1),
- LSR_PE = (1<<2),
- LSR_FE = (1<<3),
- LSR_BI = (1<<4),
- LSR_THRE = (1<<5),
- LSR_TEMT = (1<<6),
-};
-
-enum {
- MSR_DCTS = (1<<0),
- MSR_DDSR = (1<<1),
- MSR_TERI = (1<<2),
- MSR_DDCD = (1<<3),
- MSR_CTS = (1<<4),
- MSR_DSR = (1<<5),
- MSR_RI = (1<<6),
- MSR_DCD = (1<<7),
-};
-
-#define TYPE_LM32_UART "lm32-uart"
-OBJECT_DECLARE_SIMPLE_TYPE(LM32UartState, LM32_UART)
-
-struct LM32UartState {
- SysBusDevice parent_obj;
-
- MemoryRegion iomem;
- CharBackend chr;
- qemu_irq irq;
-
- uint32_t regs[R_MAX];
-};
-
-static void uart_update_irq(LM32UartState *s)
-{
- unsigned int irq;
-
- if ((s->regs[R_LSR] & (LSR_OE | LSR_PE | LSR_FE | LSR_BI))
- && (s->regs[R_IER] & IER_RLSI)) {
- irq = 1;
- s->regs[R_IIR] = IIR_ID1 | IIR_ID0;
- } else if ((s->regs[R_LSR] & LSR_DR) && (s->regs[R_IER] & IER_RBRI)) {
- irq = 1;
- s->regs[R_IIR] = IIR_ID1;
- } else if ((s->regs[R_LSR] & LSR_THRE) && (s->regs[R_IER] & IER_THRI)) {
- irq = 1;
- s->regs[R_IIR] = IIR_ID0;
- } else if ((s->regs[R_MSR] & 0x0f) && (s->regs[R_IER] & IER_MSI)) {
- irq = 1;
- s->regs[R_IIR] = 0;
- } else {
- irq = 0;
- s->regs[R_IIR] = IIR_STAT;
- }
-
- trace_lm32_uart_irq_state(irq);
- qemu_set_irq(s->irq, irq);
-}
-
-static uint64_t uart_read(void *opaque, hwaddr addr,
- unsigned size)
-{
- LM32UartState *s = opaque;
- uint32_t r = 0;
-
- addr >>= 2;
- switch (addr) {
- case R_RXTX:
- r = s->regs[R_RXTX];
- s->regs[R_LSR] &= ~LSR_DR;
- uart_update_irq(s);
- qemu_chr_fe_accept_input(&s->chr);
- break;
- case R_IIR:
- case R_LSR:
- case R_MSR:
- r = s->regs[addr];
- break;
- case R_IER:
- case R_LCR:
- case R_MCR:
- case R_DIV:
- error_report("lm32_uart: read access to write only register 0x"
- TARGET_FMT_plx, addr << 2);
- break;
- default:
- error_report("lm32_uart: read access to unknown register 0x"
- TARGET_FMT_plx, addr << 2);
- break;
- }
-
- trace_lm32_uart_memory_read(addr << 2, r);
- return r;
-}
-
-static void uart_write(void *opaque, hwaddr addr,
- uint64_t value, unsigned size)
-{
- LM32UartState *s = opaque;
- unsigned char ch = value;
-
- trace_lm32_uart_memory_write(addr, value);
-
- addr >>= 2;
- switch (addr) {
- case R_RXTX:
- /* XXX this blocks entire thread. Rewrite to use
- * qemu_chr_fe_write and background I/O callbacks */
- qemu_chr_fe_write_all(&s->chr, &ch, 1);
- break;
- case R_IER:
- case R_LCR:
- case R_MCR:
- case R_DIV:
- s->regs[addr] = value;
- break;
- case R_IIR:
- case R_LSR:
- case R_MSR:
- error_report("lm32_uart: write access to read only register 0x"
- TARGET_FMT_plx, addr << 2);
- break;
- default:
- error_report("lm32_uart: write access to unknown register 0x"
- TARGET_FMT_plx, addr << 2);
- break;
- }
- uart_update_irq(s);
-}
-
-static const MemoryRegionOps uart_ops = {
- .read = uart_read,
- .write = uart_write,
- .endianness = DEVICE_NATIVE_ENDIAN,
- .valid = {
- .min_access_size = 4,
- .max_access_size = 4,
- },
-};
-
-static void uart_rx(void *opaque, const uint8_t *buf, int size)
-{
- LM32UartState *s = opaque;
-
- if (s->regs[R_LSR] & LSR_DR) {
- s->regs[R_LSR] |= LSR_OE;
- }
-
- s->regs[R_LSR] |= LSR_DR;
- s->regs[R_RXTX] = *buf;
-
- uart_update_irq(s);
-}
-
-static int uart_can_rx(void *opaque)
-{
- LM32UartState *s = opaque;
-
- return !(s->regs[R_LSR] & LSR_DR);
-}
-
-static void uart_event(void *opaque, QEMUChrEvent event)
-{
-}
-
-static void uart_reset(DeviceState *d)
-{
- LM32UartState *s = LM32_UART(d);
- int i;
-
- for (i = 0; i < R_MAX; i++) {
- s->regs[i] = 0;
- }
-
- /* defaults */
- s->regs[R_LSR] = LSR_THRE | LSR_TEMT;
-}
-
-static void lm32_uart_init(Object *obj)
-{
- LM32UartState *s = LM32_UART(obj);
- SysBusDevice *dev = SYS_BUS_DEVICE(obj);
-
- sysbus_init_irq(dev, &s->irq);
-
- memory_region_init_io(&s->iomem, obj, &uart_ops, s,
- "uart", R_MAX * 4);
- sysbus_init_mmio(dev, &s->iomem);
-}
-
-static void lm32_uart_realize(DeviceState *dev, Error **errp)
-{
- LM32UartState *s = LM32_UART(dev);
-
- qemu_chr_fe_set_handlers(&s->chr, uart_can_rx, uart_rx,
- uart_event, NULL, s, NULL, true);
-}
-
-static const VMStateDescription vmstate_lm32_uart = {
- .name = "lm32-uart",
- .version_id = 1,
- .minimum_version_id = 1,
- .fields = (VMStateField[]) {
- VMSTATE_UINT32_ARRAY(regs, LM32UartState, R_MAX),
- VMSTATE_END_OF_LIST()
- }
-};
-
-static Property lm32_uart_properties[] = {
- DEFINE_PROP_CHR("chardev", LM32UartState, chr),
- DEFINE_PROP_END_OF_LIST(),
-};
-
-static void lm32_uart_class_init(ObjectClass *klass, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(klass);
-
- dc->reset = uart_reset;
- dc->vmsd = &vmstate_lm32_uart;
- device_class_set_props(dc, lm32_uart_properties);
- dc->realize = lm32_uart_realize;
-}
-
-static const TypeInfo lm32_uart_info = {
- .name = TYPE_LM32_UART,
- .parent = TYPE_SYS_BUS_DEVICE,
- .instance_size = sizeof(LM32UartState),
- .instance_init = lm32_uart_init,
- .class_init = lm32_uart_class_init,
-};
-
-static void lm32_uart_register_types(void)
-{
- type_register_static(&lm32_uart_info);
-}
-
-type_init(lm32_uart_register_types)
diff --git a/hw/char/meson.build b/hw/char/meson.build
index 014833dded..8361d0ab28 100644
--- a/hw/char/meson.build
+++ b/hw/char/meson.build
@@ -8,9 +8,6 @@ softmmu_ss.add(when: 'CONFIG_IMX', if_true: files('imx_serial.c'))
softmmu_ss.add(when: 'CONFIG_IPACK', if_true: files('ipoctal232.c'))
softmmu_ss.add(when: 'CONFIG_ISA_BUS', if_true: files('parallel-isa.c'))
softmmu_ss.add(when: 'CONFIG_ISA_DEBUG', if_true: files('debugcon.c'))
-softmmu_ss.add(when: 'CONFIG_LM32_DEVICES', if_true: files('lm32_juart.c'))
-softmmu_ss.add(when: 'CONFIG_LM32_DEVICES', if_true: files('lm32_uart.c'))
-softmmu_ss.add(when: 'CONFIG_MILKYMIST', if_true: files('milkymist-uart.c'))
softmmu_ss.add(when: 'CONFIG_NRF51_SOC', if_true: files('nrf51_uart.c'))
softmmu_ss.add(when: 'CONFIG_PARALLEL', if_true: files('parallel.c'))
softmmu_ss.add(when: 'CONFIG_PL011', if_true: files('pl011.c'))
diff --git a/hw/char/milkymist-uart.c b/hw/char/milkymist-uart.c
deleted file mode 100644
index cb1b3470ad..0000000000
--- a/hw/char/milkymist-uart.c
+++ /dev/null
@@ -1,258 +0,0 @@
-/*
- * QEMU model of the Milkymist UART block.
- *
- * Copyright (c) 2010 Michael Walle <michael@walle.cc>
- *
- * 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.1 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/>.
- *
- *
- * Specification available at:
- * http://milkymist.walle.cc/socdoc/uart.pdf
- */
-
-#include "qemu/osdep.h"
-#include "hw/irq.h"
-#include "hw/qdev-properties.h"
-#include "hw/qdev-properties-system.h"
-#include "hw/sysbus.h"
-#include "migration/vmstate.h"
-#include "trace.h"
-#include "chardev/char-fe.h"
-#include "qemu/error-report.h"
-#include "qemu/module.h"
-#include "qom/object.h"
-
-enum {
- R_RXTX = 0,
- R_DIV,
- R_STAT,
- R_CTRL,
- R_DBG,
- R_MAX
-};
-
-enum {
- STAT_THRE = (1<<0),
- STAT_RX_EVT = (1<<1),
- STAT_TX_EVT = (1<<2),
-};
-
-enum {
- CTRL_RX_IRQ_EN = (1<<0),
- CTRL_TX_IRQ_EN = (1<<1),
- CTRL_THRU_EN = (1<<2),
-};
-
-enum {
- DBG_BREAK_EN = (1<<0),
-};
-
-#define TYPE_MILKYMIST_UART "milkymist-uart"
-OBJECT_DECLARE_SIMPLE_TYPE(MilkymistUartState, MILKYMIST_UART)
-
-struct MilkymistUartState {
- SysBusDevice parent_obj;
-
- MemoryRegion regs_region;
- CharBackend chr;
- qemu_irq irq;
-
- uint32_t regs[R_MAX];
-};
-
-static void uart_update_irq(MilkymistUartState *s)
-{
- int rx_event = s->regs[R_STAT] & STAT_RX_EVT;
- int tx_event = s->regs[R_STAT] & STAT_TX_EVT;
- int rx_irq_en = s->regs[R_CTRL] & CTRL_RX_IRQ_EN;
- int tx_irq_en = s->regs[R_CTRL] & CTRL_TX_IRQ_EN;
-
- if ((rx_irq_en && rx_event) || (tx_irq_en && tx_event)) {
- trace_milkymist_uart_raise_irq();
- qemu_irq_raise(s->irq);
- } else {
- trace_milkymist_uart_lower_irq();
- qemu_irq_lower(s->irq);
- }
-}
-
-static uint64_t uart_read(void *opaque, hwaddr addr,
- unsigned size)
-{
- MilkymistUartState *s = opaque;
- uint32_t r = 0;
-
- addr >>= 2;
- switch (addr) {
- case R_RXTX:
- r = s->regs[addr];
- break;
- case R_DIV:
- case R_STAT:
- case R_CTRL:
- case R_DBG:
- r = s->regs[addr];
- break;
-
- default:
- error_report("milkymist_uart: read access to unknown register 0x"
- TARGET_FMT_plx, addr << 2);
- break;
- }
-
- trace_milkymist_uart_memory_read(addr << 2, r);
-
- return r;
-}
-
-static void uart_write(void *opaque, hwaddr addr, uint64_t value,
- unsigned size)
-{
- MilkymistUartState *s = opaque;
- unsigned char ch = value;
-
- trace_milkymist_uart_memory_write(addr, value);
-
- addr >>= 2;
- switch (addr) {
- case R_RXTX:
- qemu_chr_fe_write_all(&s->chr, &ch, 1);
- s->regs[R_STAT] |= STAT_TX_EVT;
- break;
- case R_DIV:
- case R_CTRL:
- case R_DBG:
- s->regs[addr] = value;
- break;
-
- case R_STAT:
- /* write one to clear bits */
- s->regs[addr] &= ~(value & (STAT_RX_EVT | STAT_TX_EVT));
- qemu_chr_fe_accept_input(&s->chr);
- break;
-
- default:
- error_report("milkymist_uart: write access to unknown register 0x"
- TARGET_FMT_plx, addr << 2);
- break;
- }
-
- uart_update_irq(s);
-}
-
-static const MemoryRegionOps uart_mmio_ops = {
- .read = uart_read,
- .write = uart_write,
- .valid = {
- .min_access_size = 4,
- .max_access_size = 4,
- },
- .endianness = DEVICE_NATIVE_ENDIAN,
-};
-
-static void uart_rx(void *opaque, const uint8_t *buf, int size)
-{
- MilkymistUartState *s = opaque;
-
- assert(!(s->regs[R_STAT] & STAT_RX_EVT));
-
- s->regs[R_STAT] |= STAT_RX_EVT;
- s->regs[R_RXTX] = *buf;
-
- uart_update_irq(s);
-}
-
-static int uart_can_rx(void *opaque)
-{
- MilkymistUartState *s = opaque;
-
- return !(s->regs[R_STAT] & STAT_RX_EVT);
-}
-
-static void uart_event(void *opaque, QEMUChrEvent event)
-{
-}
-
-static void milkymist_uart_reset(DeviceState *d)
-{
- MilkymistUartState *s = MILKYMIST_UART(d);
- int i;
-
- for (i = 0; i < R_MAX; i++) {
- s->regs[i] = 0;
- }
-
- /* THRE is always set */
- s->regs[R_STAT] = STAT_THRE;
-}
-
-static void milkymist_uart_realize(DeviceState *dev, Error **errp)
-{
- MilkymistUartState *s = MILKYMIST_UART(dev);
-
- qemu_chr_fe_set_handlers(&s->chr, uart_can_rx, uart_rx,
- uart_event, NULL, s, NULL, true);
-}
-
-static void milkymist_uart_init(Object *obj)
-{
- SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
- MilkymistUartState *s = MILKYMIST_UART(obj);
-
- sysbus_init_irq(sbd, &s->irq);
-
- memory_region_init_io(&s->regs_region, OBJECT(s), &uart_mmio_ops, s,
- "milkymist-uart", R_MAX * 4);
- sysbus_init_mmio(sbd, &s->regs_region);
-}
-
-static const VMStateDescription vmstate_milkymist_uart = {
- .name = "milkymist-uart",
- .version_id = 1,
- .minimum_version_id = 1,
- .fields = (VMStateField[]) {
- VMSTATE_UINT32_ARRAY(regs, MilkymistUartState, R_MAX),
- VMSTATE_END_OF_LIST()
- }
-};
-
-static Property milkymist_uart_properties[] = {
- DEFINE_PROP_CHR("chardev", MilkymistUartState, chr),
- DEFINE_PROP_END_OF_LIST(),
-};
-
-static void milkymist_uart_class_init(ObjectClass *klass, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(klass);
-
- dc->realize = milkymist_uart_realize;
- dc->reset = milkymist_uart_reset;
- dc->vmsd = &vmstate_milkymist_uart;
- device_class_set_props(dc, milkymist_uart_properties);
-}
-
-static const TypeInfo milkymist_uart_info = {
- .name = TYPE_MILKYMIST_UART,
- .parent = TYPE_SYS_BUS_DEVICE,
- .instance_size = sizeof(MilkymistUartState),
- .instance_init = milkymist_uart_init,
- .class_init = milkymist_uart_class_init,
-};
-
-static void milkymist_uart_register_types(void)
-{
- type_register_static(&milkymist_uart_info);
-}
-
-type_init(milkymist_uart_register_types)
diff --git a/hw/char/trace-events b/hw/char/trace-events
index c8dcade104..2e6e6b119a 100644
--- a/hw/char/trace-events
+++ b/hw/char/trace-events
@@ -35,23 +35,6 @@ grlib_apbuart_event(int event) "event:%d"
grlib_apbuart_writel_unknown(uint64_t addr, uint32_t value) "addr 0x%"PRIx64" value 0x%x"
grlib_apbuart_readl_unknown(uint64_t addr) "addr 0x%"PRIx64
-# lm32_juart.c
-lm32_juart_get_jtx(uint32_t value) "jtx 0x%08x"
-lm32_juart_set_jtx(uint32_t value) "jtx 0x%08x"
-lm32_juart_get_jrx(uint32_t value) "jrx 0x%08x"
-lm32_juart_set_jrx(uint32_t value) "jrx 0x%08x"
-
-# lm32_uart.c
-lm32_uart_memory_write(uint32_t addr, uint32_t value) "addr 0x%08x value 0x%08x"
-lm32_uart_memory_read(uint32_t addr, uint32_t value) "addr 0x%08x value 0x%08x"
-lm32_uart_irq_state(int level) "irq state %d"
-
-# milkymist-uart.c
-milkymist_uart_memory_read(uint32_t addr, uint32_t value) "addr 0x%08x value 0x%08x"
-milkymist_uart_memory_write(uint32_t addr, uint32_t value) "addr 0x%08x value 0x%08x"
-milkymist_uart_raise_irq(void) "Raise IRQ"
-milkymist_uart_lower_irq(void) "Lower IRQ"
-
# escc.c
escc_put_queue(char channel, int b) "channel %c put: 0x%02x"
escc_get_queue(char channel, int val) "channel %c get 0x%02x"
diff --git a/hw/core/numa.c b/hw/core/numa.c
index ac6bed5817..1058d3697b 100644
--- a/hw/core/numa.c
+++ b/hw/core/numa.c
@@ -802,9 +802,27 @@ void query_numa_node_mem(NumaNodeMem node_mem[], MachineState *ms)
}
}
+static int ram_block_notify_add_single(RAMBlock *rb, void *opaque)
+{
+ const ram_addr_t max_size = qemu_ram_get_max_length(rb);
+ const ram_addr_t size = qemu_ram_get_used_length(rb);
+ void *host = qemu_ram_get_host_addr(rb);
+ RAMBlockNotifier *notifier = opaque;
+
+ if (host) {
+ notifier->ram_block_added(notifier, host, size, max_size);
+ }
+ return 0;
+}
+
void ram_block_notifier_add(RAMBlockNotifier *n)
{
QLIST_INSERT_HEAD(&ram_list.ramblock_notifiers, n, next);
+
+ /* Notify about all existing ram blocks. */
+ if (n->ram_block_added) {
+ qemu_ram_foreach_block(ram_block_notify_add_single, n);
+ }
}
void ram_block_notifier_remove(RAMBlockNotifier *n)
@@ -812,20 +830,35 @@ void ram_block_notifier_remove(RAMBlockNotifier *n)
QLIST_REMOVE(n, next);
}
-void ram_block_notify_add(void *host, size_t size)
+void ram_block_notify_add(void *host, size_t size, size_t max_size)
+{
+ RAMBlockNotifier *notifier;
+
+ QLIST_FOREACH(notifier, &ram_list.ramblock_notifiers, next) {
+ if (notifier->ram_block_added) {
+ notifier->ram_block_added(notifier, host, size, max_size);
+ }
+ }
+}
+
+void ram_block_notify_remove(void *host, size_t size, size_t max_size)
{
RAMBlockNotifier *notifier;
QLIST_FOREACH(notifier, &ram_list.ramblock_notifiers, next) {
- notifier->ram_block_added(notifier, host, size);
+ if (notifier->ram_block_removed) {
+ notifier->ram_block_removed(notifier, host, size, max_size);
+ }
}
}
-void ram_block_notify_remove(void *host, size_t size)
+void ram_block_notify_resize(void *host, size_t old_size, size_t new_size)
{
RAMBlockNotifier *notifier;
QLIST_FOREACH(notifier, &ram_list.ramblock_notifiers, next) {
- notifier->ram_block_removed(notifier, host, size);
+ if (notifier->ram_block_resized) {
+ notifier->ram_block_resized(notifier, host, old_size, new_size);
+ }
}
}
diff --git a/hw/display/Kconfig b/hw/display/Kconfig
index ca46b5830e..a2306b67d8 100644
--- a/hw/display/Kconfig
+++ b/hw/display/Kconfig
@@ -72,10 +72,6 @@ config BLIZZARD
config FRAMEBUFFER
bool
-config MILKYMIST_TMU2
- bool
- depends on OPENGL && X11
-
config SM501
bool
select I2C
diff --git a/hw/display/meson.build b/hw/display/meson.build
index 612cd6582d..aaf797c5e9 100644
--- a/hw/display/meson.build
+++ b/hw/display/meson.build
@@ -48,7 +48,6 @@ endif
softmmu_ss.add(when: 'CONFIG_DPCD', if_true: files('dpcd.c'))
softmmu_ss.add(when: 'CONFIG_XLNX_ZYNQMP_ARM', if_true: files('xlnx_dp.c'))
-softmmu_ss.add(when: 'CONFIG_MILKYMIST', if_true: files('milkymist-vgafb.c'))
softmmu_ss.add(when: 'CONFIG_ARTIST', if_true: files('artist.c'))
softmmu_ss.add(when: [pixman, 'CONFIG_ATI_VGA'], if_true: files('ati.c', 'ati_2d.c', 'ati_dbg.c'))
@@ -94,7 +93,6 @@ if config_all_devices.has_key('CONFIG_VIRTIO_VGA')
hw_display_modules += {'virtio-vga-gl': virtio_vga_gl_ss}
endif
-specific_ss.add(when: [x11, opengl, 'CONFIG_MILKYMIST_TMU2'], if_true: files('milkymist-tmu2.c'))
specific_ss.add(when: 'CONFIG_OMAP', if_true: files('omap_lcdc.c'))
modules += { 'hw-display': hw_display_modules }
diff --git a/hw/display/milkymist-tmu2.c b/hw/display/milkymist-tmu2.c
deleted file mode 100644
index 02a28c807b..0000000000
--- a/hw/display/milkymist-tmu2.c
+++ /dev/null
@@ -1,551 +0,0 @@
-/*
- * QEMU model of the Milkymist texture mapping unit.
- *
- * Copyright (c) 2010 Michael Walle <michael@walle.cc>
- * Copyright (c) 2010 Sebastien Bourdeauducq
- * <sebastien.bourdeauducq@lekernel.net>
- *
- * 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.1 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/>.
- *
- *
- * Specification available at:
- * http://milkymist.walle.cc/socdoc/tmu2.pdf
- *
- */
-
-#include "qemu/osdep.h"
-#include "hw/irq.h"
-#include "hw/sysbus.h"
-#include "migration/vmstate.h"
-#include "trace.h"
-#include "qapi/error.h"
-#include "qemu/error-report.h"
-#include "qemu/module.h"
-#include "qapi/error.h"
-#include "hw/display/milkymist_tmu2.h"
-
-#include <X11/Xlib.h>
-#include <epoxy/gl.h>
-#include <epoxy/glx.h>
-#include "qom/object.h"
-
-enum {
- R_CTL = 0,
- R_HMESHLAST,
- R_VMESHLAST,
- R_BRIGHTNESS,
- R_CHROMAKEY,
- R_VERTICESADDR,
- R_TEXFBUF,
- R_TEXHRES,
- R_TEXVRES,
- R_TEXHMASK,
- R_TEXVMASK,
- R_DSTFBUF,
- R_DSTHRES,
- R_DSTVRES,
- R_DSTHOFFSET,
- R_DSTVOFFSET,
- R_DSTSQUAREW,
- R_DSTSQUAREH,
- R_ALPHA,
- R_MAX
-};
-
-enum {
- CTL_START_BUSY = (1<<0),
- CTL_CHROMAKEY = (1<<1),
-};
-
-enum {
- MAX_BRIGHTNESS = 63,
- MAX_ALPHA = 63,
-};
-
-enum {
- MESH_MAXSIZE = 128,
-};
-
-struct vertex {
- int x;
- int y;
-} QEMU_PACKED;
-
-#define TYPE_MILKYMIST_TMU2 "milkymist-tmu2"
-OBJECT_DECLARE_SIMPLE_TYPE(MilkymistTMU2State, MILKYMIST_TMU2)
-
-struct MilkymistTMU2State {
- SysBusDevice parent_obj;
-
- MemoryRegion regs_region;
- Chardev *chr;
- qemu_irq irq;
-
- uint32_t regs[R_MAX];
-
- Display *dpy;
- GLXFBConfig glx_fb_config;
- GLXContext glx_context;
-};
-
-static const int glx_fbconfig_attr[] = {
- GLX_GREEN_SIZE, 5,
- GLX_GREEN_SIZE, 6,
- GLX_BLUE_SIZE, 5,
- None
-};
-
-static int tmu2_glx_init(MilkymistTMU2State *s)
-{
- GLXFBConfig *configs;
- int nelements;
-
- s->dpy = XOpenDisplay(NULL); /* FIXME: call XCloseDisplay() */
- if (s->dpy == NULL) {
- return 1;
- }
-
- configs = glXChooseFBConfig(s->dpy, 0, glx_fbconfig_attr, &nelements);
- if (configs == NULL) {
- return 1;
- }
-
- s->glx_fb_config = *configs;
- XFree(configs);
-
- /* FIXME: call glXDestroyContext() */
- s->glx_context = glXCreateNewContext(s->dpy, s->glx_fb_config,
- GLX_RGBA_TYPE, NULL, 1);
- if (s->glx_context == NULL) {
- return 1;
- }
-
- return 0;
-}
-
-static void tmu2_gl_map(struct vertex *mesh, int texhres, int texvres,
- int hmeshlast, int vmeshlast, int ho, int vo, int sw, int sh)
-{
- int x, y;
- int x0, y0, x1, y1;
- int u0, v0, u1, v1, u2, v2, u3, v3;
- double xscale = 1.0 / ((double)(64 * texhres));
- double yscale = 1.0 / ((double)(64 * texvres));
-
- glLoadIdentity();
- glTranslatef(ho, vo, 0);
- glEnable(GL_TEXTURE_2D);
- glBegin(GL_QUADS);
-
- for (y = 0; y < vmeshlast; y++) {
- y0 = y * sh;
- y1 = y0 + sh;
- for (x = 0; x < hmeshlast; x++) {
- x0 = x * sw;
- x1 = x0 + sw;
-
- u0 = be32_to_cpu(mesh[MESH_MAXSIZE * y + x].x);
- v0 = be32_to_cpu(mesh[MESH_MAXSIZE * y + x].y);
- u1 = be32_to_cpu(mesh[MESH_MAXSIZE * y + x + 1].x);
- v1 = be32_to_cpu(mesh[MESH_MAXSIZE * y + x + 1].y);
- u2 = be32_to_cpu(mesh[MESH_MAXSIZE * (y + 1) + x + 1].x);
- v2 = be32_to_cpu(mesh[MESH_MAXSIZE * (y + 1) + x + 1].y);
- u3 = be32_to_cpu(mesh[MESH_MAXSIZE * (y + 1) + x].x);
- v3 = be32_to_cpu(mesh[MESH_MAXSIZE * (y + 1) + x].y);
-
- glTexCoord2d(((double)u0) * xscale, ((double)v0) * yscale);
- glVertex3i(x0, y0, 0);
- glTexCoord2d(((double)u1) * xscale, ((double)v1) * yscale);
- glVertex3i(x1, y0, 0);
- glTexCoord2d(((double)u2) * xscale, ((double)v2) * yscale);
- glVertex3i(x1, y1, 0);
- glTexCoord2d(((double)u3) * xscale, ((double)v3) * yscale);
- glVertex3i(x0, y1, 0);
- }
- }
-
- glEnd();
-}
-
-static void tmu2_start(MilkymistTMU2State *s)
-{
- int pbuffer_attrib[6] = {
- GLX_PBUFFER_WIDTH,
- 0,
- GLX_PBUFFER_HEIGHT,
- 0,
- GLX_PRESERVED_CONTENTS,
- True
- };
-
- GLXPbuffer pbuffer;
- GLuint texture;
- void *fb;
- hwaddr fb_len;
- void *mesh;
- hwaddr mesh_len;
- float m;
-
- trace_milkymist_tmu2_start();
-
- /* Create and set up a suitable OpenGL context */
- pbuffer_attrib[1] = s->regs[R_DSTHRES];
- pbuffer_attrib[3] = s->regs[R_DSTVRES];
- pbuffer = glXCreatePbuffer(s->dpy, s->glx_fb_config, pbuffer_attrib);
- glXMakeContextCurrent(s->dpy, pbuffer, pbuffer, s->glx_context);
-
- /* Fixup endianness. TODO: would it work on BE hosts? */
- glPixelStorei(GL_UNPACK_SWAP_BYTES, 1);
- glPixelStorei(GL_PACK_SWAP_BYTES, 1);
-
- /* Row alignment */
- glPixelStorei(GL_UNPACK_ALIGNMENT, 2);
- glPixelStorei(GL_PACK_ALIGNMENT, 2);
-
- /* Read the QEMU source framebuffer into an OpenGL texture */
- glGenTextures(1, &texture);
- glBindTexture(GL_TEXTURE_2D, texture);
- fb_len = 2ULL * s->regs[R_TEXHRES] * s->regs[R_TEXVRES];
- fb = cpu_physical_memory_map(s->regs[R_TEXFBUF], &fb_len, false);
- if (fb == NULL) {
- glDeleteTextures(1, &texture);
- glXMakeContextCurrent(s->dpy, None, None, NULL);
- glXDestroyPbuffer(s->dpy, pbuffer);
- return;
- }
- glTexImage2D(GL_TEXTURE_2D, 0, 3, s->regs[R_TEXHRES], s->regs[R_TEXVRES],
- 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, fb);
- cpu_physical_memory_unmap(fb, fb_len, 0, fb_len);
-
- /* Set up texturing options */
- /* WARNING:
- * Many cases of TMU2 masking are not supported by OpenGL.
- * We only implement the most common ones:
- * - full bilinear filtering vs. nearest texel
- * - texture clamping vs. texture wrapping
- */
- if ((s->regs[R_TEXHMASK] & 0x3f) > 0x20) {
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- } else {
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- }
- if ((s->regs[R_TEXHMASK] >> 6) & s->regs[R_TEXHRES]) {
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
- } else {
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
- }
- if ((s->regs[R_TEXVMASK] >> 6) & s->regs[R_TEXVRES]) {
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
- } else {
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
- }
-
- /* Translucency and decay */
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- m = (float)(s->regs[R_BRIGHTNESS] + 1) / 64.0f;
- glColor4f(m, m, m, (float)(s->regs[R_ALPHA] + 1) / 64.0f);
-
- /* Read the QEMU dest. framebuffer into the OpenGL framebuffer */
- fb_len = 2ULL * s->regs[R_DSTHRES] * s->regs[R_DSTVRES];
- fb = cpu_physical_memory_map(s->regs[R_DSTFBUF], &fb_len, false);
- if (fb == NULL) {
- glDeleteTextures(1, &texture);
- glXMakeContextCurrent(s->dpy, None, None, NULL);
- glXDestroyPbuffer(s->dpy, pbuffer);
- return;
- }
-
- glDrawPixels(s->regs[R_DSTHRES], s->regs[R_DSTVRES], GL_RGB,
- GL_UNSIGNED_SHORT_5_6_5, fb);
- cpu_physical_memory_unmap(fb, fb_len, 0, fb_len);
- glViewport(0, 0, s->regs[R_DSTHRES], s->regs[R_DSTVRES]);
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- glOrtho(0.0, s->regs[R_DSTHRES], 0.0, s->regs[R_DSTVRES], -1.0, 1.0);
- glMatrixMode(GL_MODELVIEW);
-
- /* Map the texture */
- mesh_len = MESH_MAXSIZE*MESH_MAXSIZE*sizeof(struct vertex);
- mesh = cpu_physical_memory_map(s->regs[R_VERTICESADDR], &mesh_len, false);
- if (mesh == NULL) {
- glDeleteTextures(1, &texture);
- glXMakeContextCurrent(s->dpy, None, None, NULL);
- glXDestroyPbuffer(s->dpy, pbuffer);
- return;
- }
-
- tmu2_gl_map((struct vertex *)mesh,
- s->regs[R_TEXHRES], s->regs[R_TEXVRES],
- s->regs[R_HMESHLAST], s->regs[R_VMESHLAST],
- s->regs[R_DSTHOFFSET], s->regs[R_DSTVOFFSET],
- s->regs[R_DSTSQUAREW], s->regs[R_DSTSQUAREH]);
- cpu_physical_memory_unmap(mesh, mesh_len, 0, mesh_len);
-
- /* Write back the OpenGL framebuffer to the QEMU framebuffer */
- fb_len = 2ULL * s->regs[R_DSTHRES] * s->regs[R_DSTVRES];
- fb = cpu_physical_memory_map(s->regs[R_DSTFBUF], &fb_len, true);
- if (fb == NULL) {
- glDeleteTextures(1, &texture);
- glXMakeContextCurrent(s->dpy, None, None, NULL);
- glXDestroyPbuffer(s->dpy, pbuffer);
- return;
- }
-
- glReadPixels(0, 0, s->regs[R_DSTHRES], s->regs[R_DSTVRES], GL_RGB,
- GL_UNSIGNED_SHORT_5_6_5, fb);
- cpu_physical_memory_unmap(fb, fb_len, 1, fb_len);
-
- /* Free OpenGL allocs */
- glDeleteTextures(1, &texture);
- glXMakeContextCurrent(s->dpy, None, None, NULL);
- glXDestroyPbuffer(s->dpy, pbuffer);
-
- s->regs[R_CTL] &= ~CTL_START_BUSY;
-
- trace_milkymist_tmu2_pulse_irq();
- qemu_irq_pulse(s->irq);
-}
-
-static uint64_t tmu2_read(void *opaque, hwaddr addr,
- unsigned size)
-{
- MilkymistTMU2State *s = opaque;
- uint32_t r = 0;
-
- addr >>= 2;
- switch (addr) {
- case R_CTL:
- case R_HMESHLAST:
- case R_VMESHLAST:
- case R_BRIGHTNESS:
- case R_CHROMAKEY:
- case R_VERTICESADDR:
- case R_TEXFBUF:
- case R_TEXHRES:
- case R_TEXVRES:
- case R_TEXHMASK:
- case R_TEXVMASK:
- case R_DSTFBUF:
- case R_DSTHRES:
- case R_DSTVRES:
- case R_DSTHOFFSET:
- case R_DSTVOFFSET:
- case R_DSTSQUAREW:
- case R_DSTSQUAREH:
- case R_ALPHA:
- r = s->regs[addr];
- break;
-
- default:
- error_report("milkymist_tmu2: read access to unknown register 0x"
- TARGET_FMT_plx, addr << 2);
- break;
- }
-
- trace_milkymist_tmu2_memory_read(addr << 2, r);
-
- return r;
-}
-
-static void tmu2_check_registers(MilkymistTMU2State *s)
-{
- if (s->regs[R_BRIGHTNESS] > MAX_BRIGHTNESS) {
- error_report("milkymist_tmu2: max brightness is %d", MAX_BRIGHTNESS);
- }
-
- if (s->regs[R_ALPHA] > MAX_ALPHA) {
- error_report("milkymist_tmu2: max alpha is %d", MAX_ALPHA);
- }
-
- if (s->regs[R_VERTICESADDR] & 0x07) {
- error_report("milkymist_tmu2: vertex mesh address has to be 64-bit "
- "aligned");
- }
-
- if (s->regs[R_TEXFBUF] & 0x01) {
- error_report("milkymist_tmu2: texture buffer address has to be "
- "16-bit aligned");
- }
-}
-
-static void tmu2_write(void *opaque, hwaddr addr, uint64_t value,
- unsigned size)
-{
- MilkymistTMU2State *s = opaque;
-
- trace_milkymist_tmu2_memory_write(addr, value);
-
- addr >>= 2;
- switch (addr) {
- case R_CTL:
- s->regs[addr] = value;
- if (value & CTL_START_BUSY) {
- tmu2_start(s);
- }
- break;
- case R_BRIGHTNESS:
- case R_HMESHLAST:
- case R_VMESHLAST:
- case R_CHROMAKEY:
- case R_VERTICESADDR:
- case R_TEXFBUF:
- case R_TEXHRES:
- case R_TEXVRES:
- case R_TEXHMASK:
- case R_TEXVMASK:
- case R_DSTFBUF:
- case R_DSTHRES:
- case R_DSTVRES:
- case R_DSTHOFFSET:
- case R_DSTVOFFSET:
- case R_DSTSQUAREW:
- case R_DSTSQUAREH:
- case R_ALPHA:
- s->regs[addr] = value;
- break;
-
- default:
- error_report("milkymist_tmu2: write access to unknown register 0x"
- TARGET_FMT_plx, addr << 2);
- break;
- }
-
- tmu2_check_registers(s);
-}
-
-static const MemoryRegionOps tmu2_mmio_ops = {
- .read = tmu2_read,
- .write = tmu2_write,
- .valid = {
- .min_access_size = 4,
- .max_access_size = 4,
- },
- .endianness = DEVICE_NATIVE_ENDIAN,
-};
-
-static void milkymist_tmu2_reset(DeviceState *d)
-{
- MilkymistTMU2State *s = MILKYMIST_TMU2(d);
- int i;
-
- for (i = 0; i < R_MAX; i++) {
- s->regs[i] = 0;
- }
-}
-
-static void milkymist_tmu2_init(Object *obj)
-{
- MilkymistTMU2State *s = MILKYMIST_TMU2(obj);
- SysBusDevice *dev = SYS_BUS_DEVICE(obj);
-
- sysbus_init_irq(dev, &s->irq);
-
- memory_region_init_io(&s->regs_region, obj, &tmu2_mmio_ops, s,
- "milkymist-tmu2", R_MAX * 4);
- sysbus_init_mmio(dev, &s->regs_region);
-}
-
-static void milkymist_tmu2_realize(DeviceState *dev, Error **errp)
-{
- MilkymistTMU2State *s = MILKYMIST_TMU2(dev);
-
- if (tmu2_glx_init(s)) {
- error_setg(errp, "tmu2_glx_init failed");
- }
-}
-
-static const VMStateDescription vmstate_milkymist_tmu2 = {
- .name = "milkymist-tmu2",
- .version_id = 1,
- .minimum_version_id = 1,
- .fields = (VMStateField[]) {
- VMSTATE_UINT32_ARRAY(regs, MilkymistTMU2State, R_MAX),
- VMSTATE_END_OF_LIST()
- }
-};
-
-static void milkymist_tmu2_class_init(ObjectClass *klass, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(klass);
-
- dc->realize = milkymist_tmu2_realize;
- dc->reset = milkymist_tmu2_reset;
- dc->vmsd = &vmstate_milkymist_tmu2;
-}
-
-static const TypeInfo milkymist_tmu2_info = {
- .name = TYPE_MILKYMIST_TMU2,
- .parent = TYPE_SYS_BUS_DEVICE,
- .instance_size = sizeof(MilkymistTMU2State),
- .instance_init = milkymist_tmu2_init,
- .class_init = milkymist_tmu2_class_init,
-};
-
-static void milkymist_tmu2_register_types(void)
-{
- type_register_static(&milkymist_tmu2_info);
-}
-
-type_init(milkymist_tmu2_register_types)
-
-DeviceState *milkymist_tmu2_create(hwaddr base, qemu_irq irq)
-{
- DeviceState *dev;
- Display *d;
- GLXFBConfig *configs;
- int nelements;
- int ver_major, ver_minor;
-
- /* check that GLX will work */
- d = XOpenDisplay(NULL);
- if (d == NULL) {
- return NULL;
- }
-
- if (!glXQueryVersion(d, &ver_major, &ver_minor)) {
- /*
- * Yeah, sometimes getting the GLX version can fail.
- * Isn't X beautiful?
- */
- XCloseDisplay(d);
- return NULL;
- }
-
- if ((ver_major < 1) || ((ver_major == 1) && (ver_minor < 3))) {
- printf("Your GLX version is %d.%d,"
- "but TMU emulation needs at least 1.3. TMU disabled.\n",
- ver_major, ver_minor);
- XCloseDisplay(d);
- return NULL;
- }
-
- configs = glXChooseFBConfig(d, 0, glx_fbconfig_attr, &nelements);
- if (configs == NULL) {
- XCloseDisplay(d);
- return NULL;
- }
-
- XFree(configs);
- XCloseDisplay(d);
-
- dev = qdev_new(TYPE_MILKYMIST_TMU2);
- sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
- sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, base);
- sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, irq);
-
- return dev;
-}
diff --git a/hw/display/milkymist-vgafb.c b/hw/display/milkymist-vgafb.c
deleted file mode 100644
index e2c587e2df..0000000000
--- a/hw/display/milkymist-vgafb.c
+++ /dev/null
@@ -1,360 +0,0 @@
-
-/*
- * QEMU model of the Milkymist VGA framebuffer.
- *
- * Copyright (c) 2010-2012 Michael Walle <michael@walle.cc>
- *
- * 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.1 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/>.
- *
- *
- * Specification available at:
- * http://milkymist.walle.cc/socdoc/vgafb.pdf
- */
-
-#include "qemu/osdep.h"
-#include "hw/hw.h"
-#include "hw/qdev-properties.h"
-#include "hw/sysbus.h"
-#include "trace.h"
-#include "ui/console.h"
-#include "framebuffer.h"
-#include "ui/pixel_ops.h"
-#include "qemu/error-report.h"
-#include "qemu/module.h"
-#include "qom/object.h"
-
-#define BITS 8
-#include "migration/vmstate.h"
-#include "milkymist-vgafb_template.h"
-#define BITS 15
-#include "milkymist-vgafb_template.h"
-#define BITS 16
-#include "milkymist-vgafb_template.h"
-#define BITS 24
-#include "milkymist-vgafb_template.h"
-#define BITS 32
-#include "milkymist-vgafb_template.h"
-
-enum {
- R_CTRL = 0,
- R_HRES,
- R_HSYNC_START,
- R_HSYNC_END,
- R_HSCAN,
- R_VRES,
- R_VSYNC_START,
- R_VSYNC_END,
- R_VSCAN,
- R_BASEADDRESS,
- R_BASEADDRESS_ACT,
- R_BURST_COUNT,
- R_DDC,
- R_SOURCE_CLOCK,
- R_MAX
-};
-
-enum {
- CTRL_RESET = (1<<0),
-};
-
-#define TYPE_MILKYMIST_VGAFB "milkymist-vgafb"
-OBJECT_DECLARE_SIMPLE_TYPE(MilkymistVgafbState, MILKYMIST_VGAFB)
-
-struct MilkymistVgafbState {
- SysBusDevice parent_obj;
-
- MemoryRegion regs_region;
- MemoryRegionSection fbsection;
- QemuConsole *con;
-
- int invalidate;
- uint32_t fb_offset;
- uint32_t fb_mask;
-
- uint32_t regs[R_MAX];
-};
-
-static int vgafb_enabled(MilkymistVgafbState *s)
-{
- return !(s->regs[R_CTRL] & CTRL_RESET);
-}
-
-static void vgafb_update_display(void *opaque)
-{
- MilkymistVgafbState *s = opaque;
- SysBusDevice *sbd;
- DisplaySurface *surface = qemu_console_surface(s->con);
- int src_width;
- int first = 0;
- int last = 0;
- drawfn fn;
-
- if (!vgafb_enabled(s)) {
- return;
- }
-
- sbd = SYS_BUS_DEVICE(s);
- int dest_width = s->regs[R_HRES];
-
- switch (surface_bits_per_pixel(surface)) {
- case 0:
- return;
- case 8:
- fn = draw_line_8;
- break;
- case 15:
- fn = draw_line_15;
- dest_width *= 2;
- break;
- case 16:
- fn = draw_line_16;
- dest_width *= 2;
- break;
- case 24:
- fn = draw_line_24;
- dest_width *= 3;
- break;
- case 32:
- fn = draw_line_32;
- dest_width *= 4;
- break;
- default:
- hw_error("milkymist_vgafb: bad color depth\n");
- break;
- }
-
- src_width = s->regs[R_HRES] * 2;
- if (s->invalidate) {
- framebuffer_update_memory_section(&s->fbsection,
- sysbus_address_space(sbd),
- s->regs[R_BASEADDRESS] + s->fb_offset,
- s->regs[R_VRES], src_width);
- }
-
- framebuffer_update_display(surface, &s->fbsection,
- s->regs[R_HRES],
- s->regs[R_VRES],
- src_width,
- dest_width,
- 0,
- s->invalidate,
- fn,
- NULL,
- &first, &last);
-
- if (first >= 0) {
- dpy_gfx_update(s->con, 0, first, s->regs[R_HRES], last - first + 1);
- }
- s->invalidate = 0;
-}
-
-static void vgafb_invalidate_display(void *opaque)
-{
- MilkymistVgafbState *s = opaque;
- s->invalidate = 1;
-}
-
-static void vgafb_resize(MilkymistVgafbState *s)
-{
- if (!vgafb_enabled(s)) {
- return;
- }
-
- qemu_console_resize(s->con, s->regs[R_HRES], s->regs[R_VRES]);
- s->invalidate = 1;
-}
-
-static uint64_t vgafb_read(void *opaque, hwaddr addr,
- unsigned size)
-{
- MilkymistVgafbState *s = opaque;
- uint32_t r = 0;
-
- addr >>= 2;
- switch (addr) {
- case R_CTRL:
- case R_HRES:
- case R_HSYNC_START:
- case R_HSYNC_END:
- case R_HSCAN:
- case R_VRES:
- case R_VSYNC_START:
- case R_VSYNC_END:
- case R_VSCAN:
- case R_BASEADDRESS:
- case R_BURST_COUNT:
- case R_DDC:
- case R_SOURCE_CLOCK:
- r = s->regs[addr];
- break;
- case R_BASEADDRESS_ACT:
- r = s->regs[R_BASEADDRESS];
- break;
-
- default:
- error_report("milkymist_vgafb: read access to unknown register 0x"
- TARGET_FMT_plx, addr << 2);
- break;
- }
-
- trace_milkymist_vgafb_memory_read(addr << 2, r);
-
- return r;
-}
-
-static void vgafb_write(void *opaque, hwaddr addr, uint64_t value,
- unsigned size)
-{
- MilkymistVgafbState *s = opaque;
-
- trace_milkymist_vgafb_memory_write(addr, value);
-
- addr >>= 2;
- switch (addr) {
- case R_CTRL:
- s->regs[addr] = value;
- vgafb_resize(s);
- break;
- case R_HSYNC_START:
- case R_HSYNC_END:
- case R_HSCAN:
- case R_VSYNC_START:
- case R_VSYNC_END:
- case R_VSCAN:
- case R_BURST_COUNT:
- case R_DDC:
- case R_SOURCE_CLOCK:
- s->regs[addr] = value;
- break;
- case R_BASEADDRESS:
- if (value & 0x1f) {
- error_report("milkymist_vgafb: framebuffer base address have to "
- "be 32 byte aligned");
- break;
- }
- s->regs[addr] = value & s->fb_mask;
- s->invalidate = 1;
- break;
- case R_HRES:
- case R_VRES:
- s->regs[addr] = value;
- vgafb_resize(s);
- break;
- case R_BASEADDRESS_ACT:
- error_report("milkymist_vgafb: write to read-only register 0x"
- TARGET_FMT_plx, addr << 2);
- break;
-
- default:
- error_report("milkymist_vgafb: write access to unknown register 0x"
- TARGET_FMT_plx, addr << 2);
- break;
- }
-}
-
-static const MemoryRegionOps vgafb_mmio_ops = {
- .read = vgafb_read,
- .write = vgafb_write,
- .valid = {
- .min_access_size = 4,
- .max_access_size = 4,
- },
- .endianness = DEVICE_NATIVE_ENDIAN,
-};
-
-static void milkymist_vgafb_reset(DeviceState *d)
-{
- MilkymistVgafbState *s = MILKYMIST_VGAFB(d);
- int i;
-
- for (i = 0; i < R_MAX; i++) {
- s->regs[i] = 0;
- }
-
- /* defaults */
- s->regs[R_CTRL] = CTRL_RESET;
- s->regs[R_HRES] = 640;
- s->regs[R_VRES] = 480;
- s->regs[R_BASEADDRESS] = 0;
-}
-
-static const GraphicHwOps vgafb_ops = {
- .invalidate = vgafb_invalidate_display,
- .gfx_update = vgafb_update_display,
-};
-
-static void milkymist_vgafb_init(Object *obj)
-{
- MilkymistVgafbState *s = MILKYMIST_VGAFB(obj);
- SysBusDevice *dev = SYS_BUS_DEVICE(obj);
-
- memory_region_init_io(&s->regs_region, OBJECT(s), &vgafb_mmio_ops, s,
- "milkymist-vgafb", R_MAX * 4);
- sysbus_init_mmio(dev, &s->regs_region);
-}
-
-static void milkymist_vgafb_realize(DeviceState *dev, Error **errp)
-{
- MilkymistVgafbState *s = MILKYMIST_VGAFB(dev);
-
- s->con = graphic_console_init(dev, 0, &vgafb_ops, s);
-}
-
-static int vgafb_post_load(void *opaque, int version_id)
-{
- vgafb_invalidate_display(opaque);
- return 0;
-}
-
-static const VMStateDescription vmstate_milkymist_vgafb = {
- .name = "milkymist-vgafb",
- .version_id = 1,
- .minimum_version_id = 1,
- .post_load = vgafb_post_load,
- .fields = (VMStateField[]) {
- VMSTATE_UINT32_ARRAY(regs, MilkymistVgafbState, R_MAX),
- VMSTATE_END_OF_LIST()
- }
-};
-
-static Property milkymist_vgafb_properties[] = {
- DEFINE_PROP_UINT32("fb_offset", MilkymistVgafbState, fb_offset, 0x0),
- DEFINE_PROP_UINT32("fb_mask", MilkymistVgafbState, fb_mask, 0xffffffff),
- DEFINE_PROP_END_OF_LIST(),
-};
-
-static void milkymist_vgafb_class_init(ObjectClass *klass, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(klass);
-
- dc->reset = milkymist_vgafb_reset;
- dc->vmsd = &vmstate_milkymist_vgafb;
- device_class_set_props(dc, milkymist_vgafb_properties);
- dc->realize = milkymist_vgafb_realize;
-}
-
-static const TypeInfo milkymist_vgafb_info = {
- .name = TYPE_MILKYMIST_VGAFB,
- .parent = TYPE_SYS_BUS_DEVICE,
- .instance_size = sizeof(MilkymistVgafbState),
- .instance_init = milkymist_vgafb_init,
- .class_init = milkymist_vgafb_class_init,
-};
-
-static void milkymist_vgafb_register_types(void)
-{
- type_register_static(&milkymist_vgafb_info);
-}
-
-type_init(milkymist_vgafb_register_types)
diff --git a/hw/display/milkymist-vgafb_template.h b/hw/display/milkymist-vgafb_template.h
deleted file mode 100644
index 96137f9709..0000000000
--- a/hw/display/milkymist-vgafb_template.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * QEMU model of the Milkymist VGA framebuffer.
- *
- * Copyright (c) 2010 Michael Walle <michael@walle.cc>
- *
- * 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.1 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/>.
- *
- */
-
-#if BITS == 8
-#define COPY_PIXEL(to, r, g, b) \
- do { \
- *to = rgb_to_pixel8(r, g, b); \
- to += 1; \
- } while (0)
-#elif BITS == 15
-#define COPY_PIXEL(to, r, g, b) \
- do { \
- *(uint16_t *)to = rgb_to_pixel15(r, g, b); \
- to += 2; \
- } while (0)
-#elif BITS == 16
-#define COPY_PIXEL(to, r, g, b) \
- do { \
- *(uint16_t *)to = rgb_to_pixel16(r, g, b); \
- to += 2; \
- } while (0)
-#elif BITS == 24
-#define COPY_PIXEL(to, r, g, b) \
- do { \
- uint32_t tmp = rgb_to_pixel24(r, g, b); \
- *(to++) = tmp & 0xff; \
- *(to++) = (tmp >> 8) & 0xff; \
- *(to++) = (tmp >> 16) & 0xff; \
- } while (0)
-#elif BITS == 32
-#define COPY_PIXEL(to, r, g, b) \
- do { \
- *(uint32_t *)to = rgb_to_pixel32(r, g, b); \
- to += 4; \
- } while (0)
-#else
-#error unknown bit depth
-#endif
-
-static void glue(draw_line_, BITS)(void *opaque, uint8_t *d, const uint8_t *s,
- int width, int deststep)
-{
- uint16_t rgb565;
- uint8_t r, g, b;
-
- while (width--) {
- rgb565 = lduw_be_p(s);
- r = ((rgb565 >> 11) & 0x1f) << 3;
- g = ((rgb565 >> 5) & 0x3f) << 2;
- b = ((rgb565 >> 0) & 0x1f) << 3;
- COPY_PIXEL(d, r, g, b);
- s += 2;
- }
-}
-
-#undef BITS
-#undef COPY_PIXEL
diff --git a/hw/display/trace-events b/hw/display/trace-events
index 957b8ba994..9fccca18a1 100644
--- a/hw/display/trace-events
+++ b/hw/display/trace-events
@@ -13,16 +13,6 @@ xenfb_input_connected(void *xendev, int abs_pointer_wanted) "%p abs %d"
g364fb_read(uint64_t addr, uint32_t val) "read addr=0x%"PRIx64": 0x%x"
g364fb_write(uint64_t addr, uint32_t new) "write addr=0x%"PRIx64": 0x%x"
-# milkymist-tmu2.c
-milkymist_tmu2_memory_read(uint32_t addr, uint32_t value) "addr 0x%08x value 0x%08x"
-milkymist_tmu2_memory_write(uint32_t addr, uint32_t value) "addr 0x%08x value 0x%08x"
-milkymist_tmu2_start(void) "Start TMU"
-milkymist_tmu2_pulse_irq(void) "Pulse IRQ"
-
-# milkymist-vgafb.c
-milkymist_vgafb_memory_read(uint32_t addr, uint32_t value) "addr 0x%08x value 0x%08x"
-milkymist_vgafb_memory_write(uint32_t addr, uint32_t value) "addr 0x%08x value 0x%08x"
-
# vmware_vga.c
vmware_value_read(uint32_t index, uint32_t value) "index %d, value 0x%x"
vmware_value_write(uint32_t index, uint32_t value) "index %d, value 0x%x"
diff --git a/hw/dma/meson.build b/hw/dma/meson.build
index 5c78a4e05f..f3f0661bc3 100644
--- a/hw/dma/meson.build
+++ b/hw/dma/meson.build
@@ -1,4 +1,3 @@
-softmmu_ss.add(when: 'CONFIG_PUV3', if_true: files('puv3_dma.c'))
softmmu_ss.add(when: 'CONFIG_RC4030', if_true: files('rc4030.c'))
softmmu_ss.add(when: 'CONFIG_PL080', if_true: files('pl080.c'))
softmmu_ss.add(when: 'CONFIG_PL330', if_true: files('pl330.c'))
diff --git a/hw/dma/puv3_dma.c b/hw/dma/puv3_dma.c
deleted file mode 100644
index cca1e9ec21..0000000000
--- a/hw/dma/puv3_dma.c
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * DMA device simulation in PKUnity SoC
- *
- * Copyright (C) 2010-2012 Guan Xuetao
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation, or any later version.
- * See the COPYING file in the top-level directory.
- */
-
-#include "qemu/osdep.h"
-#include "hw/sysbus.h"
-#include "qom/object.h"
-
-#undef DEBUG_PUV3
-#include "hw/unicore32/puv3.h"
-#include "qemu/module.h"
-#include "qemu/log.h"
-
-#define PUV3_DMA_CH_NR (6)
-#define PUV3_DMA_CH_MASK (0xff)
-#define PUV3_DMA_CH(offset) ((offset) >> 8)
-
-#define TYPE_PUV3_DMA "puv3_dma"
-OBJECT_DECLARE_SIMPLE_TYPE(PUV3DMAState, PUV3_DMA)
-
-struct PUV3DMAState {
- SysBusDevice parent_obj;
-
- MemoryRegion iomem;
- uint32_t reg_CFG[PUV3_DMA_CH_NR];
-};
-
-static uint64_t puv3_dma_read(void *opaque, hwaddr offset,
- unsigned size)
-{
- PUV3DMAState *s = opaque;
- uint32_t ret = 0;
-
- assert(PUV3_DMA_CH(offset) < PUV3_DMA_CH_NR);
-
- switch (offset & PUV3_DMA_CH_MASK) {
- case 0x10:
- ret = s->reg_CFG[PUV3_DMA_CH(offset)];
- break;
- default:
- qemu_log_mask(LOG_GUEST_ERROR,
- "%s: Bad read offset 0x%"HWADDR_PRIx"\n",
- __func__, offset);
- }
- DPRINTF("offset 0x%x, value 0x%x\n", offset, ret);
-
- return ret;
-}
-
-static void puv3_dma_write(void *opaque, hwaddr offset,
- uint64_t value, unsigned size)
-{
- PUV3DMAState *s = opaque;
-
- assert(PUV3_DMA_CH(offset) < PUV3_DMA_CH_NR);
-
- switch (offset & PUV3_DMA_CH_MASK) {
- case 0x10:
- s->reg_CFG[PUV3_DMA_CH(offset)] = value;
- break;
- default:
- qemu_log_mask(LOG_GUEST_ERROR,
- "%s: Bad write offset 0x%"HWADDR_PRIx"\n",
- __func__, offset);
- }
- DPRINTF("offset 0x%x, value 0x%x\n", offset, value);
-}
-
-static const MemoryRegionOps puv3_dma_ops = {
- .read = puv3_dma_read,
- .write = puv3_dma_write,
- .impl = {
- .min_access_size = 4,
- .max_access_size = 4,
- },
- .endianness = DEVICE_NATIVE_ENDIAN,
-};
-
-static void puv3_dma_realize(DeviceState *dev, Error **errp)
-{
- PUV3DMAState *s = PUV3_DMA(dev);
- int i;
-
- for (i = 0; i < PUV3_DMA_CH_NR; i++) {
- s->reg_CFG[i] = 0x0;
- }
-
- memory_region_init_io(&s->iomem, OBJECT(s), &puv3_dma_ops, s, "puv3_dma",
- PUV3_REGS_OFFSET);
- sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->iomem);
-}
-
-static void puv3_dma_class_init(ObjectClass *klass, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(klass);
-
- dc->realize = puv3_dma_realize;
-}
-
-static const TypeInfo puv3_dma_info = {
- .name = TYPE_PUV3_DMA,
- .parent = TYPE_SYS_BUS_DEVICE,
- .instance_size = sizeof(PUV3DMAState),
- .class_init = puv3_dma_class_init,
-};
-
-static void puv3_dma_register_type(void)
-{
- type_register_static(&puv3_dma_info);
-}
-
-type_init(puv3_dma_register_type)
diff --git a/hw/gpio/meson.build b/hw/gpio/meson.build
index 79568f00ce..7bd6a57264 100644
--- a/hw/gpio/meson.build
+++ b/hw/gpio/meson.build
@@ -3,7 +3,6 @@ softmmu_ss.add(when: 'CONFIG_GPIO_KEY', if_true: files('gpio_key.c'))
softmmu_ss.add(when: 'CONFIG_GPIO_PWR', if_true: files('gpio_pwr.c'))
softmmu_ss.add(when: 'CONFIG_MAX7310', if_true: files('max7310.c'))
softmmu_ss.add(when: 'CONFIG_PL061', if_true: files('pl061.c'))
-softmmu_ss.add(when: 'CONFIG_PUV3', if_true: files('puv3_gpio.c'))
softmmu_ss.add(when: 'CONFIG_ZAURUS', if_true: files('zaurus.c'))
softmmu_ss.add(when: 'CONFIG_IMX', if_true: files('imx_gpio.c'))
diff --git a/hw/gpio/puv3_gpio.c b/hw/gpio/puv3_gpio.c
deleted file mode 100644
index e003ae505c..0000000000
--- a/hw/gpio/puv3_gpio.c
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- * GPIO device simulation in PKUnity SoC
- *
- * Copyright (C) 2010-2012 Guan Xuetao
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation, or any later version.
- * See the COPYING file in the top-level directory.
- */
-
-#include "qemu/osdep.h"
-#include "hw/sysbus.h"
-#include "qom/object.h"
-
-#undef DEBUG_PUV3
-#include "hw/unicore32/puv3.h"
-#include "qemu/module.h"
-#include "qemu/log.h"
-
-#define TYPE_PUV3_GPIO "puv3_gpio"
-OBJECT_DECLARE_SIMPLE_TYPE(PUV3GPIOState, PUV3_GPIO)
-
-struct PUV3GPIOState {
- SysBusDevice parent_obj;
-
- MemoryRegion iomem;
- qemu_irq irq[9];
-
- uint32_t reg_GPLR;
- uint32_t reg_GPDR;
- uint32_t reg_GPIR;
-};
-
-static uint64_t puv3_gpio_read(void *opaque, hwaddr offset,
- unsigned size)
-{
- PUV3GPIOState *s = opaque;
- uint32_t ret = 0;
-
- switch (offset) {
- case 0x00:
- ret = s->reg_GPLR;
- break;
- case 0x04:
- ret = s->reg_GPDR;
- break;
- case 0x20:
- ret = s->reg_GPIR;
- break;
- default:
- qemu_log_mask(LOG_GUEST_ERROR,
- "%s: Bad read offset 0x%"HWADDR_PRIx"\n",
- __func__, offset);
- }
- DPRINTF("offset 0x%x, value 0x%x\n", offset, ret);
-
- return ret;
-}
-
-static void puv3_gpio_write(void *opaque, hwaddr offset,
- uint64_t value, unsigned size)
-{
- PUV3GPIOState *s = opaque;
-
- DPRINTF("offset 0x%x, value 0x%x\n", offset, value);
- switch (offset) {
- case 0x04:
- s->reg_GPDR = value;
- break;
- case 0x08:
- if (s->reg_GPDR & value) {
- s->reg_GPLR |= value;
- } else {
- qemu_log_mask(LOG_GUEST_ERROR, "%s: Write gpio input port\n",
- __func__);
- }
- break;
- case 0x0c:
- if (s->reg_GPDR & value) {
- s->reg_GPLR &= ~value;
- } else {
- qemu_log_mask(LOG_GUEST_ERROR, "%s: Write gpio input port\n",
- __func__);
- }
- break;
- case 0x10: /* GRER */
- case 0x14: /* GFER */
- case 0x18: /* GEDR */
- break;
- case 0x20: /* GPIR */
- s->reg_GPIR = value;
- break;
- default:
- qemu_log_mask(LOG_GUEST_ERROR,
- "%s: Bad write offset 0x%"HWADDR_PRIx"\n",
- __func__, offset);
- }
-}
-
-static const MemoryRegionOps puv3_gpio_ops = {
- .read = puv3_gpio_read,
- .write = puv3_gpio_write,
- .impl = {
- .min_access_size = 4,
- .max_access_size = 4,
- },
- .endianness = DEVICE_NATIVE_ENDIAN,
-};
-
-static void puv3_gpio_realize(DeviceState *dev, Error **errp)
-{
- PUV3GPIOState *s = PUV3_GPIO(dev);
- SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
-
- s->reg_GPLR = 0;
- s->reg_GPDR = 0;
-
- /* FIXME: these irqs not handled yet */
- sysbus_init_irq(sbd, &s->irq[PUV3_IRQS_GPIOLOW0]);
- sysbus_init_irq(sbd, &s->irq[PUV3_IRQS_GPIOLOW1]);
- sysbus_init_irq(sbd, &s->irq[PUV3_IRQS_GPIOLOW2]);
- sysbus_init_irq(sbd, &s->irq[PUV3_IRQS_GPIOLOW3]);
- sysbus_init_irq(sbd, &s->irq[PUV3_IRQS_GPIOLOW4]);
- sysbus_init_irq(sbd, &s->irq[PUV3_IRQS_GPIOLOW5]);
- sysbus_init_irq(sbd, &s->irq[PUV3_IRQS_GPIOLOW6]);
- sysbus_init_irq(sbd, &s->irq[PUV3_IRQS_GPIOLOW7]);
- sysbus_init_irq(sbd, &s->irq[PUV3_IRQS_GPIOHIGH]);
-
- memory_region_init_io(&s->iomem, OBJECT(s), &puv3_gpio_ops, s, "puv3_gpio",
- PUV3_REGS_OFFSET);
- sysbus_init_mmio(sbd, &s->iomem);
-}
-
-static void puv3_gpio_class_init(ObjectClass *klass, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(klass);
-
- dc->realize = puv3_gpio_realize;
-}
-
-static const TypeInfo puv3_gpio_info = {
- .name = TYPE_PUV3_GPIO,
- .parent = TYPE_SYS_BUS_DEVICE,
- .instance_size = sizeof(PUV3GPIOState),
- .class_init = puv3_gpio_class_init,
-};
-
-static void puv3_gpio_register_type(void)
-{
- type_register_static(&puv3_gpio_info);
-}
-
-type_init(puv3_gpio_register_type)
diff --git a/hw/i2c/Kconfig b/hw/i2c/Kconfig
index 09642a6dcb..8d120a25d5 100644
--- a/hw/i2c/Kconfig
+++ b/hw/i2c/Kconfig
@@ -28,3 +28,7 @@ config IMX_I2C
config MPC_I2C
bool
select I2C
+
+config PCA954X
+ bool
+ select I2C
diff --git a/hw/i2c/core.c b/hw/i2c/core.c
index 21ec52ac5a..3a7bae311d 100644
--- a/hw/i2c/core.c
+++ b/hw/i2c/core.c
@@ -77,6 +77,30 @@ int i2c_bus_busy(I2CBus *bus)
return !QLIST_EMPTY(&bus->current_devs);
}
+bool i2c_scan_bus(I2CBus *bus, uint8_t address, bool broadcast,
+ I2CNodeList *current_devs)
+{
+ BusChild *kid;
+
+ QTAILQ_FOREACH(kid, &bus->qbus.children, sibling) {
+ DeviceState *qdev = kid->child;
+ I2CSlave *candidate = I2C_SLAVE(qdev);
+ I2CSlaveClass *sc = I2C_SLAVE_GET_CLASS(candidate);
+
+ if (sc->match_and_add(candidate, address, broadcast, current_devs)) {
+ if (!broadcast) {
+ return true;
+ }
+ }
+ }
+
+ /*
+ * If broadcast was true, and the list was full or empty, return true. If
+ * broadcast was false, return false.
+ */
+ return broadcast;
+}
+
/* TODO: Make this handle multiple masters. */
/*
* Start or continue an i2c transaction. When this is called for the
@@ -93,7 +117,6 @@ int i2c_bus_busy(I2CBus *bus)
*/
int i2c_start_transfer(I2CBus *bus, uint8_t address, int recv)
{
- BusChild *kid;
I2CSlaveClass *sc;
I2CNode *node;
bool bus_scanned = false;
@@ -115,18 +138,8 @@ int i2c_start_transfer(I2CBus *bus, uint8_t address, int recv)
* terminating the previous transaction.
*/
if (QLIST_EMPTY(&bus->current_devs)) {
- QTAILQ_FOREACH(kid, &bus->qbus.children, sibling) {
- DeviceState *qdev = kid->child;
- I2CSlave *candidate = I2C_SLAVE(qdev);
- if ((candidate->address == address) || (bus->broadcast)) {
- node = g_malloc(sizeof(struct I2CNode));
- node->elt = candidate;
- QLIST_INSERT_HEAD(&bus->current_devs, node, next);
- if (!bus->broadcast) {
- break;
- }
- }
- }
+ /* Disregard whether devices were found. */
+ (void)i2c_scan_bus(bus, address, bus->broadcast, &bus->current_devs);
bus_scanned = true;
}
@@ -290,12 +303,28 @@ I2CSlave *i2c_slave_create_simple(I2CBus *bus, const char *name, uint8_t addr)
return dev;
}
+static bool i2c_slave_match(I2CSlave *candidate, uint8_t address,
+ bool broadcast, I2CNodeList *current_devs)
+{
+ if ((candidate->address == address) || (broadcast)) {
+ I2CNode *node = g_malloc(sizeof(struct I2CNode));
+ node->elt = candidate;
+ QLIST_INSERT_HEAD(current_devs, node, next);
+ return true;
+ }
+
+ /* Not found and not broadcast. */
+ return false;
+}
+
static void i2c_slave_class_init(ObjectClass *klass, void *data)
{
DeviceClass *k = DEVICE_CLASS(klass);
+ I2CSlaveClass *sc = I2C_SLAVE_CLASS(klass);
set_bit(DEVICE_CATEGORY_MISC, k->categories);
k->bus_type = TYPE_I2C_BUS;
device_class_set_props(k, i2c_props);
+ sc->match_and_add = i2c_slave_match;
}
static const TypeInfo i2c_slave_type_info = {
diff --git a/hw/i2c/i2c_mux_pca954x.c b/hw/i2c/i2c_mux_pca954x.c
new file mode 100644
index 0000000000..847c59921c
--- /dev/null
+++ b/hw/i2c/i2c_mux_pca954x.c
@@ -0,0 +1,290 @@
+/*
+ * I2C multiplexer for PCA954x series of I2C multiplexer/switch chips.
+ *
+ * Copyright 2021 Google LLC
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include "qemu/osdep.h"
+#include "qapi/error.h"
+#include "hw/i2c/i2c.h"
+#include "hw/i2c/i2c_mux_pca954x.h"
+#include "hw/i2c/smbus_slave.h"
+#include "hw/qdev-core.h"
+#include "hw/sysbus.h"
+#include "qemu/log.h"
+#include "qemu/module.h"
+#include "qemu/queue.h"
+#include "qom/object.h"
+#include "trace.h"
+
+#define PCA9548_CHANNEL_COUNT 8
+#define PCA9546_CHANNEL_COUNT 4
+
+/*
+ * struct Pca954xChannel - The i2c mux device will have N of these states
+ * that own the i2c channel bus.
+ * @bus: The owned channel bus.
+ * @enabled: Is this channel active?
+ */
+typedef struct Pca954xChannel {
+ SysBusDevice parent;
+
+ I2CBus *bus;
+
+ bool enabled;
+} Pca954xChannel;
+
+#define TYPE_PCA954X_CHANNEL "pca954x-channel"
+#define PCA954X_CHANNEL(obj) \
+ OBJECT_CHECK(Pca954xChannel, (obj), TYPE_PCA954X_CHANNEL)
+
+/*
+ * struct Pca954xState - The pca954x state object.
+ * @control: The value written to the mux control.
+ * @channel: The set of i2c channel buses that act as channels which own the
+ * i2c children.
+ */
+typedef struct Pca954xState {
+ SMBusDevice parent;
+
+ uint8_t control;
+
+ /* The channel i2c buses. */
+ Pca954xChannel channel[PCA9548_CHANNEL_COUNT];
+} Pca954xState;
+
+/*
+ * struct Pca954xClass - The pca954x class object.
+ * @nchans: The number of i2c channels this device has.
+ */
+typedef struct Pca954xClass {
+ SMBusDeviceClass parent;
+
+ uint8_t nchans;
+} Pca954xClass;
+
+#define TYPE_PCA954X "pca954x"
+OBJECT_DECLARE_TYPE(Pca954xState, Pca954xClass, PCA954X)
+
+/*
+ * For each channel, if it's enabled, recursively call match on those children.
+ */
+static bool pca954x_match(I2CSlave *candidate, uint8_t address,
+ bool broadcast,
+ I2CNodeList *current_devs)
+{
+ Pca954xState *mux = PCA954X(candidate);
+ Pca954xClass *mc = PCA954X_GET_CLASS(mux);
+ int i;
+
+ /* They are talking to the mux itself (or all devices enabled). */
+ if ((candidate->address == address) || broadcast) {
+ I2CNode *node = g_malloc(sizeof(struct I2CNode));
+ node->elt = candidate;
+ QLIST_INSERT_HEAD(current_devs, node, next);
+ if (!broadcast) {
+ return true;
+ }
+ }
+
+ for (i = 0; i < mc->nchans; i++) {
+ if (!mux->channel[i].enabled) {
+ continue;
+ }
+
+ if (i2c_scan_bus(mux->channel[i].bus, address, broadcast,
+ current_devs)) {
+ if (!broadcast) {
+ return true;
+ }
+ }
+ }
+
+ /* If we arrived here we didn't find a match, return broadcast. */
+ return broadcast;
+}
+
+static void pca954x_enable_channel(Pca954xState *s, uint8_t enable_mask)
+{
+ Pca954xClass *mc = PCA954X_GET_CLASS(s);
+ int i;
+
+ /*
+ * For each channel, check if their bit is set in enable_mask and if yes,
+ * enable it, otherwise disable, hide it.
+ */
+ for (i = 0; i < mc->nchans; i++) {
+ if (enable_mask & (1 << i)) {
+ s->channel[i].enabled = true;
+ } else {
+ s->channel[i].enabled = false;
+ }
+ }
+}
+
+static void pca954x_write(Pca954xState *s, uint8_t data)
+{
+ s->control = data;
+ pca954x_enable_channel(s, data);
+
+ trace_pca954x_write_bytes(data);
+}
+
+static int pca954x_write_data(SMBusDevice *d, uint8_t *buf, uint8_t len)
+{
+ Pca954xState *s = PCA954X(d);
+
+ if (len == 0) {
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: writing empty data\n", __func__);
+ return -1;
+ }
+
+ /*
+ * len should be 1, because they write one byte to enable/disable channels.
+ */
+ if (len > 1) {
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "%s: extra data after channel selection mask\n",
+ __func__);
+ return -1;
+ }
+
+ pca954x_write(s, buf[0]);
+ return 0;
+}
+
+static uint8_t pca954x_read_byte(SMBusDevice *d)
+{
+ Pca954xState *s = PCA954X(d);
+ uint8_t data = s->control;
+ trace_pca954x_read_data(data);
+ return data;
+}
+
+static void pca954x_enter_reset(Object *obj, ResetType type)
+{
+ Pca954xState *s = PCA954X(obj);
+ /* Reset will disable all channels. */
+ pca954x_write(s, 0);
+}
+
+I2CBus *pca954x_i2c_get_bus(I2CSlave *mux, uint8_t channel)
+{
+ Pca954xClass *pc = PCA954X_GET_CLASS(mux);
+ Pca954xState *pca954x = PCA954X(mux);
+
+ g_assert(channel < pc->nchans);
+ return I2C_BUS(qdev_get_child_bus(DEVICE(&pca954x->channel[channel]),
+ "i2c-bus"));
+}
+
+static void pca954x_channel_init(Object *obj)
+{
+ Pca954xChannel *s = PCA954X_CHANNEL(obj);
+ s->bus = i2c_init_bus(DEVICE(s), "i2c-bus");
+
+ /* Start all channels as disabled. */
+ s->enabled = false;
+}
+
+static void pca954x_channel_class_init(ObjectClass *klass, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(klass);
+ dc->desc = "Pca954x Channel";
+}
+
+static void pca9546_class_init(ObjectClass *klass, void *data)
+{
+ Pca954xClass *s = PCA954X_CLASS(klass);
+ s->nchans = PCA9546_CHANNEL_COUNT;
+}
+
+static void pca9548_class_init(ObjectClass *klass, void *data)
+{
+ Pca954xClass *s = PCA954X_CLASS(klass);
+ s->nchans = PCA9548_CHANNEL_COUNT;
+}
+
+static void pca954x_realize(DeviceState *dev, Error **errp)
+{
+ Pca954xState *s = PCA954X(dev);
+ Pca954xClass *c = PCA954X_GET_CLASS(s);
+ int i;
+
+ /* SMBus modules. Cannot fail. */
+ for (i = 0; i < c->nchans; i++) {
+ sysbus_realize(SYS_BUS_DEVICE(&s->channel[i]), &error_abort);
+ }
+}
+
+static void pca954x_init(Object *obj)
+{
+ Pca954xState *s = PCA954X(obj);
+ Pca954xClass *c = PCA954X_GET_CLASS(obj);
+ int i;
+
+ /* Only initialize the children we expect. */
+ for (i = 0; i < c->nchans; i++) {
+ object_initialize_child(obj, "channel[*]", &s->channel[i],
+ TYPE_PCA954X_CHANNEL);
+ }
+}
+
+static void pca954x_class_init(ObjectClass *klass, void *data)
+{
+ I2CSlaveClass *sc = I2C_SLAVE_CLASS(klass);
+ ResettableClass *rc = RESETTABLE_CLASS(klass);
+ DeviceClass *dc = DEVICE_CLASS(klass);
+ SMBusDeviceClass *k = SMBUS_DEVICE_CLASS(klass);
+
+ sc->match_and_add = pca954x_match;
+
+ rc->phases.enter = pca954x_enter_reset;
+
+ dc->desc = "Pca954x i2c-mux";
+ dc->realize = pca954x_realize;
+
+ k->write_data = pca954x_write_data;
+ k->receive_byte = pca954x_read_byte;
+}
+
+static const TypeInfo pca954x_info[] = {
+ {
+ .name = TYPE_PCA954X,
+ .parent = TYPE_SMBUS_DEVICE,
+ .instance_size = sizeof(Pca954xState),
+ .instance_init = pca954x_init,
+ .class_size = sizeof(Pca954xClass),
+ .class_init = pca954x_class_init,
+ .abstract = true,
+ },
+ {
+ .name = TYPE_PCA9546,
+ .parent = TYPE_PCA954X,
+ .class_init = pca9546_class_init,
+ },
+ {
+ .name = TYPE_PCA9548,
+ .parent = TYPE_PCA954X,
+ .class_init = pca9548_class_init,
+ },
+ {
+ .name = TYPE_PCA954X_CHANNEL,
+ .parent = TYPE_SYS_BUS_DEVICE,
+ .class_init = pca954x_channel_class_init,
+ .instance_size = sizeof(Pca954xChannel),
+ .instance_init = pca954x_channel_init,
+ }
+};
+
+DEFINE_TYPES(pca954x_info)
diff --git a/hw/i2c/meson.build b/hw/i2c/meson.build
index cdcd694a7f..dd3aef02b2 100644
--- a/hw/i2c/meson.build
+++ b/hw/i2c/meson.build
@@ -14,4 +14,5 @@ i2c_ss.add(when: 'CONFIG_SMBUS_EEPROM', if_true: files('smbus_eeprom.c'))
i2c_ss.add(when: 'CONFIG_VERSATILE_I2C', if_true: files('versatile_i2c.c'))
i2c_ss.add(when: 'CONFIG_OMAP', if_true: files('omap_i2c.c'))
i2c_ss.add(when: 'CONFIG_PPC4XX', if_true: files('ppc4xx_i2c.c'))
+i2c_ss.add(when: 'CONFIG_PCA954X', if_true: files('i2c_mux_pca954x.c'))
softmmu_ss.add_all(when: 'CONFIG_I2C', if_true: i2c_ss)
diff --git a/hw/i2c/trace-events b/hw/i2c/trace-events
index 82fe6f965f..82f19e6a2d 100644
--- a/hw/i2c/trace-events
+++ b/hw/i2c/trace-events
@@ -26,3 +26,8 @@ npcm7xx_smbus_recv_byte(const char *id, uint8_t value) "%s recv byte: 0x%02x"
npcm7xx_smbus_stop(const char *id) "%s stopping"
npcm7xx_smbus_nack(const char *id) "%s nacking"
npcm7xx_smbus_recv_fifo(const char *id, uint8_t received, uint8_t expected) "%s recv fifo: received %u, expected %u"
+
+# i2c-mux-pca954x.c
+
+pca954x_write_bytes(uint8_t value) "PCA954X write data: 0x%02x"
+pca954x_read_data(uint8_t value) "PCA954X read data: 0x%02x"
diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index bfecb0038c..80bee00da6 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -1815,6 +1815,7 @@ build_hpet(GArray *table_data, BIOSLinker *linker, const char *oem_id,
const char *oem_table_id)
{
Acpi20Hpet *hpet;
+ int hpet_start = table_data->len;
hpet = acpi_data_push(table_data, sizeof(*hpet));
/* Note timer_block_id value must be kept in sync with value advertised by
@@ -1823,13 +1824,15 @@ build_hpet(GArray *table_data, BIOSLinker *linker, const char *oem_id,
hpet->timer_block_id = cpu_to_le32(0x8086a201);
hpet->addr.address = cpu_to_le64(HPET_BASE);
build_header(linker, table_data,
- (void *)hpet, "HPET", sizeof(*hpet), 1, oem_id, oem_table_id);
+ (void *)(table_data->data + hpet_start),
+ "HPET", sizeof(*hpet), 1, oem_id, oem_table_id);
}
static void
build_tpm_tcpa(GArray *table_data, BIOSLinker *linker, GArray *tcpalog,
const char *oem_id, const char *oem_table_id)
{
+ int tcpa_start = table_data->len;
Acpi20Tcpa *tcpa = acpi_data_push(table_data, sizeof *tcpa);
unsigned log_addr_size = sizeof(tcpa->log_area_start_address);
unsigned log_addr_offset =
@@ -1848,7 +1851,8 @@ build_tpm_tcpa(GArray *table_data, BIOSLinker *linker, GArray *tcpalog,
ACPI_BUILD_TPMLOG_FILE, 0);
build_header(linker, table_data,
- (void *)tcpa, "TCPA", sizeof(*tcpa), 2, oem_id, oem_table_id);
+ (void *)(table_data->data + tcpa_start),
+ "TCPA", sizeof(*tcpa), 2, oem_id, oem_table_id);
}
#define HOLE_640K_START (640 * KiB)
diff --git a/hw/i386/amd_iommu.c b/hw/i386/amd_iommu.c
index 74a93a5d93..2801dff97c 100644
--- a/hw/i386/amd_iommu.c
+++ b/hw/i386/amd_iommu.c
@@ -99,7 +99,7 @@ static uint64_t amdvi_readq(AMDVIState *s, hwaddr addr)
}
/* internal write */
-static void amdvi_writeq_raw(AMDVIState *s, uint64_t val, hwaddr addr)
+static void amdvi_writeq_raw(AMDVIState *s, hwaddr addr, uint64_t val)
{
stq_le_p(&s->mmior[addr], val);
}
@@ -382,7 +382,7 @@ static void amdvi_completion_wait(AMDVIState *s, uint64_t *cmd)
}
/* set completion interrupt */
if (extract64(cmd[0], 1, 1)) {
- amdvi_test_mask(s, AMDVI_MMIO_STATUS, AMDVI_MMIO_STATUS_COMP_INT);
+ amdvi_assign_orq(s, AMDVI_MMIO_STATUS, AMDVI_MMIO_STATUS_COMP_INT);
/* generate interrupt */
amdvi_generate_msi_interrupt(s);
}
@@ -553,7 +553,7 @@ static void amdvi_cmdbuf_run(AMDVIState *s)
trace_amdvi_command_exec(s->cmdbuf_head, s->cmdbuf_tail, s->cmdbuf);
amdvi_cmdbuf_exec(s);
s->cmdbuf_head += AMDVI_COMMAND_SIZE;
- amdvi_writeq_raw(s, s->cmdbuf_head, AMDVI_MMIO_COMMAND_HEAD);
+ amdvi_writeq_raw(s, AMDVI_MMIO_COMMAND_HEAD, s->cmdbuf_head);
/* wrap head pointer */
if (s->cmdbuf_head >= s->cmdbuf_len * AMDVI_COMMAND_SIZE) {
@@ -860,8 +860,8 @@ static inline uint8_t get_pte_translation_mode(uint64_t pte)
static inline uint64_t pte_override_page_mask(uint64_t pte)
{
- uint8_t page_mask = 12;
- uint64_t addr = (pte & AMDVI_DEV_PT_ROOT_MASK) ^ AMDVI_DEV_PT_ROOT_MASK;
+ uint8_t page_mask = 13;
+ uint64_t addr = (pte & AMDVI_DEV_PT_ROOT_MASK) >> 12;
/* find the first zero bit */
while (addr & 1) {
page_mask++;
diff --git a/hw/i386/fw_cfg.c b/hw/i386/fw_cfg.c
index e48a54fa36..4e68d5dea4 100644
--- a/hw/i386/fw_cfg.c
+++ b/hw/i386/fw_cfg.c
@@ -22,6 +22,7 @@
#include "hw/nvram/fw_cfg.h"
#include "e820_memory_layout.h"
#include "kvm/kvm_i386.h"
+#include "qapi/error.h"
#include CONFIG_DEVICES
struct hpet_fw_config hpet_cfg = {.count = UINT8_MAX};
@@ -78,7 +79,8 @@ void fw_cfg_build_smbios(MachineState *ms, FWCfgState *fw_cfg)
}
smbios_get_tables(ms, mem_array, array_count,
&smbios_tables, &smbios_tables_len,
- &smbios_anchor, &smbios_anchor_len);
+ &smbios_anchor, &smbios_anchor_len,
+ &error_fatal);
g_free(mem_array);
if (smbios_anchor) {
diff --git a/hw/i386/xen/xen-mapcache.c b/hw/i386/xen/xen-mapcache.c
index e82b7dcdd2..bd47c3d672 100644
--- a/hw/i386/xen/xen-mapcache.c
+++ b/hw/i386/xen/xen-mapcache.c
@@ -169,7 +169,8 @@ static void xen_remap_bucket(MapCacheEntry *entry,
if (entry->vaddr_base != NULL) {
if (!(entry->flags & XEN_MAPCACHE_ENTRY_DUMMY)) {
- ram_block_notify_remove(entry->vaddr_base, entry->size);
+ ram_block_notify_remove(entry->vaddr_base, entry->size,
+ entry->size);
}
/*
@@ -224,7 +225,7 @@ static void xen_remap_bucket(MapCacheEntry *entry,
}
if (!(entry->flags & XEN_MAPCACHE_ENTRY_DUMMY)) {
- ram_block_notify_add(vaddr_base, size);
+ ram_block_notify_add(vaddr_base, size, size);
}
entry->vaddr_base = vaddr_base;
@@ -465,7 +466,7 @@ static void xen_invalidate_map_cache_entry_unlocked(uint8_t *buffer)
}
pentry->next = entry->next;
- ram_block_notify_remove(entry->vaddr_base, entry->size);
+ ram_block_notify_remove(entry->vaddr_base, entry->size, entry->size);
if (munmap(entry->vaddr_base, entry->size) != 0) {
perror("unmap fails");
exit(-1);
diff --git a/hw/input/meson.build b/hw/input/meson.build
index 0042c3f0dc..8deb011d4a 100644
--- a/hw/input/meson.build
+++ b/hw/input/meson.build
@@ -13,7 +13,6 @@ softmmu_ss.add(when: 'CONFIG_VIRTIO_INPUT', if_true: files('virtio-input-hid.c')
softmmu_ss.add(when: 'CONFIG_VIRTIO_INPUT_HOST', if_true: files('virtio-input-host.c'))
softmmu_ss.add(when: 'CONFIG_VHOST_USER_INPUT', if_true: files('vhost-user-input.c'))
-softmmu_ss.add(when: 'CONFIG_MILKYMIST', if_true: files('milkymist-softusb.c'))
softmmu_ss.add(when: 'CONFIG_PXA2XX', if_true: files('pxa2xx_keypad.c'))
softmmu_ss.add(when: 'CONFIG_TSC210X', if_true: files('tsc210x.c'))
softmmu_ss.add(when: 'CONFIG_LASIPS2', if_true: files('lasips2.c'))
diff --git a/hw/input/milkymist-softusb.c b/hw/input/milkymist-softusb.c
deleted file mode 100644
index d885c708d7..0000000000
--- a/hw/input/milkymist-softusb.c
+++ /dev/null
@@ -1,319 +0,0 @@
-/*
- * QEMU model of the Milkymist SoftUSB block.
- *
- * Copyright (c) 2010 Michael Walle <michael@walle.cc>
- *
- * 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.1 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/>.
- *
- *
- * Specification available at:
- * not available yet
- */
-
-#include "qemu/osdep.h"
-#include "qapi/error.h"
-#include "hw/sysbus.h"
-#include "migration/vmstate.h"
-#include "trace.h"
-#include "ui/console.h"
-#include "hw/input/hid.h"
-#include "hw/irq.h"
-#include "hw/qdev-properties.h"
-#include "qemu/error-report.h"
-#include "qemu/module.h"
-#include "qom/object.h"
-
-enum {
- R_CTRL = 0,
- R_MAX
-};
-
-enum {
- CTRL_RESET = (1<<0),
-};
-
-#define COMLOC_DEBUG_PRODUCE 0x1000
-#define COMLOC_DEBUG_BASE 0x1001
-#define COMLOC_MEVT_PRODUCE 0x1101
-#define COMLOC_MEVT_BASE 0x1102
-#define COMLOC_KEVT_PRODUCE 0x1142
-#define COMLOC_KEVT_BASE 0x1143
-
-#define TYPE_MILKYMIST_SOFTUSB "milkymist-softusb"
-OBJECT_DECLARE_SIMPLE_TYPE(MilkymistSoftUsbState, MILKYMIST_SOFTUSB)
-
-struct MilkymistSoftUsbState {
- SysBusDevice parent_obj;
-
- HIDState hid_kbd;
- HIDState hid_mouse;
-
- MemoryRegion regs_region;
- MemoryRegion pmem;
- MemoryRegion dmem;
- qemu_irq irq;
-
- void *pmem_ptr;
- void *dmem_ptr;
-
- /* device properties */
- uint32_t pmem_size;
- uint32_t dmem_size;
-
- /* device registers */
- uint32_t regs[R_MAX];
-
- /* mouse state */
- uint8_t mouse_hid_buffer[4];
-
- /* keyboard state */
- uint8_t kbd_hid_buffer[8];
-};
-
-static uint64_t softusb_read(void *opaque, hwaddr addr,
- unsigned size)
-{
- MilkymistSoftUsbState *s = opaque;
- uint32_t r = 0;
-
- addr >>= 2;
- switch (addr) {
- case R_CTRL:
- r = s->regs[addr];
- break;
-
- default:
- error_report("milkymist_softusb: read access to unknown register 0x"
- TARGET_FMT_plx, addr << 2);
- break;
- }
-
- trace_milkymist_softusb_memory_read(addr << 2, r);
-
- return r;
-}
-
-static void
-softusb_write(void *opaque, hwaddr addr, uint64_t value,
- unsigned size)
-{
- MilkymistSoftUsbState *s = opaque;
-
- trace_milkymist_softusb_memory_write(addr, value);
-
- addr >>= 2;
- switch (addr) {
- case R_CTRL:
- s->regs[addr] = value;
- break;
-
- default:
- error_report("milkymist_softusb: write access to unknown register 0x"
- TARGET_FMT_plx, addr << 2);
- break;
- }
-}
-
-static const MemoryRegionOps softusb_mmio_ops = {
- .read = softusb_read,
- .write = softusb_write,
- .endianness = DEVICE_NATIVE_ENDIAN,
- .valid = {
- .min_access_size = 4,
- .max_access_size = 4,
- },
-};
-
-static inline void softusb_read_dmem(MilkymistSoftUsbState *s,
- uint32_t offset, uint8_t *buf, uint32_t len)
-{
- if (offset + len >= s->dmem_size) {
- error_report("milkymist_softusb: read dmem out of bounds "
- "at offset 0x%x, len %d", offset, len);
- memset(buf, 0, len);
- return;
- }
-
- memcpy(buf, s->dmem_ptr + offset, len);
-}
-
-static inline void softusb_write_dmem(MilkymistSoftUsbState *s,
- uint32_t offset, uint8_t *buf, uint32_t len)
-{
- if (offset + len >= s->dmem_size) {
- error_report("milkymist_softusb: write dmem out of bounds "
- "at offset 0x%x, len %d", offset, len);
- return;
- }
-
- memcpy(s->dmem_ptr + offset, buf, len);
-}
-
-static void softusb_mouse_changed(MilkymistSoftUsbState *s)
-{
- uint8_t m;
-
- softusb_read_dmem(s, COMLOC_MEVT_PRODUCE, &m, 1);
- trace_milkymist_softusb_mevt(m);
- softusb_write_dmem(s, COMLOC_MEVT_BASE + 4 * m, s->mouse_hid_buffer, 4);
- m = (m + 1) & 0xf;
- softusb_write_dmem(s, COMLOC_MEVT_PRODUCE, &m, 1);
-
- trace_milkymist_softusb_pulse_irq();
- qemu_irq_pulse(s->irq);
-}
-
-static void softusb_kbd_changed(MilkymistSoftUsbState *s)
-{
- uint8_t m;
-
- softusb_read_dmem(s, COMLOC_KEVT_PRODUCE, &m, 1);
- trace_milkymist_softusb_kevt(m);
- softusb_write_dmem(s, COMLOC_KEVT_BASE + 8 * m, s->kbd_hid_buffer, 8);
- m = (m + 1) & 0x7;
- softusb_write_dmem(s, COMLOC_KEVT_PRODUCE, &m, 1);
-
- trace_milkymist_softusb_pulse_irq();
- qemu_irq_pulse(s->irq);
-}
-
-static void softusb_kbd_hid_datain(HIDState *hs)
-{
- MilkymistSoftUsbState *s = container_of(hs, MilkymistSoftUsbState, hid_kbd);
- int len;
-
- /* if device is in reset, do nothing */
- if (s->regs[R_CTRL] & CTRL_RESET) {
- return;
- }
-
- while (hid_has_events(hs)) {
- len = hid_keyboard_poll(hs, s->kbd_hid_buffer,
- sizeof(s->kbd_hid_buffer));
-
- if (len == 8) {
- softusb_kbd_changed(s);
- }
- }
-}
-
-static void softusb_mouse_hid_datain(HIDState *hs)
-{
- MilkymistSoftUsbState *s =
- container_of(hs, MilkymistSoftUsbState, hid_mouse);
- int len;
-
- /* if device is in reset, do nothing */
- if (s->regs[R_CTRL] & CTRL_RESET) {
- return;
- }
-
- while (hid_has_events(hs)) {
- len = hid_pointer_poll(hs, s->mouse_hid_buffer,
- sizeof(s->mouse_hid_buffer));
-
- if (len == 4) {
- softusb_mouse_changed(s);
- }
- }
-}
-
-static void milkymist_softusb_reset(DeviceState *d)
-{
- MilkymistSoftUsbState *s = MILKYMIST_SOFTUSB(d);
- int i;
-
- for (i = 0; i < R_MAX; i++) {
- s->regs[i] = 0;
- }
- memset(s->kbd_hid_buffer, 0, sizeof(s->kbd_hid_buffer));
- memset(s->mouse_hid_buffer, 0, sizeof(s->mouse_hid_buffer));
-
- hid_reset(&s->hid_kbd);
- hid_reset(&s->hid_mouse);
-
- /* defaults */
- s->regs[R_CTRL] = CTRL_RESET;
-}
-
-static void milkymist_softusb_realize(DeviceState *dev, Error **errp)
-{
- MilkymistSoftUsbState *s = MILKYMIST_SOFTUSB(dev);
- SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
-
- sysbus_init_irq(sbd, &s->irq);
-
- memory_region_init_io(&s->regs_region, OBJECT(s), &softusb_mmio_ops, s,
- "milkymist-softusb", R_MAX * 4);
- sysbus_init_mmio(sbd, &s->regs_region);
-
- /* register pmem and dmem */
- memory_region_init_ram_nomigrate(&s->pmem, OBJECT(s), "milkymist-softusb.pmem",
- s->pmem_size, &error_fatal);
- vmstate_register_ram_global(&s->pmem);
- s->pmem_ptr = memory_region_get_ram_ptr(&s->pmem);
- sysbus_init_mmio(sbd, &s->pmem);
- memory_region_init_ram_nomigrate(&s->dmem, OBJECT(s), "milkymist-softusb.dmem",
- s->dmem_size, &error_fatal);
- vmstate_register_ram_global(&s->dmem);
- s->dmem_ptr = memory_region_get_ram_ptr(&s->dmem);
- sysbus_init_mmio(sbd, &s->dmem);
-
- hid_init(&s->hid_kbd, HID_KEYBOARD, softusb_kbd_hid_datain);
- hid_init(&s->hid_mouse, HID_MOUSE, softusb_mouse_hid_datain);
-}
-
-static const VMStateDescription vmstate_milkymist_softusb = {
- .name = "milkymist-softusb",
- .version_id = 1,
- .minimum_version_id = 1,
- .fields = (VMStateField[]) {
- VMSTATE_UINT32_ARRAY(regs, MilkymistSoftUsbState, R_MAX),
- VMSTATE_HID_KEYBOARD_DEVICE(hid_kbd, MilkymistSoftUsbState),
- VMSTATE_HID_POINTER_DEVICE(hid_mouse, MilkymistSoftUsbState),
- VMSTATE_BUFFER(kbd_hid_buffer, MilkymistSoftUsbState),
- VMSTATE_BUFFER(mouse_hid_buffer, MilkymistSoftUsbState),
- VMSTATE_END_OF_LIST()
- }
-};
-
-static Property milkymist_softusb_properties[] = {
- DEFINE_PROP_UINT32("pmem_size", MilkymistSoftUsbState, pmem_size, 0x00001000),
- DEFINE_PROP_UINT32("dmem_size", MilkymistSoftUsbState, dmem_size, 0x00002000),
- DEFINE_PROP_END_OF_LIST(),
-};
-
-static void milkymist_softusb_class_init(ObjectClass *klass, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(klass);
-
- dc->realize = milkymist_softusb_realize;
- dc->reset = milkymist_softusb_reset;
- dc->vmsd = &vmstate_milkymist_softusb;
- device_class_set_props(dc, milkymist_softusb_properties);
-}
-
-static const TypeInfo milkymist_softusb_info = {
- .name = TYPE_MILKYMIST_SOFTUSB,
- .parent = TYPE_SYS_BUS_DEVICE,
- .instance_size = sizeof(MilkymistSoftUsbState),
- .class_init = milkymist_softusb_class_init,
-};
-
-static void milkymist_softusb_register_types(void)
-{
- type_register_static(&milkymist_softusb_info);
-}
-
-type_init(milkymist_softusb_register_types)
diff --git a/hw/input/trace-events b/hw/input/trace-events
index 1dd8ad6018..33741e74f5 100644
--- a/hw/input/trace-events
+++ b/hw/input/trace-events
@@ -44,13 +44,6 @@ ps2_mouse_reset(void *opaque) "%p"
ps2_kbd_init(void *s) "%p"
ps2_mouse_init(void *s) "%p"
-# milkymist-softusb.c
-milkymist_softusb_memory_read(uint32_t addr, uint32_t value) "addr 0x%08x value 0x%08x"
-milkymist_softusb_memory_write(uint32_t addr, uint32_t value) "addr 0x%08x value 0x%08x"
-milkymist_softusb_mevt(uint8_t m) "m %d"
-milkymist_softusb_kevt(uint8_t m) "m %d"
-milkymist_softusb_pulse_irq(void) "Pulse IRQ"
-
# hid.c
hid_kbd_queue_full(void) "queue full"
hid_kbd_queue_empty(void) "queue empty"
diff --git a/hw/input/virtio-input-host.c b/hw/input/virtio-input-host.c
index 85daf73f1a..137efba57b 100644
--- a/hw/input/virtio-input-host.c
+++ b/hw/input/virtio-input-host.c
@@ -193,13 +193,16 @@ static void virtio_input_host_handle_status(VirtIOInput *vinput,
{
VirtIOInputHost *vih = VIRTIO_INPUT_HOST(vinput);
struct input_event evdev;
+ struct timeval tval;
int rc;
- if (gettimeofday(&evdev.time, NULL)) {
+ if (gettimeofday(&tval, NULL)) {
perror("virtio_input_host_handle_status: gettimeofday");
return;
}
+ evdev.input_event_sec = tval.tv_sec;
+ evdev.input_event_usec = tval.tv_usec;
evdev.type = le16_to_cpu(event->type);
evdev.code = le16_to_cpu(event->code);
evdev.value = le32_to_cpu(event->value);
diff --git a/hw/intc/lm32_pic.c b/hw/intc/lm32_pic.c
deleted file mode 100644
index 991a90bc99..0000000000
--- a/hw/intc/lm32_pic.c
+++ /dev/null
@@ -1,195 +0,0 @@
-/*
- * LatticeMico32 CPU interrupt controller logic.
- *
- * Copyright (c) 2010 Michael Walle <michael@walle.cc>
- *
- * 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.1 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 "migration/vmstate.h"
-#include "monitor/monitor.h"
-#include "qemu/module.h"
-#include "hw/sysbus.h"
-#include "trace.h"
-#include "hw/lm32/lm32_pic.h"
-#include "hw/intc/intc.h"
-#include "hw/irq.h"
-#include "qom/object.h"
-
-#define TYPE_LM32_PIC "lm32-pic"
-OBJECT_DECLARE_SIMPLE_TYPE(LM32PicState, LM32_PIC)
-
-struct LM32PicState {
- SysBusDevice parent_obj;
-
- qemu_irq parent_irq;
- uint32_t im; /* interrupt mask */
- uint32_t ip; /* interrupt pending */
- uint32_t irq_state;
-
- /* statistics */
- uint64_t stats_irq_count[32];
-};
-
-static void update_irq(LM32PicState *s)
-{
- s->ip |= s->irq_state;
-
- if (s->ip & s->im) {
- trace_lm32_pic_raise_irq();
- qemu_irq_raise(s->parent_irq);
- } else {
- trace_lm32_pic_lower_irq();
- qemu_irq_lower(s->parent_irq);
- }
-}
-
-static void irq_handler(void *opaque, int irq, int level)
-{
- LM32PicState *s = opaque;
-
- assert(irq < 32);
- trace_lm32_pic_interrupt(irq, level);
-
- if (level) {
- s->irq_state |= (1 << irq);
- s->stats_irq_count[irq]++;
- } else {
- s->irq_state &= ~(1 << irq);
- }
-
- update_irq(s);
-}
-
-void lm32_pic_set_im(DeviceState *d, uint32_t im)
-{
- LM32PicState *s = LM32_PIC(d);
-
- trace_lm32_pic_set_im(im);
- s->im = im;
-
- update_irq(s);
-}
-
-void lm32_pic_set_ip(DeviceState *d, uint32_t ip)
-{
- LM32PicState *s = LM32_PIC(d);
-
- trace_lm32_pic_set_ip(ip);
-
- /* ack interrupt */
- s->ip &= ~ip;
-
- update_irq(s);
-}
-
-uint32_t lm32_pic_get_im(DeviceState *d)
-{
- LM32PicState *s = LM32_PIC(d);
-
- trace_lm32_pic_get_im(s->im);
- return s->im;
-}
-
-uint32_t lm32_pic_get_ip(DeviceState *d)
-{
- LM32PicState *s = LM32_PIC(d);
-
- trace_lm32_pic_get_ip(s->ip);
- return s->ip;
-}
-
-static void pic_reset(DeviceState *d)
-{
- LM32PicState *s = LM32_PIC(d);
- int i;
-
- s->im = 0;
- s->ip = 0;
- s->irq_state = 0;
- for (i = 0; i < 32; i++) {
- s->stats_irq_count[i] = 0;
- }
-}
-
-static bool lm32_get_statistics(InterruptStatsProvider *obj,
- uint64_t **irq_counts, unsigned int *nb_irqs)
-{
- LM32PicState *s = LM32_PIC(obj);
- *irq_counts = s->stats_irq_count;
- *nb_irqs = ARRAY_SIZE(s->stats_irq_count);
- return true;
-}
-
-static void lm32_print_info(InterruptStatsProvider *obj, Monitor *mon)
-{
- LM32PicState *s = LM32_PIC(obj);
- monitor_printf(mon, "lm32-pic: im=%08x ip=%08x irq_state=%08x\n",
- s->im, s->ip, s->irq_state);
-}
-
-static void lm32_pic_init(Object *obj)
-{
- DeviceState *dev = DEVICE(obj);
- LM32PicState *s = LM32_PIC(obj);
- SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
-
- qdev_init_gpio_in(dev, irq_handler, 32);
- sysbus_init_irq(sbd, &s->parent_irq);
-}
-
-static const VMStateDescription vmstate_lm32_pic = {
- .name = "lm32-pic",
- .version_id = 2,
- .minimum_version_id = 2,
- .fields = (VMStateField[]) {
- VMSTATE_UINT32(im, LM32PicState),
- VMSTATE_UINT32(ip, LM32PicState),
- VMSTATE_UINT32(irq_state, LM32PicState),
- VMSTATE_UINT64_ARRAY(stats_irq_count, LM32PicState, 32),
- VMSTATE_END_OF_LIST()
- }
-};
-
-static void lm32_pic_class_init(ObjectClass *klass, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(klass);
- InterruptStatsProviderClass *ic = INTERRUPT_STATS_PROVIDER_CLASS(klass);
-
- dc->reset = pic_reset;
- dc->vmsd = &vmstate_lm32_pic;
- ic->get_statistics = lm32_get_statistics;
- ic->print_info = lm32_print_info;
-}
-
-static const TypeInfo lm32_pic_info = {
- .name = TYPE_LM32_PIC,
- .parent = TYPE_SYS_BUS_DEVICE,
- .instance_size = sizeof(LM32PicState),
- .instance_init = lm32_pic_init,
- .class_init = lm32_pic_class_init,
- .interfaces = (InterfaceInfo[]) {
- { TYPE_INTERRUPT_STATS_PROVIDER },
- { }
- },
-};
-
-static void lm32_pic_register_types(void)
-{
- type_register_static(&lm32_pic_info);
-}
-
-type_init(lm32_pic_register_types)
diff --git a/hw/intc/meson.build b/hw/intc/meson.build
index 1c299039f6..6e52a166e3 100644
--- a/hw/intc/meson.build
+++ b/hw/intc/meson.build
@@ -14,10 +14,8 @@ softmmu_ss.add(when: 'CONFIG_HEATHROW_PIC', if_true: files('heathrow_pic.c'))
softmmu_ss.add(when: 'CONFIG_I8259', if_true: files('i8259_common.c', 'i8259.c'))
softmmu_ss.add(when: 'CONFIG_IMX', if_true: files('imx_avic.c', 'imx_gpcv2.c'))
softmmu_ss.add(when: 'CONFIG_IOAPIC', if_true: files('ioapic_common.c'))
-softmmu_ss.add(when: 'CONFIG_LM32_DEVICES', if_true: files('lm32_pic.c'))
softmmu_ss.add(when: 'CONFIG_OPENPIC', if_true: files('openpic.c'))
softmmu_ss.add(when: 'CONFIG_PL190', if_true: files('pl190.c'))
-softmmu_ss.add(when: 'CONFIG_PUV3', if_true: files('puv3_intc.c'))
softmmu_ss.add(when: 'CONFIG_REALVIEW', if_true: files('realview_gic.c'))
softmmu_ss.add(when: 'CONFIG_SLAVIO', if_true: files('slavio_intctl.c'))
softmmu_ss.add(when: 'CONFIG_XILINX', if_true: files('xilinx_intc.c'))
diff --git a/hw/intc/puv3_intc.c b/hw/intc/puv3_intc.c
deleted file mode 100644
index 65226f5e7c..0000000000
--- a/hw/intc/puv3_intc.c
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- * INTC device simulation in PKUnity SoC
- *
- * Copyright (C) 2010-2012 Guan Xuetao
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation, or any later version.
- * See the COPYING file in the top-level directory.
- */
-
-#include "qemu/osdep.h"
-#include "hw/irq.h"
-#include "hw/sysbus.h"
-#include "qom/object.h"
-
-#undef DEBUG_PUV3
-#include "hw/unicore32/puv3.h"
-#include "qemu/module.h"
-#include "qemu/log.h"
-
-#define TYPE_PUV3_INTC "puv3_intc"
-OBJECT_DECLARE_SIMPLE_TYPE(PUV3INTCState, PUV3_INTC)
-
-struct PUV3INTCState {
- SysBusDevice parent_obj;
-
- MemoryRegion iomem;
- qemu_irq parent_irq;
-
- uint32_t reg_ICMR;
- uint32_t reg_ICPR;
-};
-
-/* Update interrupt status after enabled or pending bits have been changed. */
-static void puv3_intc_update(PUV3INTCState *s)
-{
- if (s->reg_ICMR & s->reg_ICPR) {
- qemu_irq_raise(s->parent_irq);
- } else {
- qemu_irq_lower(s->parent_irq);
- }
-}
-
-/* Process a change in an external INTC input. */
-static void puv3_intc_handler(void *opaque, int irq, int level)
-{
- PUV3INTCState *s = opaque;
-
- DPRINTF("irq 0x%x, level 0x%x\n", irq, level);
- if (level) {
- s->reg_ICPR |= (1 << irq);
- } else {
- s->reg_ICPR &= ~(1 << irq);
- }
- puv3_intc_update(s);
-}
-
-static uint64_t puv3_intc_read(void *opaque, hwaddr offset,
- unsigned size)
-{
- PUV3INTCState *s = opaque;
- uint32_t ret = 0;
-
- switch (offset) {
- case 0x04: /* INTC_ICMR */
- ret = s->reg_ICMR;
- break;
- case 0x0c: /* INTC_ICIP */
- ret = s->reg_ICPR; /* the same value with ICPR */
- break;
- default:
- qemu_log_mask(LOG_GUEST_ERROR,
- "%s: Bad read offset 0x%"HWADDR_PRIx"\n",
- __func__, offset);
- }
- DPRINTF("offset 0x%x, value 0x%x\n", offset, ret);
- return ret;
-}
-
-static void puv3_intc_write(void *opaque, hwaddr offset,
- uint64_t value, unsigned size)
-{
- PUV3INTCState *s = opaque;
-
- DPRINTF("offset 0x%x, value 0x%x\n", offset, value);
- switch (offset) {
- case 0x00: /* INTC_ICLR */
- case 0x14: /* INTC_ICCR */
- break;
- case 0x04: /* INTC_ICMR */
- s->reg_ICMR = value;
- break;
- default:
- qemu_log_mask(LOG_GUEST_ERROR,
- "%s: Bad write offset 0x%"HWADDR_PRIx"\n",
- __func__, offset);
- return;
- }
- puv3_intc_update(s);
-}
-
-static const MemoryRegionOps puv3_intc_ops = {
- .read = puv3_intc_read,
- .write = puv3_intc_write,
- .impl = {
- .min_access_size = 4,
- .max_access_size = 4,
- },
- .endianness = DEVICE_NATIVE_ENDIAN,
-};
-
-static void puv3_intc_realize(DeviceState *dev, Error **errp)
-{
- PUV3INTCState *s = PUV3_INTC(dev);
- SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
-
- qdev_init_gpio_in(dev, puv3_intc_handler, PUV3_IRQS_NR);
- sysbus_init_irq(sbd, &s->parent_irq);
-
- s->reg_ICMR = 0;
- s->reg_ICPR = 0;
-
- memory_region_init_io(&s->iomem, OBJECT(s), &puv3_intc_ops, s, "puv3_intc",
- PUV3_REGS_OFFSET);
- sysbus_init_mmio(sbd, &s->iomem);
-}
-
-static void puv3_intc_class_init(ObjectClass *klass, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(klass);
- dc->realize = puv3_intc_realize;
-}
-
-static const TypeInfo puv3_intc_info = {
- .name = TYPE_PUV3_INTC,
- .parent = TYPE_SYS_BUS_DEVICE,
- .instance_size = sizeof(PUV3INTCState),
- .class_init = puv3_intc_class_init,
-};
-
-static void puv3_intc_register_type(void)
-{
- type_register_static(&puv3_intc_info);
-}
-
-type_init(puv3_intc_register_type)
diff --git a/hw/intc/trace-events b/hw/intc/trace-events
index c9ab17234b..626bb554b2 100644
--- a/hw/intc/trace-events
+++ b/hw/intc/trace-events
@@ -51,15 +51,6 @@ grlib_irqmp_set_irq(int irq) "Raise CPU IRQ %d"
grlib_irqmp_readl_unknown(uint64_t addr) "addr 0x%"PRIx64
grlib_irqmp_writel_unknown(uint64_t addr, uint32_t value) "addr 0x%"PRIx64" value 0x%x"
-# lm32_pic.c
-lm32_pic_raise_irq(void) "Raise CPU interrupt"
-lm32_pic_lower_irq(void) "Lower CPU interrupt"
-lm32_pic_interrupt(int irq, int level) "Set IRQ%d %d"
-lm32_pic_set_im(uint32_t im) "im 0x%08x"
-lm32_pic_set_ip(uint32_t ip) "ip 0x%08x"
-lm32_pic_get_im(uint32_t im) "im 0x%08x"
-lm32_pic_get_ip(uint32_t ip) "ip 0x%08x"
-
# xics.c
xics_icp_check_ipi(int server, uint8_t mfrr) "CPU %d can take IPI mfrr=0x%x"
xics_icp_accept(uint32_t old_xirr, uint32_t new_xirr) "icp_accept: XIRR 0x%"PRIx32"->0x%"PRIx32
diff --git a/hw/lm32/Kconfig b/hw/lm32/Kconfig
deleted file mode 100644
index 8ac94205d7..0000000000
--- a/hw/lm32/Kconfig
+++ /dev/null
@@ -1,18 +0,0 @@
-config LM32_DEVICES
- bool
- select PTIMER
-
-config MILKYMIST
- bool
- # FIXME: disabling it results in compile-time errors
- select MILKYMIST_TMU2 if OPENGL && X11
- select PFLASH_CFI01
- select FRAMEBUFFER
- select SD
- select USB_OHCI
- select LM32_DEVICES
-
-config LM32_EVR
- bool
- select LM32_DEVICES
- select PFLASH_CFI02
diff --git a/hw/lm32/lm32.h b/hw/lm32/lm32.h
deleted file mode 100644
index 7b4f6255b9..0000000000
--- a/hw/lm32/lm32.h
+++ /dev/null
@@ -1,48 +0,0 @@
-#ifndef HW_LM32_H
-#define HW_LM32_H
-
-#include "hw/char/lm32_juart.h"
-#include "hw/qdev-properties.h"
-#include "qapi/error.h"
-
-static inline DeviceState *lm32_pic_init(qemu_irq cpu_irq)
-{
- DeviceState *dev;
- SysBusDevice *d;
-
- dev = qdev_new("lm32-pic");
- d = SYS_BUS_DEVICE(dev);
- sysbus_realize_and_unref(d, &error_fatal);
- sysbus_connect_irq(d, 0, cpu_irq);
-
- return dev;
-}
-
-static inline DeviceState *lm32_juart_init(Chardev *chr)
-{
- DeviceState *dev;
-
- dev = qdev_new(TYPE_LM32_JUART);
- qdev_prop_set_chr(dev, "chardev", chr);
- sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
-
- return dev;
-}
-
-static inline DeviceState *lm32_uart_create(hwaddr addr,
- qemu_irq irq,
- Chardev *chr)
-{
- DeviceState *dev;
- SysBusDevice *s;
-
- dev = qdev_new("lm32-uart");
- s = SYS_BUS_DEVICE(dev);
- qdev_prop_set_chr(dev, "chardev", chr);
- sysbus_realize_and_unref(s, &error_fatal);
- sysbus_mmio_map(s, 0, addr);
- sysbus_connect_irq(s, 0, irq);
- return dev;
-}
-
-#endif
diff --git a/hw/lm32/lm32_boards.c b/hw/lm32/lm32_boards.c
deleted file mode 100644
index 2961e4c2b4..0000000000
--- a/hw/lm32/lm32_boards.c
+++ /dev/null
@@ -1,332 +0,0 @@
-/*
- * QEMU models for LatticeMico32 uclinux and evr32 boards.
- *
- * Copyright (c) 2010 Michael Walle <michael@walle.cc>
- *
- * 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.1 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 "qemu/units.h"
-#include "qemu/cutils.h"
-#include "qemu/error-report.h"
-#include "cpu.h"
-#include "hw/sysbus.h"
-#include "hw/irq.h"
-#include "hw/block/flash.h"
-#include "hw/boards.h"
-#include "hw/loader.h"
-#include "elf.h"
-#include "lm32_hwsetup.h"
-#include "lm32.h"
-#include "sysemu/reset.h"
-#include "sysemu/sysemu.h"
-
-typedef struct {
- LM32CPU *cpu;
- hwaddr bootstrap_pc;
- hwaddr flash_base;
- hwaddr hwsetup_base;
- hwaddr initrd_base;
- size_t initrd_size;
- hwaddr cmdline_base;
-} ResetInfo;
-
-static void cpu_irq_handler(void *opaque, int irq, int level)
-{
- LM32CPU *cpu = opaque;
- CPUState *cs = CPU(cpu);
-
- if (level) {
- cpu_interrupt(cs, CPU_INTERRUPT_HARD);
- } else {
- cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD);
- }
-}
-
-static void main_cpu_reset(void *opaque)
-{
- ResetInfo *reset_info = opaque;
- CPULM32State *env = &reset_info->cpu->env;
-
- cpu_reset(CPU(reset_info->cpu));
-
- /* init defaults */
- env->pc = (uint32_t)reset_info->bootstrap_pc;
- env->regs[R_R1] = (uint32_t)reset_info->hwsetup_base;
- env->regs[R_R2] = (uint32_t)reset_info->cmdline_base;
- env->regs[R_R3] = (uint32_t)reset_info->initrd_base;
- env->regs[R_R4] = (uint32_t)(reset_info->initrd_base +
- reset_info->initrd_size);
- env->eba = reset_info->flash_base;
- env->deba = reset_info->flash_base;
-}
-
-static void lm32_evr_init(MachineState *machine)
-{
- MachineClass *mc = MACHINE_GET_CLASS(machine);
- const char *kernel_filename = machine->kernel_filename;
- LM32CPU *cpu;
- CPULM32State *env;
- DriveInfo *dinfo;
- MemoryRegion *address_space_mem = get_system_memory();
- qemu_irq irq[32];
- ResetInfo *reset_info;
- int i;
-
- if (machine->ram_size != mc->default_ram_size) {
- char *sz = size_to_str(mc->default_ram_size);
- error_report("Invalid RAM size, should be %s", sz);
- g_free(sz);
- exit(EXIT_FAILURE);
- }
-
- /* memory map */
- hwaddr flash_base = 0x04000000;
- size_t flash_sector_size = 256 * KiB;
- size_t flash_size = 32 * MiB;
- hwaddr ram_base = 0x08000000;
- hwaddr timer0_base = 0x80002000;
- hwaddr uart0_base = 0x80006000;
- hwaddr timer1_base = 0x8000a000;
- int uart0_irq = 0;
- int timer0_irq = 1;
- int timer1_irq = 3;
-
- reset_info = g_malloc0(sizeof(ResetInfo));
-
- cpu = LM32_CPU(cpu_create(machine->cpu_type));
-
- env = &cpu->env;
- reset_info->cpu = cpu;
-
- reset_info->flash_base = flash_base;
-
- memory_region_add_subregion(address_space_mem, ram_base, machine->ram);
-
- dinfo = drive_get(IF_PFLASH, 0, 0);
- /* Spansion S29NS128P */
- pflash_cfi02_register(flash_base, "lm32_evr.flash", flash_size,
- dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
- flash_sector_size,
- 1, 2, 0x01, 0x7e, 0x43, 0x00, 0x555, 0x2aa, 1);
-
- /* create irq lines */
- env->pic_state = lm32_pic_init(qemu_allocate_irq(cpu_irq_handler, cpu, 0));
- for (i = 0; i < 32; i++) {
- irq[i] = qdev_get_gpio_in(env->pic_state, i);
- }
-
- lm32_uart_create(uart0_base, irq[uart0_irq], serial_hd(0));
- sysbus_create_simple("lm32-timer", timer0_base, irq[timer0_irq]);
- sysbus_create_simple("lm32-timer", timer1_base, irq[timer1_irq]);
-
- /* make sure juart isn't the first chardev */
- env->juart_state = lm32_juart_init(serial_hd(1));
-
- reset_info->bootstrap_pc = flash_base;
-
- if (kernel_filename) {
- uint64_t entry;
- int kernel_size;
-
- kernel_size = load_elf(kernel_filename, NULL, NULL, NULL,
- &entry, NULL, NULL, NULL,
- 1, EM_LATTICEMICO32, 0, 0);
- reset_info->bootstrap_pc = entry;
-
- if (kernel_size < 0) {
- kernel_size = load_image_targphys(kernel_filename, ram_base,
- machine->ram_size);
- reset_info->bootstrap_pc = ram_base;
- }
-
- if (kernel_size < 0) {
- error_report("could not load kernel '%s'", kernel_filename);
- exit(1);
- }
- }
-
- qemu_register_reset(main_cpu_reset, reset_info);
-}
-
-static void lm32_uclinux_init(MachineState *machine)
-{
- MachineClass *mc = MACHINE_GET_CLASS(machine);
- const char *kernel_filename = machine->kernel_filename;
- const char *kernel_cmdline = machine->kernel_cmdline;
- const char *initrd_filename = machine->initrd_filename;
- LM32CPU *cpu;
- CPULM32State *env;
- DriveInfo *dinfo;
- MemoryRegion *address_space_mem = get_system_memory();
- qemu_irq irq[32];
- HWSetup *hw;
- ResetInfo *reset_info;
- int i;
-
- if (machine->ram_size != mc->default_ram_size) {
- char *sz = size_to_str(mc->default_ram_size);
- error_report("Invalid RAM size, should be %s", sz);
- g_free(sz);
- exit(EXIT_FAILURE);
- }
-
- /* memory map */
- hwaddr flash_base = 0x04000000;
- size_t flash_sector_size = 256 * KiB;
- size_t flash_size = 32 * MiB;
- hwaddr ram_base = 0x08000000;
- hwaddr uart0_base = 0x80000000;
- hwaddr timer0_base = 0x80002000;
- hwaddr timer1_base = 0x80010000;
- hwaddr timer2_base = 0x80012000;
- int uart0_irq = 0;
- int timer0_irq = 1;
- int timer1_irq = 20;
- int timer2_irq = 21;
- hwaddr hwsetup_base = 0x0bffe000;
- hwaddr cmdline_base = 0x0bfff000;
- hwaddr initrd_base = 0x08400000;
- size_t initrd_max = 0x01000000;
-
- reset_info = g_malloc0(sizeof(ResetInfo));
-
- cpu = LM32_CPU(cpu_create(machine->cpu_type));
-
- env = &cpu->env;
- reset_info->cpu = cpu;
-
- reset_info->flash_base = flash_base;
-
- memory_region_add_subregion(address_space_mem, ram_base, machine->ram);
-
- dinfo = drive_get(IF_PFLASH, 0, 0);
- /* Spansion S29NS128P */
- pflash_cfi02_register(flash_base, "lm32_uclinux.flash", flash_size,
- dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
- flash_sector_size,
- 1, 2, 0x01, 0x7e, 0x43, 0x00, 0x555, 0x2aa, 1);
-
- /* create irq lines */
- env->pic_state = lm32_pic_init(qemu_allocate_irq(cpu_irq_handler, env, 0));
- for (i = 0; i < 32; i++) {
- irq[i] = qdev_get_gpio_in(env->pic_state, i);
- }
-
- lm32_uart_create(uart0_base, irq[uart0_irq], serial_hd(0));
- sysbus_create_simple("lm32-timer", timer0_base, irq[timer0_irq]);
- sysbus_create_simple("lm32-timer", timer1_base, irq[timer1_irq]);
- sysbus_create_simple("lm32-timer", timer2_base, irq[timer2_irq]);
-
- /* make sure juart isn't the first chardev */
- env->juart_state = lm32_juart_init(serial_hd(1));
-
- reset_info->bootstrap_pc = flash_base;
-
- if (kernel_filename) {
- uint64_t entry;
- int kernel_size;
-
- kernel_size = load_elf(kernel_filename, NULL, NULL, NULL,
- &entry, NULL, NULL, NULL,
- 1, EM_LATTICEMICO32, 0, 0);
- reset_info->bootstrap_pc = entry;
-
- if (kernel_size < 0) {
- kernel_size = load_image_targphys(kernel_filename, ram_base,
- machine->ram_size);
- reset_info->bootstrap_pc = ram_base;
- }
-
- if (kernel_size < 0) {
- error_report("could not load kernel '%s'", kernel_filename);
- exit(1);
- }
- }
-
- /* generate a rom with the hardware description */
- hw = hwsetup_init();
- hwsetup_add_cpu(hw, "LM32", 75000000);
- hwsetup_add_flash(hw, "flash", flash_base, flash_size);
- hwsetup_add_ddr_sdram(hw, "ddr_sdram", ram_base, machine->ram_size);
- hwsetup_add_timer(hw, "timer0", timer0_base, timer0_irq);
- hwsetup_add_timer(hw, "timer1_dev_only", timer1_base, timer1_irq);
- hwsetup_add_timer(hw, "timer2_dev_only", timer2_base, timer2_irq);
- hwsetup_add_uart(hw, "uart", uart0_base, uart0_irq);
- hwsetup_add_trailer(hw);
- hwsetup_create_rom(hw, hwsetup_base);
- hwsetup_free(hw);
-
- reset_info->hwsetup_base = hwsetup_base;
-
- if (kernel_cmdline && strlen(kernel_cmdline)) {
- pstrcpy_targphys("cmdline", cmdline_base, TARGET_PAGE_SIZE,
- kernel_cmdline);
- reset_info->cmdline_base = cmdline_base;
- }
-
- if (initrd_filename) {
- size_t initrd_size;
- initrd_size = load_image_targphys(initrd_filename, initrd_base,
- initrd_max);
- reset_info->initrd_base = initrd_base;
- reset_info->initrd_size = initrd_size;
- }
-
- qemu_register_reset(main_cpu_reset, reset_info);
-}
-
-static void lm32_evr_class_init(ObjectClass *oc, void *data)
-{
- MachineClass *mc = MACHINE_CLASS(oc);
-
- mc->desc = "LatticeMico32 EVR32 eval system";
- mc->init = lm32_evr_init;
- mc->is_default = true;
- mc->default_cpu_type = LM32_CPU_TYPE_NAME("lm32-full");
- mc->default_ram_size = 64 * MiB;
- mc->default_ram_id = "lm32_evr.sdram";
-}
-
-static const TypeInfo lm32_evr_type = {
- .name = MACHINE_TYPE_NAME("lm32-evr"),
- .parent = TYPE_MACHINE,
- .class_init = lm32_evr_class_init,
-};
-
-static void lm32_uclinux_class_init(ObjectClass *oc, void *data)
-{
- MachineClass *mc = MACHINE_CLASS(oc);
-
- mc->desc = "lm32 platform for uClinux and u-boot by Theobroma Systems";
- mc->init = lm32_uclinux_init;
- mc->default_cpu_type = LM32_CPU_TYPE_NAME("lm32-full");
- mc->default_ram_size = 64 * MiB;
- mc->default_ram_id = "lm32_uclinux.sdram";
-}
-
-static const TypeInfo lm32_uclinux_type = {
- .name = MACHINE_TYPE_NAME("lm32-uclinux"),
- .parent = TYPE_MACHINE,
- .class_init = lm32_uclinux_class_init,
-};
-
-static void lm32_machine_init(void)
-{
- type_register_static(&lm32_evr_type);
- type_register_static(&lm32_uclinux_type);
-}
-
-type_init(lm32_machine_init)
diff --git a/hw/lm32/lm32_hwsetup.h b/hw/lm32/lm32_hwsetup.h
deleted file mode 100644
index e6cd30ad68..0000000000
--- a/hw/lm32/lm32_hwsetup.h
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
- * LatticeMico32 hwsetup helper functions.
- *
- * Copyright (c) 2010 Michael Walle <michael@walle.cc>
- *
- * 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.1 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/>.
- */
-
-/*
- * These are helper functions for creating the hardware description blob used
- * in the Theobroma's uClinux port.
- */
-
-#ifndef QEMU_HW_LM32_HWSETUP_H
-#define QEMU_HW_LM32_HWSETUP_H
-
-#include "qemu/cutils.h"
-#include "hw/loader.h"
-
-typedef struct {
- void *data;
- void *ptr;
-} HWSetup;
-
-enum hwsetup_tag {
- HWSETUP_TAG_EOL = 0,
- HWSETUP_TAG_CPU = 1,
- HWSETUP_TAG_ASRAM = 2,
- HWSETUP_TAG_FLASH = 3,
- HWSETUP_TAG_SDRAM = 4,
- HWSETUP_TAG_OCM = 5,
- HWSETUP_TAG_DDR_SDRAM = 6,
- HWSETUP_TAG_DDR2_SDRAM = 7,
- HWSETUP_TAG_TIMER = 8,
- HWSETUP_TAG_UART = 9,
- HWSETUP_TAG_GPIO = 10,
- HWSETUP_TAG_TRISPEEDMAC = 11,
- HWSETUP_TAG_I2CM = 12,
- HWSETUP_TAG_LEDS = 13,
- HWSETUP_TAG_7SEG = 14,
- HWSETUP_TAG_SPI_S = 15,
- HWSETUP_TAG_SPI_M = 16,
-};
-
-static inline HWSetup *hwsetup_init(void)
-{
- HWSetup *hw;
-
- hw = g_malloc(sizeof(HWSetup));
- hw->data = g_malloc0(TARGET_PAGE_SIZE);
- hw->ptr = hw->data;
-
- return hw;
-}
-
-static inline void hwsetup_free(HWSetup *hw)
-{
- g_free(hw->data);
- g_free(hw);
-}
-
-static inline void hwsetup_create_rom(HWSetup *hw,
- hwaddr base)
-{
- rom_add_blob("hwsetup", hw->data, TARGET_PAGE_SIZE,
- TARGET_PAGE_SIZE, base, NULL, NULL, NULL, NULL, true);
-}
-
-static inline void hwsetup_add_u8(HWSetup *hw, uint8_t u)
-{
- stb_p(hw->ptr, u);
- hw->ptr += 1;
-}
-
-static inline void hwsetup_add_u32(HWSetup *hw, uint32_t u)
-{
- stl_p(hw->ptr, u);
- hw->ptr += 4;
-}
-
-static inline void hwsetup_add_tag(HWSetup *hw, enum hwsetup_tag t)
-{
- stl_p(hw->ptr, t);
- hw->ptr += 4;
-}
-
-static inline void hwsetup_add_str(HWSetup *hw, const char *str)
-{
- pstrcpy(hw->ptr, 32, str);
- hw->ptr += 32;
-}
-
-static inline void hwsetup_add_trailer(HWSetup *hw)
-{
- hwsetup_add_u32(hw, 8); /* size */
- hwsetup_add_tag(hw, HWSETUP_TAG_EOL);
-}
-
-static inline void hwsetup_add_cpu(HWSetup *hw,
- const char *name, uint32_t frequency)
-{
- hwsetup_add_u32(hw, 44); /* size */
- hwsetup_add_tag(hw, HWSETUP_TAG_CPU);
- hwsetup_add_str(hw, name);
- hwsetup_add_u32(hw, frequency);
-}
-
-static inline void hwsetup_add_flash(HWSetup *hw,
- const char *name, uint32_t base, uint32_t size)
-{
- hwsetup_add_u32(hw, 52); /* size */
- hwsetup_add_tag(hw, HWSETUP_TAG_FLASH);
- hwsetup_add_str(hw, name);
- hwsetup_add_u32(hw, base);
- hwsetup_add_u32(hw, size);
- hwsetup_add_u8(hw, 8); /* read latency */
- hwsetup_add_u8(hw, 8); /* write latency */
- hwsetup_add_u8(hw, 25); /* address width */
- hwsetup_add_u8(hw, 32); /* data width */
-}
-
-static inline void hwsetup_add_ddr_sdram(HWSetup *hw,
- const char *name, uint32_t base, uint32_t size)
-{
- hwsetup_add_u32(hw, 48); /* size */
- hwsetup_add_tag(hw, HWSETUP_TAG_DDR_SDRAM);
- hwsetup_add_str(hw, name);
- hwsetup_add_u32(hw, base);
- hwsetup_add_u32(hw, size);
-}
-
-static inline void hwsetup_add_timer(HWSetup *hw,
- const char *name, uint32_t base, uint32_t irq)
-{
- hwsetup_add_u32(hw, 56); /* size */
- hwsetup_add_tag(hw, HWSETUP_TAG_TIMER);
- hwsetup_add_str(hw, name);
- hwsetup_add_u32(hw, base);
- hwsetup_add_u8(hw, 1); /* wr_tickcount */
- hwsetup_add_u8(hw, 1); /* rd_tickcount */
- hwsetup_add_u8(hw, 1); /* start_stop_control */
- hwsetup_add_u8(hw, 32); /* counter_width */
- hwsetup_add_u32(hw, 20); /* reload_ticks */
- hwsetup_add_u8(hw, irq);
- hwsetup_add_u8(hw, 0); /* padding */
- hwsetup_add_u8(hw, 0); /* padding */
- hwsetup_add_u8(hw, 0); /* padding */
-}
-
-static inline void hwsetup_add_uart(HWSetup *hw,
- const char *name, uint32_t base, uint32_t irq)
-{
- hwsetup_add_u32(hw, 56); /* size */
- hwsetup_add_tag(hw, HWSETUP_TAG_UART);
- hwsetup_add_str(hw, name);
- hwsetup_add_u32(hw, base);
- hwsetup_add_u32(hw, 115200); /* baudrate */
- hwsetup_add_u8(hw, 8); /* databits */
- hwsetup_add_u8(hw, 1); /* stopbits */
- hwsetup_add_u8(hw, 1); /* use_interrupt */
- hwsetup_add_u8(hw, 1); /* block_on_transmit */
- hwsetup_add_u8(hw, 1); /* block_on_receive */
- hwsetup_add_u8(hw, 4); /* rx_buffer_size */
- hwsetup_add_u8(hw, 4); /* tx_buffer_size */
- hwsetup_add_u8(hw, irq);
-}
-
-#endif /* QEMU_HW_LM32_HWSETUP_H */
diff --git a/hw/lm32/meson.build b/hw/lm32/meson.build
deleted file mode 100644
index 42d6f8db3d..0000000000
--- a/hw/lm32/meson.build
+++ /dev/null
@@ -1,6 +0,0 @@
-lm32_ss = ss.source_set()
-# LM32 boards
-lm32_ss.add(when: 'CONFIG_LM32_EVR', if_true: files('lm32_boards.c'))
-lm32_ss.add(when: 'CONFIG_MILKYMIST', if_true: files('milkymist.c'))
-
-hw_arch += {'lm32': lm32_ss}
diff --git a/hw/lm32/milkymist-hw.h b/hw/lm32/milkymist-hw.h
deleted file mode 100644
index 5dca5d52f5..0000000000
--- a/hw/lm32/milkymist-hw.h
+++ /dev/null
@@ -1,133 +0,0 @@
-#ifndef QEMU_HW_MILKYMIST_HW_H
-#define QEMU_HW_MILKYMIST_HW_H
-
-#include "hw/qdev-core.h"
-#include "net/net.h"
-#include "qapi/error.h"
-
-static inline DeviceState *milkymist_uart_create(hwaddr base,
- qemu_irq irq,
- Chardev *chr)
-{
- DeviceState *dev;
-
- dev = qdev_new("milkymist-uart");
- qdev_prop_set_chr(dev, "chardev", chr);
- sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
- sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, base);
- sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, irq);
-
- return dev;
-}
-
-static inline DeviceState *milkymist_hpdmc_create(hwaddr base)
-{
- DeviceState *dev;
-
- dev = qdev_new("milkymist-hpdmc");
- sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
- sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, base);
-
- return dev;
-}
-
-static inline DeviceState *milkymist_vgafb_create(hwaddr base,
- uint32_t fb_offset, uint32_t fb_mask)
-{
- DeviceState *dev;
-
- dev = qdev_new("milkymist-vgafb");
- qdev_prop_set_uint32(dev, "fb_offset", fb_offset);
- qdev_prop_set_uint32(dev, "fb_mask", fb_mask);
- sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
- sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, base);
-
- return dev;
-}
-
-static inline DeviceState *milkymist_sysctl_create(hwaddr base,
- qemu_irq gpio_irq, qemu_irq timer0_irq, qemu_irq timer1_irq,
- uint32_t freq_hz, uint32_t system_id, uint32_t capabilities,
- uint32_t gpio_strappings)
-{
- DeviceState *dev;
-
- dev = qdev_new("milkymist-sysctl");
- qdev_prop_set_uint32(dev, "frequency", freq_hz);
- qdev_prop_set_uint32(dev, "systemid", system_id);
- qdev_prop_set_uint32(dev, "capabilities", capabilities);
- qdev_prop_set_uint32(dev, "gpio_strappings", gpio_strappings);
- sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
- sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, base);
- sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, gpio_irq);
- sysbus_connect_irq(SYS_BUS_DEVICE(dev), 1, timer0_irq);
- sysbus_connect_irq(SYS_BUS_DEVICE(dev), 2, timer1_irq);
-
- return dev;
-}
-
-static inline DeviceState *milkymist_pfpu_create(hwaddr base,
- qemu_irq irq)
-{
- DeviceState *dev;
-
- dev = qdev_new("milkymist-pfpu");
- sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
- sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, base);
- sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, irq);
- return dev;
-}
-
-static inline DeviceState *milkymist_ac97_create(hwaddr base,
- qemu_irq crrequest_irq, qemu_irq crreply_irq, qemu_irq dmar_irq,
- qemu_irq dmaw_irq)
-{
- DeviceState *dev;
-
- dev = qdev_new("milkymist-ac97");
- sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
- sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, base);
- sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, crrequest_irq);
- sysbus_connect_irq(SYS_BUS_DEVICE(dev), 1, crreply_irq);
- sysbus_connect_irq(SYS_BUS_DEVICE(dev), 2, dmar_irq);
- sysbus_connect_irq(SYS_BUS_DEVICE(dev), 3, dmaw_irq);
-
- return dev;
-}
-
-static inline DeviceState *milkymist_minimac2_create(hwaddr base,
- hwaddr buffers_base, qemu_irq rx_irq, qemu_irq tx_irq)
-{
- DeviceState *dev;
-
- qemu_check_nic_model(&nd_table[0], "minimac2");
- dev = qdev_new("milkymist-minimac2");
- qdev_set_nic_properties(dev, &nd_table[0]);
- sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
- sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, base);
- sysbus_mmio_map(SYS_BUS_DEVICE(dev), 1, buffers_base);
- sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, rx_irq);
- sysbus_connect_irq(SYS_BUS_DEVICE(dev), 1, tx_irq);
-
- return dev;
-}
-
-static inline DeviceState *milkymist_softusb_create(hwaddr base,
- qemu_irq irq, uint32_t pmem_base, uint32_t pmem_size,
- uint32_t dmem_base, uint32_t dmem_size)
-{
- DeviceState *dev;
-
- dev = qdev_new("milkymist-softusb");
- qdev_prop_set_uint32(dev, "pmem_size", pmem_size);
- qdev_prop_set_uint32(dev, "dmem_size", dmem_size);
- sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
- sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, base);
- sysbus_mmio_map(SYS_BUS_DEVICE(dev), 1, pmem_base);
- sysbus_mmio_map(SYS_BUS_DEVICE(dev), 2, dmem_base);
- sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, irq);
-
- return dev;
-}
-
-#endif /* QEMU_HW_MILKYMIST_HW_H */
diff --git a/hw/lm32/milkymist.c b/hw/lm32/milkymist.c
deleted file mode 100644
index bef7855328..0000000000
--- a/hw/lm32/milkymist.c
+++ /dev/null
@@ -1,249 +0,0 @@
-/*
- * QEMU model for the Milkymist board.
- *
- * Copyright (c) 2010 Michael Walle <michael@walle.cc>
- *
- * 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.1 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 "qemu/units.h"
-#include "qemu/error-report.h"
-#include "qemu-common.h"
-#include "qemu/datadir.h"
-#include "cpu.h"
-#include "hw/sysbus.h"
-#include "hw/irq.h"
-#include "hw/block/flash.h"
-#include "sysemu/sysemu.h"
-#include "sysemu/qtest.h"
-#include "sysemu/reset.h"
-#include "hw/boards.h"
-#include "hw/loader.h"
-#include "hw/qdev-properties.h"
-#include "elf.h"
-#include "milkymist-hw.h"
-#include "hw/display/milkymist_tmu2.h"
-#include "hw/sd/sd.h"
-#include "lm32.h"
-#include "qemu/cutils.h"
-
-#define BIOS_FILENAME "mmone-bios.bin"
-#define BIOS_OFFSET 0x00860000
-#define BIOS_SIZE (512 * KiB)
-#define KERNEL_LOAD_ADDR 0x40000000
-
-typedef struct {
- LM32CPU *cpu;
- hwaddr bootstrap_pc;
- hwaddr flash_base;
- hwaddr initrd_base;
- size_t initrd_size;
- hwaddr cmdline_base;
-} ResetInfo;
-
-static void cpu_irq_handler(void *opaque, int irq, int level)
-{
- LM32CPU *cpu = opaque;
- CPUState *cs = CPU(cpu);
-
- if (level) {
- cpu_interrupt(cs, CPU_INTERRUPT_HARD);
- } else {
- cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD);
- }
-}
-
-static void main_cpu_reset(void *opaque)
-{
- ResetInfo *reset_info = opaque;
- CPULM32State *env = &reset_info->cpu->env;
-
- cpu_reset(CPU(reset_info->cpu));
-
- /* init defaults */
- env->pc = reset_info->bootstrap_pc;
- env->regs[R_R1] = reset_info->cmdline_base;
- env->regs[R_R2] = reset_info->initrd_base;
- env->regs[R_R3] = reset_info->initrd_base + reset_info->initrd_size;
- env->eba = reset_info->flash_base;
- env->deba = reset_info->flash_base;
-}
-
-static DeviceState *milkymist_memcard_create(hwaddr base)
-{
- DeviceState *dev;
- DriveInfo *dinfo;
-
- dev = qdev_new("milkymist-memcard");
- sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
- sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, base);
-
- dinfo = drive_get_next(IF_SD);
- if (dinfo) {
- DeviceState *card;
-
- card = qdev_new(TYPE_SD_CARD);
- qdev_prop_set_drive_err(card, "drive", blk_by_legacy_dinfo(dinfo),
- &error_fatal);
- qdev_realize_and_unref(card, qdev_get_child_bus(dev, "sd-bus"),
- &error_fatal);
- }
-
- return dev;
-}
-
-static void
-milkymist_init(MachineState *machine)
-{
- MachineClass *mc = MACHINE_GET_CLASS(machine);
- const char *bios_name = machine->firmware ?: BIOS_FILENAME;
- const char *kernel_filename = machine->kernel_filename;
- const char *kernel_cmdline = machine->kernel_cmdline;
- const char *initrd_filename = machine->initrd_filename;
- LM32CPU *cpu;
- CPULM32State *env;
- int kernel_size;
- DriveInfo *dinfo;
- MemoryRegion *address_space_mem = get_system_memory();
- qemu_irq irq[32];
- int i;
- char *bios_filename;
- ResetInfo *reset_info;
-
- if (machine->ram_size != mc->default_ram_size) {
- char *sz = size_to_str(mc->default_ram_size);
- error_report("Invalid RAM size, should be %s", sz);
- g_free(sz);
- exit(EXIT_FAILURE);
- }
-
- /* memory map */
- hwaddr flash_base = 0x00000000;
- size_t flash_sector_size = 128 * KiB;
- size_t flash_size = 32 * MiB;
- hwaddr sdram_base = 0x40000000;
-
- hwaddr initrd_base = sdram_base + 0x1002000;
- hwaddr cmdline_base = sdram_base + 0x1000000;
- size_t initrd_max = machine->ram_size - 0x1002000;
-
- reset_info = g_malloc0(sizeof(ResetInfo));
-
- cpu = LM32_CPU(cpu_create(machine->cpu_type));
-
- env = &cpu->env;
- reset_info->cpu = cpu;
-
- cpu_lm32_set_phys_msb_ignore(env, 1);
-
- memory_region_add_subregion(address_space_mem, sdram_base, machine->ram);
-
- dinfo = drive_get(IF_PFLASH, 0, 0);
- /* Numonyx JS28F256J3F105 */
- pflash_cfi01_register(flash_base, "milkymist.flash", flash_size,
- dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
- flash_sector_size, 2, 0x00, 0x89, 0x00, 0x1d, 1);
-
- /* create irq lines */
- env->pic_state = lm32_pic_init(qemu_allocate_irq(cpu_irq_handler, cpu, 0));
- for (i = 0; i < 32; i++) {
- irq[i] = qdev_get_gpio_in(env->pic_state, i);
- }
-
- /* load bios rom */
- bios_filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
-
- if (bios_filename) {
- if (load_image_targphys(bios_filename, BIOS_OFFSET, BIOS_SIZE) < 0) {
- error_report("could not load bios '%s'", bios_filename);
- exit(1);
- }
- }
-
- reset_info->bootstrap_pc = BIOS_OFFSET;
-
- /* if no kernel is given no valid bios rom is a fatal error */
- if (!kernel_filename && !dinfo && !bios_filename && !qtest_enabled()) {
- error_report("could not load Milkymist One bios '%s'", bios_name);
- exit(1);
- }
- g_free(bios_filename);
-
- milkymist_uart_create(0x60000000, irq[0], serial_hd(0));
- milkymist_sysctl_create(0x60001000, irq[1], irq[2], irq[3],
- 80000000, 0x10014d31, 0x0000041f, 0x00000001);
- milkymist_hpdmc_create(0x60002000);
- milkymist_vgafb_create(0x60003000, 0x40000000, 0x0fffffff);
- milkymist_memcard_create(0x60004000);
- milkymist_ac97_create(0x60005000, irq[4], irq[5], irq[6], irq[7]);
- milkymist_pfpu_create(0x60006000, irq[8]);
- if (machine->enable_graphics) {
- milkymist_tmu2_create(0x60007000, irq[9]);
- }
- milkymist_minimac2_create(0x60008000, 0x30000000, irq[10], irq[11]);
- milkymist_softusb_create(0x6000f000, irq[15],
- 0x20000000, 0x1000, 0x20020000, 0x2000);
-
- /* make sure juart isn't the first chardev */
- env->juart_state = lm32_juart_init(serial_hd(1));
-
- if (kernel_filename) {
- uint64_t entry;
-
- /* Boots a kernel elf binary. */
- kernel_size = load_elf(kernel_filename, NULL, NULL, NULL,
- &entry, NULL, NULL, NULL,
- 1, EM_LATTICEMICO32, 0, 0);
- reset_info->bootstrap_pc = entry;
-
- if (kernel_size < 0) {
- kernel_size = load_image_targphys(kernel_filename, sdram_base,
- machine->ram_size);
- reset_info->bootstrap_pc = sdram_base;
- }
-
- if (kernel_size < 0) {
- error_report("could not load kernel '%s'", kernel_filename);
- exit(1);
- }
- }
-
- if (kernel_cmdline && strlen(kernel_cmdline)) {
- pstrcpy_targphys("cmdline", cmdline_base, TARGET_PAGE_SIZE,
- kernel_cmdline);
- reset_info->cmdline_base = (uint32_t)cmdline_base;
- }
-
- if (initrd_filename) {
- size_t initrd_size;
- initrd_size = load_image_targphys(initrd_filename, initrd_base,
- initrd_max);
- reset_info->initrd_base = (uint32_t)initrd_base;
- reset_info->initrd_size = (uint32_t)initrd_size;
- }
-
- qemu_register_reset(main_cpu_reset, reset_info);
-}
-
-static void milkymist_machine_init(MachineClass *mc)
-{
- mc->desc = "Milkymist One";
- mc->init = milkymist_init;
- mc->default_cpu_type = LM32_CPU_TYPE_NAME("lm32-full");
- mc->default_ram_size = 128 * MiB;
- mc->default_ram_id = "milkymist.sdram";
-}
-
-DEFINE_MACHINE("milkymist", milkymist_machine_init)
diff --git a/hw/mem/pc-dimm.c b/hw/mem/pc-dimm.c
index 12b655eda8..a3a2560301 100644
--- a/hw/mem/pc-dimm.c
+++ b/hw/mem/pc-dimm.c
@@ -34,6 +34,16 @@
static int pc_dimm_get_free_slot(const int *hint, int max_slots, Error **errp);
+static MemoryRegion *pc_dimm_get_memory_region(PCDIMMDevice *dimm, Error **errp)
+{
+ if (!dimm->hostmem) {
+ error_setg(errp, "'" PC_DIMM_MEMDEV_PROP "' property must be set");
+ return NULL;
+ }
+
+ return host_memory_backend_get_memory(dimm->hostmem);
+}
+
void pc_dimm_pre_plug(PCDIMMDevice *dimm, MachineState *machine,
const uint64_t *legacy_align, Error **errp)
{
@@ -66,9 +76,8 @@ void pc_dimm_pre_plug(PCDIMMDevice *dimm, MachineState *machine,
void pc_dimm_plug(PCDIMMDevice *dimm, MachineState *machine)
{
- PCDIMMDeviceClass *ddc = PC_DIMM_GET_CLASS(dimm);
- MemoryRegion *vmstate_mr = ddc->get_vmstate_memory_region(dimm,
- &error_abort);
+ MemoryRegion *vmstate_mr = pc_dimm_get_memory_region(dimm,
+ &error_abort);
memory_device_plug(MEMORY_DEVICE(dimm), machine);
vmstate_register_ram(vmstate_mr, DEVICE(dimm));
@@ -76,9 +85,8 @@ void pc_dimm_plug(PCDIMMDevice *dimm, MachineState *machine)
void pc_dimm_unplug(PCDIMMDevice *dimm, MachineState *machine)
{
- PCDIMMDeviceClass *ddc = PC_DIMM_GET_CLASS(dimm);
- MemoryRegion *vmstate_mr = ddc->get_vmstate_memory_region(dimm,
- &error_abort);
+ MemoryRegion *vmstate_mr = pc_dimm_get_memory_region(dimm,
+ &error_abort);
memory_device_unplug(MEMORY_DEVICE(dimm), machine);
vmstate_unregister_ram(vmstate_mr, DEVICE(dimm));
@@ -205,16 +213,6 @@ static void pc_dimm_unrealize(DeviceState *dev)
host_memory_backend_set_mapped(dimm->hostmem, false);
}
-static MemoryRegion *pc_dimm_get_memory_region(PCDIMMDevice *dimm, Error **errp)
-{
- if (!dimm->hostmem) {
- error_setg(errp, "'" PC_DIMM_MEMDEV_PROP "' property must be set");
- return NULL;
- }
-
- return host_memory_backend_get_memory(dimm->hostmem);
-}
-
static uint64_t pc_dimm_md_get_addr(const MemoryDeviceState *md)
{
return object_property_get_uint(OBJECT(md), PC_DIMM_ADDR_PROP,
@@ -266,7 +264,6 @@ static void pc_dimm_md_fill_device_info(const MemoryDeviceState *md,
static void pc_dimm_class_init(ObjectClass *oc, void *data)
{
DeviceClass *dc = DEVICE_CLASS(oc);
- PCDIMMDeviceClass *ddc = PC_DIMM_CLASS(oc);
MemoryDeviceClass *mdc = MEMORY_DEVICE_CLASS(oc);
dc->realize = pc_dimm_realize;
@@ -274,8 +271,6 @@ static void pc_dimm_class_init(ObjectClass *oc, void *data)
device_class_set_props(dc, pc_dimm_properties);
dc->desc = "DIMM memory module";
- ddc->get_vmstate_memory_region = pc_dimm_get_memory_region;
-
mdc->get_addr = pc_dimm_md_get_addr;
mdc->set_addr = pc_dimm_md_set_addr;
/* for a dimm plugged_size == region_size */
diff --git a/hw/meson.build b/hw/meson.build
index 8ba79b1a52..6bdbae0e81 100644
--- a/hw/meson.build
+++ b/hw/meson.build
@@ -47,11 +47,9 @@ subdir('avr')
subdir('cris')
subdir('hppa')
subdir('i386')
-subdir('lm32')
subdir('m68k')
subdir('microblaze')
subdir('mips')
-subdir('moxie')
subdir('nios2')
subdir('openrisc')
subdir('ppc')
@@ -63,5 +61,4 @@ subdir('sh4')
subdir('sparc')
subdir('sparc64')
subdir('tricore')
-subdir('unicore32')
subdir('xtensa')
diff --git a/hw/misc/meson.build b/hw/misc/meson.build
index 1e7b8b064b..66e1648533 100644
--- a/hw/misc/meson.build
+++ b/hw/misc/meson.build
@@ -36,9 +36,6 @@ softmmu_ss.add(when: 'CONFIG_SIFIVE_E_PRCI', if_true: files('sifive_e_prci.c'))
softmmu_ss.add(when: 'CONFIG_SIFIVE_U_OTP', if_true: files('sifive_u_otp.c'))
softmmu_ss.add(when: 'CONFIG_SIFIVE_U_PRCI', if_true: files('sifive_u_prci.c'))
-# PKUnity SoC devices
-softmmu_ss.add(when: 'CONFIG_PUV3', if_true: files('puv3_pm.c'))
-
subdir('macio')
softmmu_ss.add(when: 'CONFIG_IVSHMEM_DEVICE', if_true: files('ivshmem.c'))
@@ -63,7 +60,6 @@ softmmu_ss.add(when: 'CONFIG_IMX', if_true: files(
'imx_ccm.c',
'imx_rngc.c',
))
-softmmu_ss.add(when: 'CONFIG_MILKYMIST', if_true: files('milkymist-hpdmc.c', 'milkymist-pfpu.c'))
softmmu_ss.add(when: 'CONFIG_MAINSTONE', if_true: files('mst_fpga.c'))
softmmu_ss.add(when: 'CONFIG_NPCM7XX', if_true: files(
'npcm7xx_clk.c',
diff --git a/hw/misc/milkymist-hpdmc.c b/hw/misc/milkymist-hpdmc.c
deleted file mode 100644
index 09a3875f02..0000000000
--- a/hw/misc/milkymist-hpdmc.c
+++ /dev/null
@@ -1,172 +0,0 @@
-/*
- * QEMU model of the Milkymist High Performance Dynamic Memory Controller.
- *
- * Copyright (c) 2010 Michael Walle <michael@walle.cc>
- *
- * 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.1 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/>.
- *
- *
- * Specification available at:
- * http://milkymist.walle.cc/socdoc/hpdmc.pdf
- */
-
-#include "qemu/osdep.h"
-#include "hw/sysbus.h"
-#include "migration/vmstate.h"
-#include "trace.h"
-#include "qemu/error-report.h"
-#include "qemu/module.h"
-#include "qom/object.h"
-
-enum {
- R_SYSTEM = 0,
- R_BYPASS,
- R_TIMING,
- R_IODELAY,
- R_MAX
-};
-
-enum {
- IODELAY_DQSDELAY_RDY = (1<<5),
- IODELAY_PLL1_LOCKED = (1<<6),
- IODELAY_PLL2_LOCKED = (1<<7),
-};
-
-#define TYPE_MILKYMIST_HPDMC "milkymist-hpdmc"
-OBJECT_DECLARE_SIMPLE_TYPE(MilkymistHpdmcState, MILKYMIST_HPDMC)
-
-struct MilkymistHpdmcState {
- SysBusDevice parent_obj;
-
- MemoryRegion regs_region;
-
- uint32_t regs[R_MAX];
-};
-
-static uint64_t hpdmc_read(void *opaque, hwaddr addr,
- unsigned size)
-{
- MilkymistHpdmcState *s = opaque;
- uint32_t r = 0;
-
- addr >>= 2;
- switch (addr) {
- case R_SYSTEM:
- case R_BYPASS:
- case R_TIMING:
- case R_IODELAY:
- r = s->regs[addr];
- break;
-
- default:
- error_report("milkymist_hpdmc: read access to unknown register 0x"
- TARGET_FMT_plx, addr << 2);
- break;
- }
-
- trace_milkymist_hpdmc_memory_read(addr << 2, r);
-
- return r;
-}
-
-static void hpdmc_write(void *opaque, hwaddr addr, uint64_t value,
- unsigned size)
-{
- MilkymistHpdmcState *s = opaque;
-
- trace_milkymist_hpdmc_memory_write(addr, value);
-
- addr >>= 2;
- switch (addr) {
- case R_SYSTEM:
- case R_BYPASS:
- case R_TIMING:
- s->regs[addr] = value;
- break;
- case R_IODELAY:
- /* ignore writes */
- break;
-
- default:
- error_report("milkymist_hpdmc: write access to unknown register 0x"
- TARGET_FMT_plx, addr << 2);
- break;
- }
-}
-
-static const MemoryRegionOps hpdmc_mmio_ops = {
- .read = hpdmc_read,
- .write = hpdmc_write,
- .valid = {
- .min_access_size = 4,
- .max_access_size = 4,
- },
- .endianness = DEVICE_NATIVE_ENDIAN,
-};
-
-static void milkymist_hpdmc_reset(DeviceState *d)
-{
- MilkymistHpdmcState *s = MILKYMIST_HPDMC(d);
- int i;
-
- for (i = 0; i < R_MAX; i++) {
- s->regs[i] = 0;
- }
-
- /* defaults */
- s->regs[R_IODELAY] = IODELAY_DQSDELAY_RDY | IODELAY_PLL1_LOCKED
- | IODELAY_PLL2_LOCKED;
-}
-
-static void milkymist_hpdmc_realize(DeviceState *dev, Error **errp)
-{
- MilkymistHpdmcState *s = MILKYMIST_HPDMC(dev);
-
- memory_region_init_io(&s->regs_region, OBJECT(dev), &hpdmc_mmio_ops, s,
- "milkymist-hpdmc", R_MAX * 4);
- sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->regs_region);
-}
-
-static const VMStateDescription vmstate_milkymist_hpdmc = {
- .name = "milkymist-hpdmc",
- .version_id = 1,
- .minimum_version_id = 1,
- .fields = (VMStateField[]) {
- VMSTATE_UINT32_ARRAY(regs, MilkymistHpdmcState, R_MAX),
- VMSTATE_END_OF_LIST()
- }
-};
-
-static void milkymist_hpdmc_class_init(ObjectClass *klass, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(klass);
-
- dc->realize = milkymist_hpdmc_realize;
- dc->reset = milkymist_hpdmc_reset;
- dc->vmsd = &vmstate_milkymist_hpdmc;
-}
-
-static const TypeInfo milkymist_hpdmc_info = {
- .name = TYPE_MILKYMIST_HPDMC,
- .parent = TYPE_SYS_BUS_DEVICE,
- .instance_size = sizeof(MilkymistHpdmcState),
- .class_init = milkymist_hpdmc_class_init,
-};
-
-static void milkymist_hpdmc_register_types(void)
-{
- type_register_static(&milkymist_hpdmc_info);
-}
-
-type_init(milkymist_hpdmc_register_types)
diff --git a/hw/misc/milkymist-pfpu.c b/hw/misc/milkymist-pfpu.c
deleted file mode 100644
index e4ee209c10..0000000000
--- a/hw/misc/milkymist-pfpu.c
+++ /dev/null
@@ -1,548 +0,0 @@
-/*
- * QEMU model of the Milkymist programmable FPU.
- *
- * Copyright (c) 2010 Michael Walle <michael@walle.cc>
- *
- * 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.1 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/>.
- *
- *
- * Specification available at:
- * http://milkymist.walle.cc/socdoc/pfpu.pdf
- *
- */
-
-#include "qemu/osdep.h"
-#include "hw/irq.h"
-#include "hw/sysbus.h"
-#include "migration/vmstate.h"
-#include "trace.h"
-#include "qemu/log.h"
-#include "qemu/module.h"
-#include "qemu/error-report.h"
-#include <math.h>
-#include "qom/object.h"
-
-/* #define TRACE_EXEC */
-
-#ifdef TRACE_EXEC
-# define D_EXEC(x) x
-#else
-# define D_EXEC(x)
-#endif
-
-enum {
- R_CTL = 0,
- R_MESHBASE,
- R_HMESHLAST,
- R_VMESHLAST,
- R_CODEPAGE,
- R_VERTICES,
- R_COLLISIONS,
- R_STRAYWRITES,
- R_LASTDMA,
- R_PC,
- R_DREGBASE,
- R_CODEBASE,
- R_MAX
-};
-
-enum {
- CTL_START_BUSY = (1<<0),
-};
-
-enum {
- OP_NOP = 0,
- OP_FADD,
- OP_FSUB,
- OP_FMUL,
- OP_FABS,
- OP_F2I,
- OP_I2F,
- OP_VECTOUT,
- OP_SIN,
- OP_COS,
- OP_ABOVE,
- OP_EQUAL,
- OP_COPY,
- OP_IF,
- OP_TSIGN,
- OP_QUAKE,
-};
-
-enum {
- GPR_X = 0,
- GPR_Y = 1,
- GPR_FLAGS = 2,
-};
-
-enum {
- LATENCY_FADD = 5,
- LATENCY_FSUB = 5,
- LATENCY_FMUL = 7,
- LATENCY_FABS = 2,
- LATENCY_F2I = 2,
- LATENCY_I2F = 3,
- LATENCY_VECTOUT = 0,
- LATENCY_SIN = 4,
- LATENCY_COS = 4,
- LATENCY_ABOVE = 2,
- LATENCY_EQUAL = 2,
- LATENCY_COPY = 2,
- LATENCY_IF = 2,
- LATENCY_TSIGN = 2,
- LATENCY_QUAKE = 2,
- MAX_LATENCY = 7
-};
-
-#define GPR_BEGIN 0x100
-#define GPR_END 0x17f
-#define MICROCODE_BEGIN 0x200
-#define MICROCODE_END 0x3ff
-#define MICROCODE_WORDS 2048
-
-#define REINTERPRET_CAST(type, val) (*((type *)&(val)))
-
-#ifdef TRACE_EXEC
-static const char *opcode_to_str[] = {
- "NOP", "FADD", "FSUB", "FMUL", "FABS", "F2I", "I2F", "VECTOUT",
- "SIN", "COS", "ABOVE", "EQUAL", "COPY", "IF", "TSIGN", "QUAKE",
-};
-#endif
-
-#define TYPE_MILKYMIST_PFPU "milkymist-pfpu"
-OBJECT_DECLARE_SIMPLE_TYPE(MilkymistPFPUState, MILKYMIST_PFPU)
-
-struct MilkymistPFPUState {
- SysBusDevice parent_obj;
-
- MemoryRegion regs_region;
- Chardev *chr;
- qemu_irq irq;
-
- uint32_t regs[R_MAX];
- uint32_t gp_regs[128];
- uint32_t microcode[MICROCODE_WORDS];
-
- int output_queue_pos;
- uint32_t output_queue[MAX_LATENCY];
-};
-
-static inline uint32_t
-get_dma_address(uint32_t base, uint32_t x, uint32_t y)
-{
- return base + 8 * (128 * y + x);
-}
-
-static inline void
-output_queue_insert(MilkymistPFPUState *s, uint32_t val, int pos)
-{
- s->output_queue[(s->output_queue_pos + pos) % MAX_LATENCY] = val;
-}
-
-static inline uint32_t
-output_queue_remove(MilkymistPFPUState *s)
-{
- return s->output_queue[s->output_queue_pos];
-}
-
-static inline void
-output_queue_advance(MilkymistPFPUState *s)
-{
- s->output_queue[s->output_queue_pos] = 0;
- s->output_queue_pos = (s->output_queue_pos + 1) % MAX_LATENCY;
-}
-
-static int pfpu_decode_insn(MilkymistPFPUState *s)
-{
- uint32_t pc = s->regs[R_PC];
- uint32_t insn = s->microcode[pc];
- uint32_t reg_a = (insn >> 18) & 0x7f;
- uint32_t reg_b = (insn >> 11) & 0x7f;
- uint32_t op = (insn >> 7) & 0xf;
- uint32_t reg_d = insn & 0x7f;
- uint32_t r = 0;
- int latency = 0;
-
- switch (op) {
- case OP_NOP:
- break;
- case OP_FADD:
- {
- float a = REINTERPRET_CAST(float, s->gp_regs[reg_a]);
- float b = REINTERPRET_CAST(float, s->gp_regs[reg_b]);
- float t = a + b;
- r = REINTERPRET_CAST(uint32_t, t);
- latency = LATENCY_FADD;
- D_EXEC(qemu_log("ADD a=%f b=%f t=%f, r=%08x\n", a, b, t, r));
- } break;
- case OP_FSUB:
- {
- float a = REINTERPRET_CAST(float, s->gp_regs[reg_a]);
- float b = REINTERPRET_CAST(float, s->gp_regs[reg_b]);
- float t = a - b;
- r = REINTERPRET_CAST(uint32_t, t);
- latency = LATENCY_FSUB;
- D_EXEC(qemu_log("SUB a=%f b=%f t=%f, r=%08x\n", a, b, t, r));
- } break;
- case OP_FMUL:
- {
- float a = REINTERPRET_CAST(float, s->gp_regs[reg_a]);
- float b = REINTERPRET_CAST(float, s->gp_regs[reg_b]);
- float t = a * b;
- r = REINTERPRET_CAST(uint32_t, t);
- latency = LATENCY_FMUL;
- D_EXEC(qemu_log("MUL a=%f b=%f t=%f, r=%08x\n", a, b, t, r));
- } break;
- case OP_FABS:
- {
- float a = REINTERPRET_CAST(float, s->gp_regs[reg_a]);
- float t = fabsf(a);
- r = REINTERPRET_CAST(uint32_t, t);
- latency = LATENCY_FABS;
- D_EXEC(qemu_log("ABS a=%f t=%f, r=%08x\n", a, t, r));
- } break;
- case OP_F2I:
- {
- float a = REINTERPRET_CAST(float, s->gp_regs[reg_a]);
- int32_t t = a;
- r = REINTERPRET_CAST(uint32_t, t);
- latency = LATENCY_F2I;
- D_EXEC(qemu_log("F2I a=%f t=%d, r=%08x\n", a, t, r));
- } break;
- case OP_I2F:
- {
- int32_t a = REINTERPRET_CAST(int32_t, s->gp_regs[reg_a]);
- float t = a;
- r = REINTERPRET_CAST(uint32_t, t);
- latency = LATENCY_I2F;
- D_EXEC(qemu_log("I2F a=%08x t=%f, r=%08x\n", a, t, r));
- } break;
- case OP_VECTOUT:
- {
- uint32_t a = cpu_to_be32(s->gp_regs[reg_a]);
- uint32_t b = cpu_to_be32(s->gp_regs[reg_b]);
- hwaddr dma_ptr =
- get_dma_address(s->regs[R_MESHBASE],
- s->gp_regs[GPR_X], s->gp_regs[GPR_Y]);
- cpu_physical_memory_write(dma_ptr, &a, 4);
- cpu_physical_memory_write(dma_ptr + 4, &b, 4);
- s->regs[R_LASTDMA] = dma_ptr + 4;
- D_EXEC(qemu_log("VECTOUT a=%08x b=%08x dma=%08x\n", a, b, dma_ptr));
- trace_milkymist_pfpu_vectout(a, b, dma_ptr);
- } break;
- case OP_SIN:
- {
- int32_t a = REINTERPRET_CAST(int32_t, s->gp_regs[reg_a]);
- float t = sinf(a * (1.0f / (M_PI * 4096.0f)));
- r = REINTERPRET_CAST(uint32_t, t);
- latency = LATENCY_SIN;
- D_EXEC(qemu_log("SIN a=%d t=%f, r=%08x\n", a, t, r));
- } break;
- case OP_COS:
- {
- int32_t a = REINTERPRET_CAST(int32_t, s->gp_regs[reg_a]);
- float t = cosf(a * (1.0f / (M_PI * 4096.0f)));
- r = REINTERPRET_CAST(uint32_t, t);
- latency = LATENCY_COS;
- D_EXEC(qemu_log("COS a=%d t=%f, r=%08x\n", a, t, r));
- } break;
- case OP_ABOVE:
- {
- float a = REINTERPRET_CAST(float, s->gp_regs[reg_a]);
- float b = REINTERPRET_CAST(float, s->gp_regs[reg_b]);
- float t = (a > b) ? 1.0f : 0.0f;
- r = REINTERPRET_CAST(uint32_t, t);
- latency = LATENCY_ABOVE;
- D_EXEC(qemu_log("ABOVE a=%f b=%f t=%f, r=%08x\n", a, b, t, r));
- } break;
- case OP_EQUAL:
- {
- float a = REINTERPRET_CAST(float, s->gp_regs[reg_a]);
- float b = REINTERPRET_CAST(float, s->gp_regs[reg_b]);
- float t = (a == b) ? 1.0f : 0.0f;
- r = REINTERPRET_CAST(uint32_t, t);
- latency = LATENCY_EQUAL;
- D_EXEC(qemu_log("EQUAL a=%f b=%f t=%f, r=%08x\n", a, b, t, r));
- } break;
- case OP_COPY:
- {
- r = s->gp_regs[reg_a];
- latency = LATENCY_COPY;
- D_EXEC(qemu_log("COPY"));
- } break;
- case OP_IF:
- {
- float a = REINTERPRET_CAST(float, s->gp_regs[reg_a]);
- float b = REINTERPRET_CAST(float, s->gp_regs[reg_b]);
- uint32_t f = s->gp_regs[GPR_FLAGS];
- float t = (f != 0) ? a : b;
- r = REINTERPRET_CAST(uint32_t, t);
- latency = LATENCY_IF;
- D_EXEC(qemu_log("IF f=%u a=%f b=%f t=%f, r=%08x\n", f, a, b, t, r));
- } break;
- case OP_TSIGN:
- {
- float a = REINTERPRET_CAST(float, s->gp_regs[reg_a]);
- float b = REINTERPRET_CAST(float, s->gp_regs[reg_b]);
- float t = (b < 0) ? -a : a;
- r = REINTERPRET_CAST(uint32_t, t);
- latency = LATENCY_TSIGN;
- D_EXEC(qemu_log("TSIGN a=%f b=%f t=%f, r=%08x\n", a, b, t, r));
- } break;
- case OP_QUAKE:
- {
- uint32_t a = s->gp_regs[reg_a];
- r = 0x5f3759df - (a >> 1);
- latency = LATENCY_QUAKE;
- D_EXEC(qemu_log("QUAKE a=%d r=%08x\n", a, r));
- } break;
-
- default:
- error_report("milkymist_pfpu: unknown opcode %d", op);
- break;
- }
-
- if (!reg_d) {
- D_EXEC(qemu_log("%04d %8s R%03d, R%03d <L=%d, E=%04d>\n",
- s->regs[R_PC], opcode_to_str[op], reg_a, reg_b, latency,
- s->regs[R_PC] + latency));
- } else {
- D_EXEC(qemu_log("%04d %8s R%03d, R%03d <L=%d, E=%04d> -> R%03d\n",
- s->regs[R_PC], opcode_to_str[op], reg_a, reg_b, latency,
- s->regs[R_PC] + latency, reg_d));
- }
-
- if (op == OP_VECTOUT) {
- return 0;
- }
-
- /* store output for this cycle */
- if (reg_d) {
- uint32_t val = output_queue_remove(s);
- D_EXEC(qemu_log("R%03d <- 0x%08x\n", reg_d, val));
- s->gp_regs[reg_d] = val;
- }
-
- output_queue_advance(s);
-
- /* store op output */
- if (op != OP_NOP) {
- output_queue_insert(s, r, latency-1);
- }
-
- /* advance PC */
- s->regs[R_PC]++;
-
- return 1;
-};
-
-static void pfpu_start(MilkymistPFPUState *s)
-{
- int x, y;
- int i;
-
- for (y = 0; y <= s->regs[R_VMESHLAST]; y++) {
- for (x = 0; x <= s->regs[R_HMESHLAST]; x++) {
- D_EXEC(qemu_log("\nprocessing x=%d y=%d\n", x, y));
-
- /* set current position */
- s->gp_regs[GPR_X] = x;
- s->gp_regs[GPR_Y] = y;
-
- /* run microcode on this position */
- i = 0;
- while (pfpu_decode_insn(s)) {
- /* decode at most MICROCODE_WORDS instructions */
- if (++i >= MICROCODE_WORDS) {
- error_report("milkymist_pfpu: too many instructions "
- "executed in microcode. No VECTOUT?");
- break;
- }
- }
-
- /* reset pc for next run */
- s->regs[R_PC] = 0;
- }
- }
-
- s->regs[R_VERTICES] = x * y;
-
- trace_milkymist_pfpu_pulse_irq();
- qemu_irq_pulse(s->irq);
-}
-
-static inline int get_microcode_address(MilkymistPFPUState *s, uint32_t addr)
-{
- return (512 * s->regs[R_CODEPAGE]) + addr - MICROCODE_BEGIN;
-}
-
-static uint64_t pfpu_read(void *opaque, hwaddr addr,
- unsigned size)
-{
- MilkymistPFPUState *s = opaque;
- uint32_t r = 0;
-
- addr >>= 2;
- switch (addr) {
- case R_CTL:
- case R_MESHBASE:
- case R_HMESHLAST:
- case R_VMESHLAST:
- case R_CODEPAGE:
- case R_VERTICES:
- case R_COLLISIONS:
- case R_STRAYWRITES:
- case R_LASTDMA:
- case R_PC:
- case R_DREGBASE:
- case R_CODEBASE:
- r = s->regs[addr];
- break;
- case GPR_BEGIN ... GPR_END:
- r = s->gp_regs[addr - GPR_BEGIN];
- break;
- case MICROCODE_BEGIN ... MICROCODE_END:
- r = s->microcode[get_microcode_address(s, addr)];
- break;
-
- default:
- error_report("milkymist_pfpu: read access to unknown register 0x"
- TARGET_FMT_plx, addr << 2);
- break;
- }
-
- trace_milkymist_pfpu_memory_read(addr << 2, r);
-
- return r;
-}
-
-static void pfpu_write(void *opaque, hwaddr addr, uint64_t value,
- unsigned size)
-{
- MilkymistPFPUState *s = opaque;
-
- trace_milkymist_pfpu_memory_write(addr, value);
-
- addr >>= 2;
- switch (addr) {
- case R_CTL:
- if (value & CTL_START_BUSY) {
- pfpu_start(s);
- }
- break;
- case R_MESHBASE:
- case R_HMESHLAST:
- case R_VMESHLAST:
- case R_CODEPAGE:
- case R_VERTICES:
- case R_COLLISIONS:
- case R_STRAYWRITES:
- case R_LASTDMA:
- case R_PC:
- case R_DREGBASE:
- case R_CODEBASE:
- s->regs[addr] = value;
- break;
- case GPR_BEGIN ... GPR_END:
- s->gp_regs[addr - GPR_BEGIN] = value;
- break;
- case MICROCODE_BEGIN ... MICROCODE_END:
- s->microcode[get_microcode_address(s, addr)] = value;
- break;
-
- default:
- error_report("milkymist_pfpu: write access to unknown register 0x"
- TARGET_FMT_plx, addr << 2);
- break;
- }
-}
-
-static const MemoryRegionOps pfpu_mmio_ops = {
- .read = pfpu_read,
- .write = pfpu_write,
- .valid = {
- .min_access_size = 4,
- .max_access_size = 4,
- },
- .endianness = DEVICE_NATIVE_ENDIAN,
-};
-
-static void milkymist_pfpu_reset(DeviceState *d)
-{
- MilkymistPFPUState *s = MILKYMIST_PFPU(d);
- int i;
-
- for (i = 0; i < R_MAX; i++) {
- s->regs[i] = 0;
- }
- for (i = 0; i < 128; i++) {
- s->gp_regs[i] = 0;
- }
- for (i = 0; i < MICROCODE_WORDS; i++) {
- s->microcode[i] = 0;
- }
- s->output_queue_pos = 0;
- for (i = 0; i < MAX_LATENCY; i++) {
- s->output_queue[i] = 0;
- }
-}
-
-static void milkymist_pfpu_realize(DeviceState *dev, Error **errp)
-{
- MilkymistPFPUState *s = MILKYMIST_PFPU(dev);
- SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
-
- sysbus_init_irq(sbd, &s->irq);
-
- memory_region_init_io(&s->regs_region, OBJECT(dev), &pfpu_mmio_ops, s,
- "milkymist-pfpu", MICROCODE_END * 4);
- sysbus_init_mmio(sbd, &s->regs_region);
-}
-
-static const VMStateDescription vmstate_milkymist_pfpu = {
- .name = "milkymist-pfpu",
- .version_id = 1,
- .minimum_version_id = 1,
- .fields = (VMStateField[]) {
- VMSTATE_UINT32_ARRAY(regs, MilkymistPFPUState, R_MAX),
- VMSTATE_UINT32_ARRAY(gp_regs, MilkymistPFPUState, 128),
- VMSTATE_UINT32_ARRAY(microcode, MilkymistPFPUState, MICROCODE_WORDS),
- VMSTATE_INT32(output_queue_pos, MilkymistPFPUState),
- VMSTATE_UINT32_ARRAY(output_queue, MilkymistPFPUState, MAX_LATENCY),
- VMSTATE_END_OF_LIST()
- }
-};
-
-static void milkymist_pfpu_class_init(ObjectClass *klass, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(klass);
-
- dc->realize = milkymist_pfpu_realize;
- dc->reset = milkymist_pfpu_reset;
- dc->vmsd = &vmstate_milkymist_pfpu;
-}
-
-static const TypeInfo milkymist_pfpu_info = {
- .name = TYPE_MILKYMIST_PFPU,
- .parent = TYPE_SYS_BUS_DEVICE,
- .instance_size = sizeof(MilkymistPFPUState),
- .class_init = milkymist_pfpu_class_init,
-};
-
-static void milkymist_pfpu_register_types(void)
-{
- type_register_static(&milkymist_pfpu_info);
-}
-
-type_init(milkymist_pfpu_register_types)
diff --git a/hw/misc/puv3_pm.c b/hw/misc/puv3_pm.c
deleted file mode 100644
index 676c23f7db..0000000000
--- a/hw/misc/puv3_pm.c
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- * Power Management device simulation in PKUnity SoC
- *
- * Copyright (C) 2010-2012 Guan Xuetao
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation, or any later version.
- * See the COPYING file in the top-level directory.
- */
-
-#include "qemu/osdep.h"
-#include "hw/sysbus.h"
-#include "qom/object.h"
-
-#undef DEBUG_PUV3
-#include "hw/unicore32/puv3.h"
-#include "qemu/module.h"
-#include "qemu/log.h"
-
-#define TYPE_PUV3_PM "puv3_pm"
-OBJECT_DECLARE_SIMPLE_TYPE(PUV3PMState, PUV3_PM)
-
-struct PUV3PMState {
- SysBusDevice parent_obj;
-
- MemoryRegion iomem;
-
- uint32_t reg_PMCR;
- uint32_t reg_PCGR;
- uint32_t reg_PLL_SYS_CFG;
- uint32_t reg_PLL_DDR_CFG;
- uint32_t reg_PLL_VGA_CFG;
- uint32_t reg_DIVCFG;
-};
-
-static uint64_t puv3_pm_read(void *opaque, hwaddr offset,
- unsigned size)
-{
- PUV3PMState *s = opaque;
- uint32_t ret = 0;
-
- switch (offset) {
- case 0x14:
- ret = s->reg_PCGR;
- break;
- case 0x18:
- ret = s->reg_PLL_SYS_CFG;
- break;
- case 0x1c:
- ret = s->reg_PLL_DDR_CFG;
- break;
- case 0x20:
- ret = s->reg_PLL_VGA_CFG;
- break;
- case 0x24:
- ret = s->reg_DIVCFG;
- break;
- case 0x28: /* PLL SYS STATUS */
- ret = 0x00002401;
- break;
- case 0x2c: /* PLL DDR STATUS */
- ret = 0x00100c00;
- break;
- case 0x30: /* PLL VGA STATUS */
- ret = 0x00003801;
- break;
- case 0x34: /* DIV STATUS */
- ret = 0x22f52015;
- break;
- case 0x38: /* SW RESET */
- ret = 0x0;
- break;
- case 0x44: /* PLL DFC DONE */
- ret = 0x7;
- break;
- default:
- qemu_log_mask(LOG_GUEST_ERROR,
- "%s: Bad read offset 0x%"HWADDR_PRIx"\n",
- __func__, offset);
- }
- DPRINTF("offset 0x%x, value 0x%x\n", offset, ret);
-
- return ret;
-}
-
-static void puv3_pm_write(void *opaque, hwaddr offset,
- uint64_t value, unsigned size)
-{
- PUV3PMState *s = opaque;
-
- switch (offset) {
- case 0x0:
- s->reg_PMCR = value;
- break;
- case 0x14:
- s->reg_PCGR = value;
- break;
- case 0x18:
- s->reg_PLL_SYS_CFG = value;
- break;
- case 0x1c:
- s->reg_PLL_DDR_CFG = value;
- break;
- case 0x20:
- s->reg_PLL_VGA_CFG = value;
- break;
- case 0x24:
- case 0x38:
- break;
- default:
- qemu_log_mask(LOG_GUEST_ERROR,
- "%s: Bad write offset 0x%"HWADDR_PRIx"\n",
- __func__, offset);
- }
- DPRINTF("offset 0x%x, value 0x%x\n", offset, value);
-}
-
-static const MemoryRegionOps puv3_pm_ops = {
- .read = puv3_pm_read,
- .write = puv3_pm_write,
- .impl = {
- .min_access_size = 4,
- .max_access_size = 4,
- },
- .endianness = DEVICE_NATIVE_ENDIAN,
-};
-
-static void puv3_pm_realize(DeviceState *dev, Error **errp)
-{
- PUV3PMState *s = PUV3_PM(dev);
-
- s->reg_PCGR = 0x0;
-
- memory_region_init_io(&s->iomem, OBJECT(s), &puv3_pm_ops, s, "puv3_pm",
- PUV3_REGS_OFFSET);
- sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->iomem);
-}
-
-static void puv3_pm_class_init(ObjectClass *klass, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(klass);
-
- dc->realize = puv3_pm_realize;
-}
-
-static const TypeInfo puv3_pm_info = {
- .name = TYPE_PUV3_PM,
- .parent = TYPE_SYS_BUS_DEVICE,
- .instance_size = sizeof(PUV3PMState),
- .class_init = puv3_pm_class_init,
-};
-
-static void puv3_pm_register_type(void)
-{
- type_register_static(&puv3_pm_info);
-}
-
-type_init(puv3_pm_register_type)
diff --git a/hw/misc/trace-events b/hw/misc/trace-events
index d0a89eb059..0752217636 100644
--- a/hw/misc/trace-events
+++ b/hw/misc/trace-events
@@ -67,16 +67,6 @@ slavio_sysctrl_mem_readl(uint32_t ret) "Read system control 0x%08x"
slavio_led_mem_writew(uint32_t val) "Write diagnostic LED 0x%04x"
slavio_led_mem_readw(uint32_t ret) "Read diagnostic LED 0x%04x"
-# milkymist-hpdmc.c
-milkymist_hpdmc_memory_read(uint32_t addr, uint32_t value) "addr=0x%08x value=0x%08x"
-milkymist_hpdmc_memory_write(uint32_t addr, uint32_t value) "addr=0x%08x value=0x%08x"
-
-# milkymist-pfpu.c
-milkymist_pfpu_memory_read(uint32_t addr, uint32_t value) "addr 0x%08x value 0x%08x"
-milkymist_pfpu_memory_write(uint32_t addr, uint32_t value) "addr 0x%08x value 0x%08x"
-milkymist_pfpu_vectout(uint32_t a, uint32_t b, uint32_t dma_ptr) "a 0x%08x b 0x%08x dma_ptr 0x%08x"
-milkymist_pfpu_pulse_irq(void) "Pulse IRQ"
-
# aspeed_scu.c
aspeed_scu_write(uint64_t offset, unsigned size, uint32_t data) "To 0x%" PRIx64 " of size %u: 0x%" PRIx32
diff --git a/hw/moxie/Kconfig b/hw/moxie/Kconfig
deleted file mode 100644
index 3793ef0372..0000000000
--- a/hw/moxie/Kconfig
+++ /dev/null
@@ -1,3 +0,0 @@
-config MOXIESIM
- bool
- select SERIAL
diff --git a/hw/moxie/meson.build b/hw/moxie/meson.build
deleted file mode 100644
index 05a7c2e00f..0000000000
--- a/hw/moxie/meson.build
+++ /dev/null
@@ -1,4 +0,0 @@
-moxie_ss = ss.source_set()
-moxie_ss.add(when: 'CONFIG_MOXIESIM', if_true: files('moxiesim.c'))
-
-hw_arch += {'moxie': moxie_ss}
diff --git a/hw/moxie/moxiesim.c b/hw/moxie/moxiesim.c
deleted file mode 100644
index 3d255d4879..0000000000
--- a/hw/moxie/moxiesim.c
+++ /dev/null
@@ -1,155 +0,0 @@
-/*
- * QEMU/moxiesim emulation
- *
- * Emulates a very simple machine model similar to the one used by the
- * GDB moxie simulator.
- *
- * Copyright (c) 2008, 2009, 2010, 2013 Anthony Green
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#include "qemu/osdep.h"
-#include "qemu/error-report.h"
-#include "qapi/error.h"
-#include "cpu.h"
-#include "net/net.h"
-#include "sysemu/reset.h"
-#include "sysemu/sysemu.h"
-#include "hw/boards.h"
-#include "hw/loader.h"
-#include "hw/char/serial.h"
-#include "elf.h"
-
-#define PHYS_MEM_BASE 0x80000000
-#define FIRMWARE_BASE 0x1000
-#define FIRMWARE_SIZE (128 * 0x1000)
-
-typedef struct {
- uint64_t ram_size;
- const char *kernel_filename;
- const char *kernel_cmdline;
- const char *initrd_filename;
-} LoaderParams;
-
-static void load_kernel(MoxieCPU *cpu, LoaderParams *loader_params)
-{
- uint64_t entry, kernel_high;
- int64_t initrd_size;
- long kernel_size;
- ram_addr_t initrd_offset;
-
- kernel_size = load_elf(loader_params->kernel_filename, NULL, NULL, NULL,
- &entry, NULL, &kernel_high, NULL, 1, EM_MOXIE,
- 0, 0);
-
- if (kernel_size <= 0) {
- error_report("could not load kernel '%s'",
- loader_params->kernel_filename);
- exit(1);
- }
-
- /* load initrd */
- initrd_size = 0;
- initrd_offset = 0;
- if (loader_params->initrd_filename) {
- initrd_size = get_image_size(loader_params->initrd_filename);
- if (initrd_size > 0) {
- initrd_offset = (kernel_high + ~TARGET_PAGE_MASK)
- & TARGET_PAGE_MASK;
- if (initrd_offset + initrd_size > loader_params->ram_size) {
- error_report("memory too small for initial ram disk '%s'",
- loader_params->initrd_filename);
- exit(1);
- }
- initrd_size = load_image_targphys(loader_params->initrd_filename,
- initrd_offset,
- loader_params->ram_size);
- }
- if (initrd_size == (target_ulong)-1) {
- error_report("could not load initial ram disk '%s'",
- loader_params->initrd_filename);
- exit(1);
- }
- }
-}
-
-static void main_cpu_reset(void *opaque)
-{
- MoxieCPU *cpu = opaque;
-
- cpu_reset(CPU(cpu));
-}
-
-static void moxiesim_init(MachineState *machine)
-{
- MoxieCPU *cpu = NULL;
- ram_addr_t ram_size = machine->ram_size;
- const char *kernel_filename = machine->kernel_filename;
- const char *kernel_cmdline = machine->kernel_cmdline;
- const char *initrd_filename = machine->initrd_filename;
- CPUMoxieState *env;
- MemoryRegion *address_space_mem = get_system_memory();
- MemoryRegion *ram = g_new(MemoryRegion, 1);
- MemoryRegion *rom = g_new(MemoryRegion, 1);
- hwaddr ram_base = 0x200000;
- LoaderParams loader_params;
-
- /* Init CPUs. */
- cpu = MOXIE_CPU(cpu_create(machine->cpu_type));
- env = &cpu->env;
-
- qemu_register_reset(main_cpu_reset, cpu);
-
- /* Allocate RAM. */
- memory_region_init_ram(ram, NULL, "moxiesim.ram", ram_size, &error_fatal);
- memory_region_add_subregion(address_space_mem, ram_base, ram);
-
- memory_region_init_ram(rom, NULL, "moxie.rom", FIRMWARE_SIZE, &error_fatal);
- memory_region_add_subregion(get_system_memory(), FIRMWARE_BASE, rom);
-
- if (kernel_filename) {
- loader_params.ram_size = ram_size;
- loader_params.kernel_filename = kernel_filename;
- loader_params.kernel_cmdline = kernel_cmdline;
- loader_params.initrd_filename = initrd_filename;
- load_kernel(cpu, &loader_params);
- }
- if (machine->firmware) {
- if (load_image_targphys(machine->firmware, FIRMWARE_BASE, FIRMWARE_SIZE) < 0) {
- error_report("Failed to load firmware '%s'", machine->firmware);
- }
- }
-
- /* A single 16450 sits at offset 0x3f8. */
- if (serial_hd(0)) {
- serial_mm_init(address_space_mem, 0x3f8, 0, env->irq[4],
- 8000000/16, serial_hd(0), DEVICE_LITTLE_ENDIAN);
- }
-}
-
-static void moxiesim_machine_init(MachineClass *mc)
-{
- mc->desc = "Moxie simulator platform";
- mc->init = moxiesim_init;
- mc->is_default = true;
- mc->default_cpu_type = MOXIE_CPU_TYPE_NAME("MoxieLite");
-}
-
-DEFINE_MACHINE("moxiesim", moxiesim_machine_init)
diff --git a/hw/net/meson.build b/hw/net/meson.build
index af0749c42b..bdf71f1f40 100644
--- a/hw/net/meson.build
+++ b/hw/net/meson.build
@@ -39,7 +39,6 @@ softmmu_ss.add(when: 'CONFIG_NPCM7XX', if_true: files('npcm7xx_emc.c'))
softmmu_ss.add(when: 'CONFIG_ETRAXFS', if_true: files('etraxfs_eth.c'))
softmmu_ss.add(when: 'CONFIG_COLDFIRE', if_true: files('mcf_fec.c'))
-specific_ss.add(when: 'CONFIG_MILKYMIST', if_true: files('milkymist-minimac2.c'))
specific_ss.add(when: 'CONFIG_PSERIES', if_true: files('spapr_llan.c'))
specific_ss.add(when: 'CONFIG_XILINX_ETHLITE', if_true: files('xilinx_ethlite.c'))
diff --git a/hw/net/milkymist-minimac2.c b/hw/net/milkymist-minimac2.c
deleted file mode 100644
index 5826944fd5..0000000000
--- a/hw/net/milkymist-minimac2.c
+++ /dev/null
@@ -1,547 +0,0 @@
-/*
- * QEMU model of the Milkymist minimac2 block.
- *
- * Copyright (c) 2011 Michael Walle <michael@walle.cc>
- *
- * 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.1 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/>.
- *
- *
- * Specification available at:
- * not available yet
- *
- */
-
-#include "qemu/osdep.h"
-#include "qapi/error.h"
-#include "qom/object.h"
-#include "cpu.h" /* FIXME: why does this use TARGET_PAGE_ALIGN? */
-#include "hw/irq.h"
-#include "hw/qdev-properties.h"
-#include "hw/sysbus.h"
-#include "migration/vmstate.h"
-#include "trace.h"
-#include "net/net.h"
-#include "qemu/log.h"
-#include "qemu/module.h"
-#include "qemu/error-report.h"
-
-#include <zlib.h>
-
-enum {
- R_SETUP = 0,
- R_MDIO,
- R_STATE0,
- R_COUNT0,
- R_STATE1,
- R_COUNT1,
- R_TXCOUNT,
- R_MAX
-};
-
-enum {
- SETUP_PHY_RST = (1<<0),
-};
-
-enum {
- MDIO_DO = (1<<0),
- MDIO_DI = (1<<1),
- MDIO_OE = (1<<2),
- MDIO_CLK = (1<<3),
-};
-
-enum {
- STATE_EMPTY = 0,
- STATE_LOADED = 1,
- STATE_PENDING = 2,
-};
-
-enum {
- MDIO_OP_WRITE = 1,
- MDIO_OP_READ = 2,
-};
-
-enum mdio_state {
- MDIO_STATE_IDLE,
- MDIO_STATE_READING,
- MDIO_STATE_WRITING,
-};
-
-enum {
- R_PHY_ID1 = 2,
- R_PHY_ID2 = 3,
- R_PHY_MAX = 32
-};
-
-#define MINIMAC2_MTU 1530
-#define MINIMAC2_BUFFER_SIZE 2048
-
-struct MilkymistMinimac2MdioState {
- int last_clk;
- int count;
- uint32_t data;
- uint16_t data_out;
- int state;
-
- uint8_t phy_addr;
- uint8_t reg_addr;
-};
-typedef struct MilkymistMinimac2MdioState MilkymistMinimac2MdioState;
-
-#define TYPE_MILKYMIST_MINIMAC2 "milkymist-minimac2"
-OBJECT_DECLARE_SIMPLE_TYPE(MilkymistMinimac2State, MILKYMIST_MINIMAC2)
-
-struct MilkymistMinimac2State {
- SysBusDevice parent_obj;
-
- NICState *nic;
- NICConf conf;
- char *phy_model;
- MemoryRegion buffers;
- MemoryRegion regs_region;
-
- qemu_irq rx_irq;
- qemu_irq tx_irq;
-
- uint32_t regs[R_MAX];
-
- MilkymistMinimac2MdioState mdio;
-
- uint16_t phy_regs[R_PHY_MAX];
-
- uint8_t *rx0_buf;
- uint8_t *rx1_buf;
- uint8_t *tx_buf;
-};
-
-static const uint8_t preamble_sfd[] = {
- 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd5
-};
-
-static void minimac2_mdio_write_reg(MilkymistMinimac2State *s,
- uint8_t phy_addr, uint8_t reg_addr, uint16_t value)
-{
- trace_milkymist_minimac2_mdio_write(phy_addr, reg_addr, value);
-
- /* nop */
-}
-
-static uint16_t minimac2_mdio_read_reg(MilkymistMinimac2State *s,
- uint8_t phy_addr, uint8_t reg_addr)
-{
- uint16_t r = s->phy_regs[reg_addr];
-
- trace_milkymist_minimac2_mdio_read(phy_addr, reg_addr, r);
-
- return r;
-}
-
-static void minimac2_update_mdio(MilkymistMinimac2State *s)
-{
- MilkymistMinimac2MdioState *m = &s->mdio;
-
- /* detect rising clk edge */
- if (m->last_clk == 0 && (s->regs[R_MDIO] & MDIO_CLK)) {
- /* shift data in */
- int bit = ((s->regs[R_MDIO] & MDIO_DO)
- && (s->regs[R_MDIO] & MDIO_OE)) ? 1 : 0;
- m->data = (m->data << 1) | bit;
-
- /* check for sync */
- if (m->data == 0xffffffff) {
- m->count = 32;
- }
-
- if (m->count == 16) {
- uint8_t start = (m->data >> 14) & 0x3;
- uint8_t op = (m->data >> 12) & 0x3;
- uint8_t ta = (m->data) & 0x3;
-
- if (start == 1 && op == MDIO_OP_WRITE && ta == 2) {
- m->state = MDIO_STATE_WRITING;
- } else if (start == 1 && op == MDIO_OP_READ && (ta & 1) == 0) {
- m->state = MDIO_STATE_READING;
- } else {
- m->state = MDIO_STATE_IDLE;
- }
-
- if (m->state != MDIO_STATE_IDLE) {
- m->phy_addr = (m->data >> 7) & 0x1f;
- m->reg_addr = (m->data >> 2) & 0x1f;
- }
-
- if (m->state == MDIO_STATE_READING) {
- m->data_out = minimac2_mdio_read_reg(s, m->phy_addr,
- m->reg_addr);
- }
- }
-
- if (m->count < 16 && m->state == MDIO_STATE_READING) {
- int bit = (m->data_out & 0x8000) ? 1 : 0;
- m->data_out <<= 1;
-
- if (bit) {
- s->regs[R_MDIO] |= MDIO_DI;
- } else {
- s->regs[R_MDIO] &= ~MDIO_DI;
- }
- }
-
- if (m->count == 0 && m->state) {
- if (m->state == MDIO_STATE_WRITING) {
- uint16_t data = m->data & 0xffff;
- minimac2_mdio_write_reg(s, m->phy_addr, m->reg_addr, data);
- }
- m->state = MDIO_STATE_IDLE;
- }
- m->count--;
- }
-
- m->last_clk = (s->regs[R_MDIO] & MDIO_CLK) ? 1 : 0;
-}
-
-static size_t assemble_frame(uint8_t *buf, size_t size,
- const uint8_t *payload, size_t payload_size)
-{
- uint32_t crc;
-
- if (size < payload_size + 12) {
- qemu_log_mask(LOG_GUEST_ERROR, "milkymist_minimac2: frame too big "
- "(%zd bytes)\n", payload_size);
- return 0;
- }
-
- /* prepend preamble and sfd */
- memcpy(buf, preamble_sfd, 8);
-
- /* now copy the payload */
- memcpy(buf + 8, payload, payload_size);
-
- /* pad frame if needed */
- if (payload_size < 60) {
- memset(buf + payload_size + 8, 0, 60 - payload_size);
- payload_size = 60;
- }
-
- /* append fcs */
- crc = cpu_to_le32(crc32(0, buf + 8, payload_size));
- memcpy(buf + payload_size + 8, &crc, 4);
-
- return payload_size + 12;
-}
-
-static void minimac2_tx(MilkymistMinimac2State *s)
-{
- uint32_t txcount = s->regs[R_TXCOUNT];
- uint8_t *buf = s->tx_buf;
-
- if (txcount < 64) {
- error_report("milkymist_minimac2: ethernet frame too small (%u < %u)",
- txcount, 64);
- goto err;
- }
-
- if (txcount > MINIMAC2_MTU) {
- error_report("milkymist_minimac2: MTU exceeded (%u > %u)",
- txcount, MINIMAC2_MTU);
- goto err;
- }
-
- if (memcmp(buf, preamble_sfd, 8) != 0) {
- error_report("milkymist_minimac2: frame doesn't contain the preamble "
- "and/or the SFD (%02x %02x %02x %02x %02x %02x %02x %02x)",
- buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7]);
- goto err;
- }
-
- trace_milkymist_minimac2_tx_frame(txcount - 12);
-
- /* send packet, skipping preamble and sfd */
- qemu_send_packet_raw(qemu_get_queue(s->nic), buf + 8, txcount - 12);
-
- s->regs[R_TXCOUNT] = 0;
-
-err:
- trace_milkymist_minimac2_pulse_irq_tx();
- qemu_irq_pulse(s->tx_irq);
-}
-
-static void update_rx_interrupt(MilkymistMinimac2State *s)
-{
- if (s->regs[R_STATE0] == STATE_PENDING
- || s->regs[R_STATE1] == STATE_PENDING) {
- trace_milkymist_minimac2_raise_irq_rx();
- qemu_irq_raise(s->rx_irq);
- } else {
- trace_milkymist_minimac2_lower_irq_rx();
- qemu_irq_lower(s->rx_irq);
- }
-}
-
-static ssize_t minimac2_rx(NetClientState *nc, const uint8_t *buf, size_t size)
-{
- MilkymistMinimac2State *s = qemu_get_nic_opaque(nc);
-
- uint32_t r_count;
- uint32_t r_state;
- uint8_t *rx_buf;
-
- size_t frame_size;
-
- trace_milkymist_minimac2_rx_frame(buf, size);
-
- /* choose appropriate slot */
- if (s->regs[R_STATE0] == STATE_LOADED) {
- r_count = R_COUNT0;
- r_state = R_STATE0;
- rx_buf = s->rx0_buf;
- } else if (s->regs[R_STATE1] == STATE_LOADED) {
- r_count = R_COUNT1;
- r_state = R_STATE1;
- rx_buf = s->rx1_buf;
- } else {
- return 0;
- }
-
- /* assemble frame */
- frame_size = assemble_frame(rx_buf, MINIMAC2_BUFFER_SIZE, buf, size);
-
- if (frame_size == 0) {
- return size;
- }
-
- trace_milkymist_minimac2_rx_transfer(rx_buf, frame_size);
-
- /* update slot */
- s->regs[r_count] = frame_size;
- s->regs[r_state] = STATE_PENDING;
-
- update_rx_interrupt(s);
-
- return size;
-}
-
-static uint64_t
-minimac2_read(void *opaque, hwaddr addr, unsigned size)
-{
- MilkymistMinimac2State *s = opaque;
- uint32_t r = 0;
-
- addr >>= 2;
- switch (addr) {
- case R_SETUP:
- case R_MDIO:
- case R_STATE0:
- case R_COUNT0:
- case R_STATE1:
- case R_COUNT1:
- case R_TXCOUNT:
- r = s->regs[addr];
- break;
-
- default:
- qemu_log_mask(LOG_GUEST_ERROR,
- "milkymist_minimac2_rd%d: 0x%" HWADDR_PRIx "\n",
- size, addr << 2);
- break;
- }
-
- trace_milkymist_minimac2_memory_read(addr << 2, r);
-
- return r;
-}
-
-static int minimac2_can_rx(MilkymistMinimac2State *s)
-{
- if (s->regs[R_STATE0] == STATE_LOADED) {
- return 1;
- }
- if (s->regs[R_STATE1] == STATE_LOADED) {
- return 1;
- }
-
- return 0;
-}
-
-static void
-minimac2_write(void *opaque, hwaddr addr, uint64_t value,
- unsigned size)
-{
- MilkymistMinimac2State *s = opaque;
-
- trace_milkymist_minimac2_memory_write(addr, value);
-
- addr >>= 2;
- switch (addr) {
- case R_MDIO:
- {
- /* MDIO_DI is read only */
- int mdio_di = (s->regs[R_MDIO] & MDIO_DI);
- s->regs[R_MDIO] = value;
- if (mdio_di) {
- s->regs[R_MDIO] |= mdio_di;
- } else {
- s->regs[R_MDIO] &= ~mdio_di;
- }
-
- minimac2_update_mdio(s);
- } break;
- case R_TXCOUNT:
- s->regs[addr] = value;
- if (value > 0) {
- minimac2_tx(s);
- }
- break;
- case R_STATE0:
- case R_STATE1:
- s->regs[addr] = value;
- update_rx_interrupt(s);
- if (minimac2_can_rx(s)) {
- qemu_flush_queued_packets(qemu_get_queue(s->nic));
- }
- break;
- case R_SETUP:
- case R_COUNT0:
- case R_COUNT1:
- s->regs[addr] = value;
- break;
-
- default:
- qemu_log_mask(LOG_GUEST_ERROR,
- "milkymist_minimac2_wr%d: 0x%" HWADDR_PRIx
- " = 0x%" PRIx64 "\n",
- size, addr << 2, value);
- break;
- }
-}
-
-static const MemoryRegionOps minimac2_ops = {
- .read = minimac2_read,
- .write = minimac2_write,
- .valid = {
- .min_access_size = 4,
- .max_access_size = 4,
- },
- .endianness = DEVICE_NATIVE_ENDIAN,
-};
-
-static void milkymist_minimac2_reset(DeviceState *d)
-{
- MilkymistMinimac2State *s = MILKYMIST_MINIMAC2(d);
- int i;
-
- for (i = 0; i < R_MAX; i++) {
- s->regs[i] = 0;
- }
- for (i = 0; i < R_PHY_MAX; i++) {
- s->phy_regs[i] = 0;
- }
-
- /* defaults */
- s->phy_regs[R_PHY_ID1] = 0x0022; /* Micrel KSZ8001L */
- s->phy_regs[R_PHY_ID2] = 0x161a;
-}
-
-static NetClientInfo net_milkymist_minimac2_info = {
- .type = NET_CLIENT_DRIVER_NIC,
- .size = sizeof(NICState),
- .receive = minimac2_rx,
-};
-
-static void milkymist_minimac2_realize(DeviceState *dev, Error **errp)
-{
- SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
- MilkymistMinimac2State *s = MILKYMIST_MINIMAC2(dev);
- size_t buffers_size = TARGET_PAGE_ALIGN(3 * MINIMAC2_BUFFER_SIZE);
-
- sysbus_init_irq(sbd, &s->rx_irq);
- sysbus_init_irq(sbd, &s->tx_irq);
-
- memory_region_init_io(&s->regs_region, OBJECT(dev), &minimac2_ops, s,
- "milkymist-minimac2", R_MAX * 4);
- sysbus_init_mmio(sbd, &s->regs_region);
-
- /* register buffers memory */
- memory_region_init_ram_nomigrate(&s->buffers, OBJECT(dev), "milkymist-minimac2.buffers",
- buffers_size, &error_fatal);
- vmstate_register_ram_global(&s->buffers);
- s->rx0_buf = memory_region_get_ram_ptr(&s->buffers);
- s->rx1_buf = s->rx0_buf + MINIMAC2_BUFFER_SIZE;
- s->tx_buf = s->rx1_buf + MINIMAC2_BUFFER_SIZE;
-
- sysbus_init_mmio(sbd, &s->buffers);
-
- qemu_macaddr_default_if_unset(&s->conf.macaddr);
- s->nic = qemu_new_nic(&net_milkymist_minimac2_info, &s->conf,
- object_get_typename(OBJECT(dev)), dev->id, s);
- qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a);
-}
-
-static const VMStateDescription vmstate_milkymist_minimac2_mdio = {
- .name = "milkymist-minimac2-mdio",
- .version_id = 1,
- .minimum_version_id = 1,
- .fields = (VMStateField[]) {
- VMSTATE_INT32(last_clk, MilkymistMinimac2MdioState),
- VMSTATE_INT32(count, MilkymistMinimac2MdioState),
- VMSTATE_UINT32(data, MilkymistMinimac2MdioState),
- VMSTATE_UINT16(data_out, MilkymistMinimac2MdioState),
- VMSTATE_INT32(state, MilkymistMinimac2MdioState),
- VMSTATE_UINT8(phy_addr, MilkymistMinimac2MdioState),
- VMSTATE_UINT8(reg_addr, MilkymistMinimac2MdioState),
- VMSTATE_END_OF_LIST()
- }
-};
-
-static const VMStateDescription vmstate_milkymist_minimac2 = {
- .name = "milkymist-minimac2",
- .version_id = 1,
- .minimum_version_id = 1,
- .fields = (VMStateField[]) {
- VMSTATE_UINT32_ARRAY(regs, MilkymistMinimac2State, R_MAX),
- VMSTATE_UINT16_ARRAY(phy_regs, MilkymistMinimac2State, R_PHY_MAX),
- VMSTATE_STRUCT(mdio, MilkymistMinimac2State, 0,
- vmstate_milkymist_minimac2_mdio, MilkymistMinimac2MdioState),
- VMSTATE_END_OF_LIST()
- }
-};
-
-static Property milkymist_minimac2_properties[] = {
- DEFINE_NIC_PROPERTIES(MilkymistMinimac2State, conf),
- DEFINE_PROP_STRING("phy_model", MilkymistMinimac2State, phy_model),
- DEFINE_PROP_END_OF_LIST(),
-};
-
-static void milkymist_minimac2_class_init(ObjectClass *klass, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(klass);
-
- dc->realize = milkymist_minimac2_realize;
- dc->reset = milkymist_minimac2_reset;
- dc->vmsd = &vmstate_milkymist_minimac2;
- device_class_set_props(dc, milkymist_minimac2_properties);
-}
-
-static const TypeInfo milkymist_minimac2_info = {
- .name = TYPE_MILKYMIST_MINIMAC2,
- .parent = TYPE_SYS_BUS_DEVICE,
- .instance_size = sizeof(MilkymistMinimac2State),
- .class_init = milkymist_minimac2_class_init,
-};
-
-static void milkymist_minimac2_register_types(void)
-{
- type_register_static(&milkymist_minimac2_info);
-}
-
-type_init(milkymist_minimac2_register_types)
diff --git a/hw/net/trace-events b/hw/net/trace-events
index baf25ffa7e..314e21fa99 100644
--- a/hw/net/trace-events
+++ b/hw/net/trace-events
@@ -19,18 +19,6 @@ mdio_bitbang(bool mdc, bool mdio, int state, uint16_t cnt, unsigned int drive) "
lance_mem_readw(uint64_t addr, uint32_t ret) "addr=0x%"PRIx64"val=0x%04x"
lance_mem_writew(uint64_t addr, uint32_t val) "addr=0x%"PRIx64"val=0x%04x"
-# milkymist-minimac2.c
-milkymist_minimac2_memory_read(uint32_t addr, uint32_t value) "addr 0x%08x value 0x%08x"
-milkymist_minimac2_memory_write(uint32_t addr, uint32_t value) "addr 0x%08x value 0x%08x"
-milkymist_minimac2_mdio_write(uint8_t phy_addr, uint8_t addr, uint16_t value) "phy_addr 0x%02x addr 0x%02x value 0x%04x"
-milkymist_minimac2_mdio_read(uint8_t phy_addr, uint8_t addr, uint16_t value) "phy_addr 0x%02x addr 0x%02x value 0x%04x"
-milkymist_minimac2_tx_frame(uint32_t length) "length %u"
-milkymist_minimac2_rx_frame(const void *buf, uint32_t length) "buf %p length %u"
-milkymist_minimac2_rx_transfer(const void *buf, uint32_t length) "buf %p length %d"
-milkymist_minimac2_raise_irq_rx(void) "Raise IRQ RX"
-milkymist_minimac2_lower_irq_rx(void) "Lower IRQ RX"
-milkymist_minimac2_pulse_irq_tx(void) "Pulse IRQ TX"
-
# mipsnet.c
mipsnet_send(uint32_t size) "sending len=%u"
mipsnet_receive(uint32_t size) "receiving len=%u"
diff --git a/hw/scsi/virtio-scsi-dataplane.c b/hw/scsi/virtio-scsi-dataplane.c
index 4ad8793406..28e003250a 100644
--- a/hw/scsi/virtio-scsi-dataplane.c
+++ b/hw/scsi/virtio-scsi-dataplane.c
@@ -94,8 +94,7 @@ static bool virtio_scsi_data_plane_handle_event(VirtIODevice *vdev,
return progress;
}
-static int virtio_scsi_vring_init(VirtIOSCSI *s, VirtQueue *vq, int n,
- VirtIOHandleAIOOutput fn)
+static int virtio_scsi_set_host_notifier(VirtIOSCSI *s, VirtQueue *vq, int n)
{
BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(s)));
int rc;
@@ -109,7 +108,6 @@ static int virtio_scsi_vring_init(VirtIOSCSI *s, VirtQueue *vq, int n,
return rc;
}
- virtio_queue_aio_set_host_notifier_handler(vq, s->ctx, fn);
return 0;
}
@@ -154,40 +152,55 @@ int virtio_scsi_dataplane_start(VirtIODevice *vdev)
goto fail_guest_notifiers;
}
- aio_context_acquire(s->ctx);
- rc = virtio_scsi_vring_init(s, vs->ctrl_vq, 0,
- virtio_scsi_data_plane_handle_ctrl);
- if (rc) {
- goto fail_vrings;
+ memory_region_transaction_begin();
+
+ rc = virtio_scsi_set_host_notifier(s, vs->ctrl_vq, 0);
+ if (rc != 0) {
+ goto fail_host_notifiers;
}
vq_init_count++;
- rc = virtio_scsi_vring_init(s, vs->event_vq, 1,
- virtio_scsi_data_plane_handle_event);
- if (rc) {
- goto fail_vrings;
+ rc = virtio_scsi_set_host_notifier(s, vs->event_vq, 1);
+ if (rc != 0) {
+ goto fail_host_notifiers;
}
vq_init_count++;
+
for (i = 0; i < vs->conf.num_queues; i++) {
- rc = virtio_scsi_vring_init(s, vs->cmd_vqs[i], i + 2,
- virtio_scsi_data_plane_handle_cmd);
+ rc = virtio_scsi_set_host_notifier(s, vs->cmd_vqs[i], i + 2);
if (rc) {
- goto fail_vrings;
+ goto fail_host_notifiers;
}
vq_init_count++;
}
+ memory_region_transaction_commit();
+
+ aio_context_acquire(s->ctx);
+ virtio_queue_aio_set_host_notifier_handler(vs->ctrl_vq, s->ctx,
+ virtio_scsi_data_plane_handle_ctrl);
+ virtio_queue_aio_set_host_notifier_handler(vs->event_vq, s->ctx,
+ virtio_scsi_data_plane_handle_event);
+
+ for (i = 0; i < vs->conf.num_queues; i++) {
+ virtio_queue_aio_set_host_notifier_handler(vs->cmd_vqs[i], s->ctx,
+ virtio_scsi_data_plane_handle_cmd);
+ }
+
s->dataplane_starting = false;
s->dataplane_started = true;
aio_context_release(s->ctx);
return 0;
-fail_vrings:
- aio_wait_bh_oneshot(s->ctx, virtio_scsi_dataplane_stop_bh, s);
- aio_context_release(s->ctx);
+fail_host_notifiers:
for (i = 0; i < vq_init_count; i++) {
virtio_bus_set_host_notifier(VIRTIO_BUS(qbus), i, false);
+ }
+
+ memory_region_transaction_commit();
+
+ for (i = 0; i < vq_init_count; i++) {
virtio_bus_cleanup_host_notifier(VIRTIO_BUS(qbus), i);
}
k->set_guest_notifiers(qbus->parent, vs->conf.num_queues + 2, false);
@@ -225,8 +238,15 @@ void virtio_scsi_dataplane_stop(VirtIODevice *vdev)
blk_drain_all(); /* ensure there are no in-flight requests */
+ memory_region_transaction_begin();
+
for (i = 0; i < vs->conf.num_queues + 2; i++) {
virtio_bus_set_host_notifier(VIRTIO_BUS(qbus), i, false);
+ }
+
+ memory_region_transaction_commit();
+
+ for (i = 0; i < vs->conf.num_queues + 2; i++) {
virtio_bus_cleanup_host_notifier(VIRTIO_BUS(qbus), i);
}
diff --git a/hw/sd/meson.build b/hw/sd/meson.build
index 9c29691e13..f1ce357a3b 100644
--- a/hw/sd/meson.build
+++ b/hw/sd/meson.build
@@ -4,7 +4,6 @@ softmmu_ss.add(when: 'CONFIG_SDHCI', if_true: files('sdhci.c'))
softmmu_ss.add(when: 'CONFIG_SDHCI_PCI', if_true: files('sdhci-pci.c'))
softmmu_ss.add(when: 'CONFIG_SSI_SD', if_true: files('ssi-sd.c'))
-softmmu_ss.add(when: 'CONFIG_MILKYMIST', if_true: files('milkymist-memcard.c'))
softmmu_ss.add(when: 'CONFIG_OMAP', if_true: files('omap_mmc.c'))
softmmu_ss.add(when: 'CONFIG_PXA2XX', if_true: files('pxa2xx_mmci.c'))
softmmu_ss.add(when: 'CONFIG_RASPI', if_true: files('bcm2835_sdhost.c'))
diff --git a/hw/sd/milkymist-memcard.c b/hw/sd/milkymist-memcard.c
deleted file mode 100644
index a1235aa46c..0000000000
--- a/hw/sd/milkymist-memcard.c
+++ /dev/null
@@ -1,335 +0,0 @@
-/*
- * QEMU model of the Milkymist SD Card Controller.
- *
- * Copyright (c) 2010 Michael Walle <michael@walle.cc>
- *
- * 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.1 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/>.
- *
- *
- * Specification available at:
- * http://milkymist.walle.cc/socdoc/memcard.pdf
- */
-
-#include "qemu/osdep.h"
-#include "qemu/log.h"
-#include "qemu/module.h"
-#include "hw/sysbus.h"
-#include "migration/vmstate.h"
-#include "trace.h"
-#include "qapi/error.h"
-#include "sysemu/block-backend.h"
-#include "sysemu/blockdev.h"
-#include "hw/qdev-properties.h"
-#include "hw/sd/sd.h"
-#include "qom/object.h"
-
-enum {
- ENABLE_CMD_TX = (1<<0),
- ENABLE_CMD_RX = (1<<1),
- ENABLE_DAT_TX = (1<<2),
- ENABLE_DAT_RX = (1<<3),
-};
-
-enum {
- PENDING_CMD_TX = (1<<0),
- PENDING_CMD_RX = (1<<1),
- PENDING_DAT_TX = (1<<2),
- PENDING_DAT_RX = (1<<3),
-};
-
-enum {
- START_CMD_TX = (1<<0),
- START_DAT_RX = (1<<1),
-};
-
-enum {
- R_CLK2XDIV = 0,
- R_ENABLE,
- R_PENDING,
- R_START,
- R_CMD,
- R_DAT,
- R_MAX
-};
-
-#define TYPE_MILKYMIST_MEMCARD "milkymist-memcard"
-OBJECT_DECLARE_SIMPLE_TYPE(MilkymistMemcardState, MILKYMIST_MEMCARD)
-
-#define TYPE_MILKYMIST_SDBUS "milkymist-sdbus"
-
-struct MilkymistMemcardState {
- SysBusDevice parent_obj;
-
- MemoryRegion regs_region;
- SDBus sdbus;
-
- int command_write_ptr;
- int response_read_ptr;
- int response_len;
- int ignore_next_cmd;
- int enabled;
- uint8_t command[6];
- uint8_t response[17];
- uint32_t regs[R_MAX];
-};
-
-static void update_pending_bits(MilkymistMemcardState *s)
-{
- /* transmits are instantaneous, thus tx pending bits are never set */
- s->regs[R_PENDING] = 0;
- /* if rx is enabled the corresponding pending bits are always set */
- if (s->regs[R_ENABLE] & ENABLE_CMD_RX) {
- s->regs[R_PENDING] |= PENDING_CMD_RX;
- }
- if (s->regs[R_ENABLE] & ENABLE_DAT_RX) {
- s->regs[R_PENDING] |= PENDING_DAT_RX;
- }
-}
-
-static void memcard_sd_command(MilkymistMemcardState *s)
-{
- SDRequest req;
-
- req.cmd = s->command[0] & 0x3f;
- req.arg = ldl_be_p(s->command + 1);
- req.crc = s->command[5];
-
- s->response[0] = req.cmd;
- s->response_len = sdbus_do_command(&s->sdbus, &req, s->response + 1);
- s->response_read_ptr = 0;
-
- if (s->response_len == 16) {
- /* R2 response */
- s->response[0] = 0x3f;
- s->response_len += 1;
- } else if (s->response_len == 4) {
- /* no crc calculation, insert dummy byte */
- s->response[5] = 0;
- s->response_len += 2;
- }
-
- if (req.cmd == 0) {
- /* next write is a dummy byte to clock the initialization of the sd
- * card */
- s->ignore_next_cmd = 1;
- }
-}
-
-static uint64_t memcard_read(void *opaque, hwaddr addr,
- unsigned size)
-{
- MilkymistMemcardState *s = opaque;
- uint32_t r = 0;
-
- addr >>= 2;
- switch (addr) {
- case R_CMD:
- if (!s->enabled) {
- r = 0xff;
- } else {
- r = s->response[s->response_read_ptr++];
- if (s->response_read_ptr > s->response_len) {
- qemu_log_mask(LOG_GUEST_ERROR, "milkymist_memcard: "
- "read more cmd bytes than available: clipping\n");
- s->response_read_ptr = 0;
- }
- }
- break;
- case R_DAT:
- if (!s->enabled) {
- r = 0xffffffff;
- } else {
- sdbus_read_data(&s->sdbus, &r, sizeof(r));
- be32_to_cpus(&r);
- }
- break;
- case R_CLK2XDIV:
- case R_ENABLE:
- case R_PENDING:
- case R_START:
- r = s->regs[addr];
- break;
-
- default:
- qemu_log_mask(LOG_UNIMP, "milkymist_memcard: "
- "read access to unknown register 0x%" HWADDR_PRIx "\n",
- addr << 2);
- break;
- }
-
- trace_milkymist_memcard_memory_read(addr << 2, r);
-
- return r;
-}
-
-static void memcard_write(void *opaque, hwaddr addr, uint64_t value,
- unsigned size)
-{
- MilkymistMemcardState *s = opaque;
- uint32_t val32;
-
- trace_milkymist_memcard_memory_write(addr, value);
-
- addr >>= 2;
- switch (addr) {
- case R_PENDING:
- /* clear rx pending bits */
- s->regs[R_PENDING] &= ~(value & (PENDING_CMD_RX | PENDING_DAT_RX));
- update_pending_bits(s);
- break;
- case R_CMD:
- if (!s->enabled) {
- break;
- }
- if (s->ignore_next_cmd) {
- s->ignore_next_cmd = 0;
- break;
- }
- s->command[s->command_write_ptr] = value & 0xff;
- s->command_write_ptr = (s->command_write_ptr + 1) % 6;
- if (s->command_write_ptr == 0) {
- memcard_sd_command(s);
- }
- break;
- case R_DAT:
- if (!s->enabled) {
- break;
- }
- val32 = cpu_to_be32(value);
- sdbus_write_data(&s->sdbus, &val32, sizeof(val32));
- break;
- case R_ENABLE:
- s->regs[addr] = value;
- update_pending_bits(s);
- break;
- case R_CLK2XDIV:
- case R_START:
- s->regs[addr] = value;
- break;
-
- default:
- qemu_log_mask(LOG_UNIMP, "milkymist_memcard: "
- "write access to unknown register 0x%" HWADDR_PRIx " "
- "(value 0x%" PRIx64 ")\n", addr << 2, value);
- break;
- }
-}
-
-static const MemoryRegionOps memcard_mmio_ops = {
- .read = memcard_read,
- .write = memcard_write,
- .valid = {
- .min_access_size = 4,
- .max_access_size = 4,
- },
- .endianness = DEVICE_NATIVE_ENDIAN,
-};
-
-static void milkymist_memcard_reset(DeviceState *d)
-{
- MilkymistMemcardState *s = MILKYMIST_MEMCARD(d);
- int i;
-
- s->command_write_ptr = 0;
- s->response_read_ptr = 0;
- s->response_len = 0;
-
- for (i = 0; i < R_MAX; i++) {
- s->regs[i] = 0;
- }
-}
-
-static void milkymist_memcard_set_readonly(DeviceState *dev, bool level)
-{
- qemu_log_mask(LOG_UNIMP,
- "milkymist_memcard: read-only mode not supported\n");
-}
-
-static void milkymist_memcard_set_inserted(DeviceState *dev, bool level)
-{
- MilkymistMemcardState *s = MILKYMIST_MEMCARD(dev);
-
- s->enabled = !!level;
-}
-
-static void milkymist_memcard_init(Object *obj)
-{
- MilkymistMemcardState *s = MILKYMIST_MEMCARD(obj);
- SysBusDevice *dev = SYS_BUS_DEVICE(obj);
-
- memory_region_init_io(&s->regs_region, OBJECT(s), &memcard_mmio_ops, s,
- "milkymist-memcard", R_MAX * 4);
- sysbus_init_mmio(dev, &s->regs_region);
-
- qbus_create_inplace(&s->sdbus, sizeof(s->sdbus), TYPE_SD_BUS,
- DEVICE(obj), "sd-bus");
-}
-
-static const VMStateDescription vmstate_milkymist_memcard = {
- .name = "milkymist-memcard",
- .version_id = 1,
- .minimum_version_id = 1,
- .fields = (VMStateField[]) {
- VMSTATE_INT32(command_write_ptr, MilkymistMemcardState),
- VMSTATE_INT32(response_read_ptr, MilkymistMemcardState),
- VMSTATE_INT32(response_len, MilkymistMemcardState),
- VMSTATE_INT32(ignore_next_cmd, MilkymistMemcardState),
- VMSTATE_INT32(enabled, MilkymistMemcardState),
- VMSTATE_UINT8_ARRAY(command, MilkymistMemcardState, 6),
- VMSTATE_UINT8_ARRAY(response, MilkymistMemcardState, 17),
- VMSTATE_UINT32_ARRAY(regs, MilkymistMemcardState, R_MAX),
- VMSTATE_END_OF_LIST()
- }
-};
-
-static void milkymist_memcard_class_init(ObjectClass *klass, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(klass);
-
- dc->reset = milkymist_memcard_reset;
- dc->vmsd = &vmstate_milkymist_memcard;
- /* Reason: output IRQs should be wired up */
- dc->user_creatable = false;
-}
-
-static const TypeInfo milkymist_memcard_info = {
- .name = TYPE_MILKYMIST_MEMCARD,
- .parent = TYPE_SYS_BUS_DEVICE,
- .instance_size = sizeof(MilkymistMemcardState),
- .instance_init = milkymist_memcard_init,
- .class_init = milkymist_memcard_class_init,
-};
-
-static void milkymist_sdbus_class_init(ObjectClass *klass, void *data)
-{
- SDBusClass *sbc = SD_BUS_CLASS(klass);
-
- sbc->set_inserted = milkymist_memcard_set_inserted;
- sbc->set_readonly = milkymist_memcard_set_readonly;
-}
-
-static const TypeInfo milkymist_sdbus_info = {
- .name = TYPE_MILKYMIST_SDBUS,
- .parent = TYPE_SD_BUS,
- .instance_size = sizeof(SDBus),
- .class_init = milkymist_sdbus_class_init,
-};
-
-static void milkymist_memcard_register_types(void)
-{
- type_register_static(&milkymist_memcard_info);
- type_register_static(&milkymist_sdbus_info);
-}
-
-type_init(milkymist_memcard_register_types)
diff --git a/hw/sd/trace-events b/hw/sd/trace-events
index 4140e48540..e185d07a1d 100644
--- a/hw/sd/trace-events
+++ b/hw/sd/trace-events
@@ -55,10 +55,6 @@ sdcard_write_data(const char *proto, const char *cmd_desc, uint8_t cmd, uint8_t
sdcard_read_data(const char *proto, const char *cmd_desc, uint8_t cmd, uint32_t length) "%s %20s/ CMD%02d len %" PRIu32
sdcard_set_voltage(uint16_t millivolts) "%u mV"
-# milkymist-memcard.c
-milkymist_memcard_memory_read(uint32_t addr, uint32_t value) "addr 0x%08x value 0x%08x"
-milkymist_memcard_memory_write(uint32_t addr, uint32_t value) "addr 0x%08x value 0x%08x"
-
# pxa2xx_mmci.c
pxa2xx_mmci_read(uint8_t size, uint32_t addr, uint32_t value) "size %d addr 0x%02x value 0x%08x"
pxa2xx_mmci_write(uint8_t size, uint32_t addr, uint32_t value) "size %d addr 0x%02x value 0x%08x"
diff --git a/hw/smbios/smbios.c b/hw/smbios/smbios.c
index f22c4f5b73..7397e56737 100644
--- a/hw/smbios/smbios.c
+++ b/hw/smbios/smbios.c
@@ -27,6 +27,7 @@
#include "hw/firmware/smbios.h"
#include "hw/loader.h"
#include "hw/boards.h"
+#include "hw/pci/pci_bus.h"
#include "smbios_build.h"
/* legacy structures and constants for <= 2.0 machines */
@@ -118,6 +119,28 @@ static struct {
uint16_t speed;
} type17;
+static QEnumLookup type41_kind_lookup = {
+ .array = (const char *const[]) {
+ "other",
+ "unknown",
+ "video",
+ "scsi",
+ "ethernet",
+ "tokenring",
+ "sound",
+ "pata",
+ "sata",
+ "sas",
+ },
+ .size = 10
+};
+struct type41_instance {
+ const char *designation, *pcidev;
+ uint8_t instance, kind;
+ QTAILQ_ENTRY(type41_instance) next;
+};
+static QTAILQ_HEAD(, type41_instance) type41 = QTAILQ_HEAD_INITIALIZER(type41);
+
static QemuOptsList qemu_smbios_opts = {
.name = "smbios",
.head = QTAILQ_HEAD_INITIALIZER(qemu_smbios_opts.head),
@@ -358,6 +381,32 @@ static const QemuOptDesc qemu_smbios_type17_opts[] = {
{ /* end of list */ }
};
+static const QemuOptDesc qemu_smbios_type41_opts[] = {
+ {
+ .name = "type",
+ .type = QEMU_OPT_NUMBER,
+ .help = "SMBIOS element type",
+ },{
+ .name = "designation",
+ .type = QEMU_OPT_STRING,
+ .help = "reference designation string",
+ },{
+ .name = "kind",
+ .type = QEMU_OPT_STRING,
+ .help = "device type",
+ .def_value_str = "other",
+ },{
+ .name = "instance",
+ .type = QEMU_OPT_NUMBER,
+ .help = "device type instance",
+ },{
+ .name = "pcidev",
+ .type = QEMU_OPT_STRING,
+ .help = "PCI device",
+ },
+ { /* end of list */ }
+};
+
static void smbios_register_config(void)
{
qemu_add_opts(&qemu_smbios_opts);
@@ -773,6 +822,53 @@ static void smbios_build_type_32_table(void)
SMBIOS_BUILD_TABLE_POST;
}
+static void smbios_build_type_41_table(Error **errp)
+{
+ unsigned instance = 0;
+ struct type41_instance *t41;
+
+ QTAILQ_FOREACH(t41, &type41, next) {
+ SMBIOS_BUILD_TABLE_PRE(41, 0x2900 + instance, true);
+
+ SMBIOS_TABLE_SET_STR(41, reference_designation_str, t41->designation);
+ t->device_type = t41->kind;
+ t->device_type_instance = t41->instance;
+ t->segment_group_number = cpu_to_le16(0);
+ t->bus_number = 0;
+ t->device_number = 0;
+
+ if (t41->pcidev) {
+ PCIDevice *pdev = NULL;
+ int rc = pci_qdev_find_device(t41->pcidev, &pdev);
+ if (rc != 0) {
+ error_setg(errp,
+ "No PCI device %s for SMBIOS type 41 entry %s",
+ t41->pcidev, t41->designation);
+ return;
+ }
+ /*
+ * We only handle the case were the device is attached to
+ * the PCI root bus. The general case is more complex as
+ * bridges are enumerated later and the table would need
+ * to be updated at this moment.
+ */
+ if (!pci_bus_is_root(pci_get_bus(pdev))) {
+ error_setg(errp,
+ "Cannot create type 41 entry for PCI device %s: "
+ "not attached to the root bus",
+ t41->pcidev);
+ return;
+ }
+ t->segment_group_number = cpu_to_le16(0);
+ t->bus_number = pci_dev_bus_num(pdev);
+ t->device_number = pdev->devfn;
+ }
+
+ SMBIOS_BUILD_TABLE_POST;
+ instance++;
+ }
+}
+
static void smbios_build_type_127_table(void)
{
SMBIOS_BUILD_TABLE_PRE(127, 0x7F00, true); /* required */
@@ -883,7 +979,8 @@ void smbios_get_tables(MachineState *ms,
const struct smbios_phys_mem_area *mem_array,
const unsigned int mem_array_size,
uint8_t **tables, size_t *tables_len,
- uint8_t **anchor, size_t *anchor_len)
+ uint8_t **anchor, size_t *anchor_len,
+ Error **errp)
{
unsigned i, dimm_cnt;
@@ -928,6 +1025,7 @@ void smbios_get_tables(MachineState *ms,
smbios_build_type_32_table();
smbios_build_type_38_table();
+ smbios_build_type_41_table(errp);
smbios_build_type_127_table();
smbios_validate_table(ms);
@@ -1224,6 +1322,30 @@ void smbios_entry_add(QemuOpts *opts, Error **errp)
save_opt(&type17.part, opts, "part");
type17.speed = qemu_opt_get_number(opts, "speed", 0);
return;
+ case 41: {
+ struct type41_instance *t;
+ Error *local_err = NULL;
+
+ if (!qemu_opts_validate(opts, qemu_smbios_type41_opts, errp)) {
+ return;
+ }
+ t = g_new0(struct type41_instance, 1);
+ save_opt(&t->designation, opts, "designation");
+ t->kind = qapi_enum_parse(&type41_kind_lookup,
+ qemu_opt_get(opts, "kind"),
+ 0, &local_err) + 1;
+ t->kind |= 0x80; /* enabled */
+ if (local_err != NULL) {
+ error_propagate(errp, local_err);
+ g_free(t);
+ return;
+ }
+ t->instance = qemu_opt_get_number(opts, "instance", 1);
+ save_opt(&t->pcidev, opts, "pcidev");
+
+ QTAILQ_INSERT_TAIL(&type41, t, next);
+ return;
+ }
default:
error_setg(errp,
"Don't know how to build fields for SMBIOS type %ld",
diff --git a/hw/timer/lm32_timer.c b/hw/timer/lm32_timer.c
deleted file mode 100644
index eeaf0ada5f..0000000000
--- a/hw/timer/lm32_timer.c
+++ /dev/null
@@ -1,249 +0,0 @@
-/*
- * QEMU model of the LatticeMico32 timer block.
- *
- * Copyright (c) 2010 Michael Walle <michael@walle.cc>
- *
- * 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.1 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/>.
- *
- *
- * Specification available at:
- * http://www.latticesemi.com/documents/mico32timer.pdf
- */
-
-#include "qemu/osdep.h"
-#include "hw/irq.h"
-#include "hw/sysbus.h"
-#include "migration/vmstate.h"
-#include "trace.h"
-#include "qemu/timer.h"
-#include "hw/ptimer.h"
-#include "hw/qdev-properties.h"
-#include "qemu/error-report.h"
-#include "qemu/module.h"
-#include "qom/object.h"
-
-#define DEFAULT_FREQUENCY (50*1000000)
-
-enum {
- R_SR = 0,
- R_CR,
- R_PERIOD,
- R_SNAPSHOT,
- R_MAX
-};
-
-enum {
- SR_TO = (1 << 0),
- SR_RUN = (1 << 1),
-};
-
-enum {
- CR_ITO = (1 << 0),
- CR_CONT = (1 << 1),
- CR_START = (1 << 2),
- CR_STOP = (1 << 3),
-};
-
-#define TYPE_LM32_TIMER "lm32-timer"
-OBJECT_DECLARE_SIMPLE_TYPE(LM32TimerState, LM32_TIMER)
-
-struct LM32TimerState {
- SysBusDevice parent_obj;
-
- MemoryRegion iomem;
-
- ptimer_state *ptimer;
-
- qemu_irq irq;
- uint32_t freq_hz;
-
- uint32_t regs[R_MAX];
-};
-
-static void timer_update_irq(LM32TimerState *s)
-{
- int state = (s->regs[R_SR] & SR_TO) && (s->regs[R_CR] & CR_ITO);
-
- trace_lm32_timer_irq_state(state);
- qemu_set_irq(s->irq, state);
-}
-
-static uint64_t timer_read(void *opaque, hwaddr addr, unsigned size)
-{
- LM32TimerState *s = opaque;
- uint32_t r = 0;
-
- addr >>= 2;
- switch (addr) {
- case R_SR:
- case R_CR:
- case R_PERIOD:
- r = s->regs[addr];
- break;
- case R_SNAPSHOT:
- r = (uint32_t)ptimer_get_count(s->ptimer);
- break;
- default:
- error_report("lm32_timer: read access to unknown register 0x"
- TARGET_FMT_plx, addr << 2);
- break;
- }
-
- trace_lm32_timer_memory_read(addr << 2, r);
- return r;
-}
-
-static void timer_write(void *opaque, hwaddr addr,
- uint64_t value, unsigned size)
-{
- LM32TimerState *s = opaque;
-
- trace_lm32_timer_memory_write(addr, value);
-
- addr >>= 2;
- switch (addr) {
- case R_SR:
- s->regs[R_SR] &= ~SR_TO;
- break;
- case R_CR:
- ptimer_transaction_begin(s->ptimer);
- s->regs[R_CR] = value;
- if (s->regs[R_CR] & CR_START) {
- ptimer_run(s->ptimer, 1);
- }
- if (s->regs[R_CR] & CR_STOP) {
- ptimer_stop(s->ptimer);
- }
- ptimer_transaction_commit(s->ptimer);
- break;
- case R_PERIOD:
- s->regs[R_PERIOD] = value;
- ptimer_transaction_begin(s->ptimer);
- ptimer_set_count(s->ptimer, value);
- ptimer_transaction_commit(s->ptimer);
- break;
- case R_SNAPSHOT:
- error_report("lm32_timer: write access to read only register 0x"
- TARGET_FMT_plx, addr << 2);
- break;
- default:
- error_report("lm32_timer: write access to unknown register 0x"
- TARGET_FMT_plx, addr << 2);
- break;
- }
- timer_update_irq(s);
-}
-
-static const MemoryRegionOps timer_ops = {
- .read = timer_read,
- .write = timer_write,
- .endianness = DEVICE_NATIVE_ENDIAN,
- .valid = {
- .min_access_size = 4,
- .max_access_size = 4,
- },
-};
-
-static void timer_hit(void *opaque)
-{
- LM32TimerState *s = opaque;
-
- trace_lm32_timer_hit();
-
- s->regs[R_SR] |= SR_TO;
-
- if (s->regs[R_CR] & CR_CONT) {
- ptimer_set_count(s->ptimer, s->regs[R_PERIOD]);
- ptimer_run(s->ptimer, 1);
- }
- timer_update_irq(s);
-}
-
-static void timer_reset(DeviceState *d)
-{
- LM32TimerState *s = LM32_TIMER(d);
- int i;
-
- for (i = 0; i < R_MAX; i++) {
- s->regs[i] = 0;
- }
- ptimer_transaction_begin(s->ptimer);
- ptimer_stop(s->ptimer);
- ptimer_transaction_commit(s->ptimer);
-}
-
-static void lm32_timer_init(Object *obj)
-{
- LM32TimerState *s = LM32_TIMER(obj);
- SysBusDevice *dev = SYS_BUS_DEVICE(obj);
-
- sysbus_init_irq(dev, &s->irq);
-
- memory_region_init_io(&s->iomem, obj, &timer_ops, s,
- "timer", R_MAX * 4);
- sysbus_init_mmio(dev, &s->iomem);
-}
-
-static void lm32_timer_realize(DeviceState *dev, Error **errp)
-{
- LM32TimerState *s = LM32_TIMER(dev);
-
- s->ptimer = ptimer_init(timer_hit, s, PTIMER_POLICY_DEFAULT);
-
- ptimer_transaction_begin(s->ptimer);
- ptimer_set_freq(s->ptimer, s->freq_hz);
- ptimer_transaction_commit(s->ptimer);
-}
-
-static const VMStateDescription vmstate_lm32_timer = {
- .name = "lm32-timer",
- .version_id = 1,
- .minimum_version_id = 1,
- .fields = (VMStateField[]) {
- VMSTATE_PTIMER(ptimer, LM32TimerState),
- VMSTATE_UINT32(freq_hz, LM32TimerState),
- VMSTATE_UINT32_ARRAY(regs, LM32TimerState, R_MAX),
- VMSTATE_END_OF_LIST()
- }
-};
-
-static Property lm32_timer_properties[] = {
- DEFINE_PROP_UINT32("frequency", LM32TimerState, freq_hz, DEFAULT_FREQUENCY),
- DEFINE_PROP_END_OF_LIST(),
-};
-
-static void lm32_timer_class_init(ObjectClass *klass, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(klass);
-
- dc->realize = lm32_timer_realize;
- dc->reset = timer_reset;
- dc->vmsd = &vmstate_lm32_timer;
- device_class_set_props(dc, lm32_timer_properties);
-}
-
-static const TypeInfo lm32_timer_info = {
- .name = TYPE_LM32_TIMER,
- .parent = TYPE_SYS_BUS_DEVICE,
- .instance_size = sizeof(LM32TimerState),
- .instance_init = lm32_timer_init,
- .class_init = lm32_timer_class_init,
-};
-
-static void lm32_timer_register_types(void)
-{
- type_register_static(&lm32_timer_info);
-}
-
-type_init(lm32_timer_register_types)
diff --git a/hw/timer/meson.build b/hw/timer/meson.build
index 598d058506..157f540ecd 100644
--- a/hw/timer/meson.build
+++ b/hw/timer/meson.build
@@ -19,15 +19,12 @@ softmmu_ss.add(when: 'CONFIG_HPET', if_true: files('hpet.c'))
softmmu_ss.add(when: 'CONFIG_I8254', if_true: files('i8254_common.c', 'i8254.c'))
softmmu_ss.add(when: 'CONFIG_IMX', if_true: files('imx_epit.c'))
softmmu_ss.add(when: 'CONFIG_IMX', if_true: files('imx_gpt.c'))
-softmmu_ss.add(when: 'CONFIG_LM32_DEVICES', if_true: files('lm32_timer.c'))
-softmmu_ss.add(when: 'CONFIG_MILKYMIST', if_true: files('milkymist-sysctl.c'))
softmmu_ss.add(when: 'CONFIG_MIPS_CPS', if_true: files('mips_gictimer.c'))
softmmu_ss.add(when: 'CONFIG_MSF2', if_true: files('mss-timer.c'))
softmmu_ss.add(when: 'CONFIG_NPCM7XX', if_true: files('npcm7xx_timer.c'))
softmmu_ss.add(when: 'CONFIG_NRF51_SOC', if_true: files('nrf51_timer.c'))
softmmu_ss.add(when: 'CONFIG_OMAP', if_true: files('omap_gptimer.c'))
softmmu_ss.add(when: 'CONFIG_OMAP', if_true: files('omap_synctimer.c'))
-softmmu_ss.add(when: 'CONFIG_PUV3', if_true: files('puv3_ost.c'))
softmmu_ss.add(when: 'CONFIG_PXA2XX', if_true: files('pxa2xx_timer.c'))
softmmu_ss.add(when: 'CONFIG_RASPI', if_true: files('bcm2835_systmr.c'))
softmmu_ss.add(when: 'CONFIG_SH_TIMER', if_true: files('sh_timer.c'))
diff --git a/hw/timer/milkymist-sysctl.c b/hw/timer/milkymist-sysctl.c
deleted file mode 100644
index 9ecea63861..0000000000
--- a/hw/timer/milkymist-sysctl.c
+++ /dev/null
@@ -1,361 +0,0 @@
-/*
- * QEMU model of the Milkymist System Controller.
- *
- * Copyright (c) 2010-2012 Michael Walle <michael@walle.cc>
- *
- * 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.1 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/>.
- *
- *
- * Specification available at:
- * http://milkymist.walle.cc/socdoc/sysctl.pdf
- */
-
-#include "qemu/osdep.h"
-#include "hw/irq.h"
-#include "hw/sysbus.h"
-#include "migration/vmstate.h"
-#include "trace.h"
-#include "qemu/timer.h"
-#include "sysemu/runstate.h"
-#include "hw/ptimer.h"
-#include "hw/qdev-properties.h"
-#include "qemu/error-report.h"
-#include "qemu/module.h"
-#include "qom/object.h"
-
-enum {
- CTRL_ENABLE = (1<<0),
- CTRL_AUTORESTART = (1<<1),
-};
-
-enum {
- ICAP_READY = (1<<0),
-};
-
-enum {
- R_GPIO_IN = 0,
- R_GPIO_OUT,
- R_GPIO_INTEN,
- R_TIMER0_CONTROL = 4,
- R_TIMER0_COMPARE,
- R_TIMER0_COUNTER,
- R_TIMER1_CONTROL = 8,
- R_TIMER1_COMPARE,
- R_TIMER1_COUNTER,
- R_ICAP = 16,
- R_DBG_SCRATCHPAD = 20,
- R_DBG_WRITE_LOCK,
- R_CLK_FREQUENCY = 29,
- R_CAPABILITIES,
- R_SYSTEM_ID,
- R_MAX
-};
-
-#define TYPE_MILKYMIST_SYSCTL "milkymist-sysctl"
-OBJECT_DECLARE_SIMPLE_TYPE(MilkymistSysctlState, MILKYMIST_SYSCTL)
-
-struct MilkymistSysctlState {
- SysBusDevice parent_obj;
-
- MemoryRegion regs_region;
-
- ptimer_state *ptimer0;
- ptimer_state *ptimer1;
-
- uint32_t freq_hz;
- uint32_t capabilities;
- uint32_t systemid;
- uint32_t strappings;
-
- uint32_t regs[R_MAX];
-
- qemu_irq gpio_irq;
- qemu_irq timer0_irq;
- qemu_irq timer1_irq;
-};
-
-static void sysctl_icap_write(MilkymistSysctlState *s, uint32_t value)
-{
- trace_milkymist_sysctl_icap_write(value);
- switch (value & 0xffff) {
- case 0x000e:
- qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
- break;
- }
-}
-
-static uint64_t sysctl_read(void *opaque, hwaddr addr,
- unsigned size)
-{
- MilkymistSysctlState *s = opaque;
- uint32_t r = 0;
-
- addr >>= 2;
- switch (addr) {
- case R_TIMER0_COUNTER:
- r = (uint32_t)ptimer_get_count(s->ptimer0);
- /* milkymist timer counts up */
- r = s->regs[R_TIMER0_COMPARE] - r;
- break;
- case R_TIMER1_COUNTER:
- r = (uint32_t)ptimer_get_count(s->ptimer1);
- /* milkymist timer counts up */
- r = s->regs[R_TIMER1_COMPARE] - r;
- break;
- case R_GPIO_IN:
- case R_GPIO_OUT:
- case R_GPIO_INTEN:
- case R_TIMER0_CONTROL:
- case R_TIMER0_COMPARE:
- case R_TIMER1_CONTROL:
- case R_TIMER1_COMPARE:
- case R_ICAP:
- case R_DBG_SCRATCHPAD:
- case R_DBG_WRITE_LOCK:
- case R_CLK_FREQUENCY:
- case R_CAPABILITIES:
- case R_SYSTEM_ID:
- r = s->regs[addr];
- break;
-
- default:
- error_report("milkymist_sysctl: read access to unknown register 0x"
- TARGET_FMT_plx, addr << 2);
- break;
- }
-
- trace_milkymist_sysctl_memory_read(addr << 2, r);
-
- return r;
-}
-
-static void sysctl_write(void *opaque, hwaddr addr, uint64_t value,
- unsigned size)
-{
- MilkymistSysctlState *s = opaque;
-
- trace_milkymist_sysctl_memory_write(addr, value);
-
- addr >>= 2;
- switch (addr) {
- case R_GPIO_OUT:
- case R_GPIO_INTEN:
- case R_TIMER0_COUNTER:
- case R_TIMER1_COUNTER:
- case R_DBG_SCRATCHPAD:
- s->regs[addr] = value;
- break;
- case R_TIMER0_COMPARE:
- ptimer_transaction_begin(s->ptimer0);
- ptimer_set_limit(s->ptimer0, value, 0);
- s->regs[addr] = value;
- ptimer_transaction_commit(s->ptimer0);
- break;
- case R_TIMER1_COMPARE:
- ptimer_transaction_begin(s->ptimer1);
- ptimer_set_limit(s->ptimer1, value, 0);
- s->regs[addr] = value;
- ptimer_transaction_commit(s->ptimer1);
- break;
- case R_TIMER0_CONTROL:
- ptimer_transaction_begin(s->ptimer0);
- s->regs[addr] = value;
- if (s->regs[R_TIMER0_CONTROL] & CTRL_ENABLE) {
- trace_milkymist_sysctl_start_timer0();
- ptimer_set_count(s->ptimer0,
- s->regs[R_TIMER0_COMPARE] - s->regs[R_TIMER0_COUNTER]);
- ptimer_run(s->ptimer0, 0);
- } else {
- trace_milkymist_sysctl_stop_timer0();
- ptimer_stop(s->ptimer0);
- }
- ptimer_transaction_commit(s->ptimer0);
- break;
- case R_TIMER1_CONTROL:
- ptimer_transaction_begin(s->ptimer1);
- s->regs[addr] = value;
- if (s->regs[R_TIMER1_CONTROL] & CTRL_ENABLE) {
- trace_milkymist_sysctl_start_timer1();
- ptimer_set_count(s->ptimer1,
- s->regs[R_TIMER1_COMPARE] - s->regs[R_TIMER1_COUNTER]);
- ptimer_run(s->ptimer1, 0);
- } else {
- trace_milkymist_sysctl_stop_timer1();
- ptimer_stop(s->ptimer1);
- }
- ptimer_transaction_commit(s->ptimer1);
- break;
- case R_ICAP:
- sysctl_icap_write(s, value);
- break;
- case R_DBG_WRITE_LOCK:
- s->regs[addr] = 1;
- break;
- case R_SYSTEM_ID:
- qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
- break;
-
- case R_GPIO_IN:
- case R_CLK_FREQUENCY:
- case R_CAPABILITIES:
- error_report("milkymist_sysctl: write to read-only register 0x"
- TARGET_FMT_plx, addr << 2);
- break;
-
- default:
- error_report("milkymist_sysctl: write access to unknown register 0x"
- TARGET_FMT_plx, addr << 2);
- break;
- }
-}
-
-static const MemoryRegionOps sysctl_mmio_ops = {
- .read = sysctl_read,
- .write = sysctl_write,
- .valid = {
- .min_access_size = 4,
- .max_access_size = 4,
- },
- .endianness = DEVICE_NATIVE_ENDIAN,
-};
-
-static void timer0_hit(void *opaque)
-{
- MilkymistSysctlState *s = opaque;
-
- if (!(s->regs[R_TIMER0_CONTROL] & CTRL_AUTORESTART)) {
- s->regs[R_TIMER0_CONTROL] &= ~CTRL_ENABLE;
- trace_milkymist_sysctl_stop_timer0();
- ptimer_stop(s->ptimer0);
- }
-
- trace_milkymist_sysctl_pulse_irq_timer0();
- qemu_irq_pulse(s->timer0_irq);
-}
-
-static void timer1_hit(void *opaque)
-{
- MilkymistSysctlState *s = opaque;
-
- if (!(s->regs[R_TIMER1_CONTROL] & CTRL_AUTORESTART)) {
- s->regs[R_TIMER1_CONTROL] &= ~CTRL_ENABLE;
- trace_milkymist_sysctl_stop_timer1();
- ptimer_stop(s->ptimer1);
- }
-
- trace_milkymist_sysctl_pulse_irq_timer1();
- qemu_irq_pulse(s->timer1_irq);
-}
-
-static void milkymist_sysctl_reset(DeviceState *d)
-{
- MilkymistSysctlState *s = MILKYMIST_SYSCTL(d);
- int i;
-
- for (i = 0; i < R_MAX; i++) {
- s->regs[i] = 0;
- }
-
- ptimer_transaction_begin(s->ptimer0);
- ptimer_stop(s->ptimer0);
- ptimer_transaction_commit(s->ptimer0);
- ptimer_transaction_begin(s->ptimer1);
- ptimer_stop(s->ptimer1);
- ptimer_transaction_commit(s->ptimer1);
-
- /* defaults */
- s->regs[R_ICAP] = ICAP_READY;
- s->regs[R_SYSTEM_ID] = s->systemid;
- s->regs[R_CLK_FREQUENCY] = s->freq_hz;
- s->regs[R_CAPABILITIES] = s->capabilities;
- s->regs[R_GPIO_IN] = s->strappings;
-}
-
-static void milkymist_sysctl_init(Object *obj)
-{
- MilkymistSysctlState *s = MILKYMIST_SYSCTL(obj);
- SysBusDevice *dev = SYS_BUS_DEVICE(obj);
-
- sysbus_init_irq(dev, &s->gpio_irq);
- sysbus_init_irq(dev, &s->timer0_irq);
- sysbus_init_irq(dev, &s->timer1_irq);
-
- memory_region_init_io(&s->regs_region, obj, &sysctl_mmio_ops, s,
- "milkymist-sysctl", R_MAX * 4);
- sysbus_init_mmio(dev, &s->regs_region);
-}
-
-static void milkymist_sysctl_realize(DeviceState *dev, Error **errp)
-{
- MilkymistSysctlState *s = MILKYMIST_SYSCTL(dev);
-
- s->ptimer0 = ptimer_init(timer0_hit, s, PTIMER_POLICY_DEFAULT);
- s->ptimer1 = ptimer_init(timer1_hit, s, PTIMER_POLICY_DEFAULT);
-
- ptimer_transaction_begin(s->ptimer0);
- ptimer_set_freq(s->ptimer0, s->freq_hz);
- ptimer_transaction_commit(s->ptimer0);
- ptimer_transaction_begin(s->ptimer1);
- ptimer_set_freq(s->ptimer1, s->freq_hz);
- ptimer_transaction_commit(s->ptimer1);
-}
-
-static const VMStateDescription vmstate_milkymist_sysctl = {
- .name = "milkymist-sysctl",
- .version_id = 1,
- .minimum_version_id = 1,
- .fields = (VMStateField[]) {
- VMSTATE_UINT32_ARRAY(regs, MilkymistSysctlState, R_MAX),
- VMSTATE_PTIMER(ptimer0, MilkymistSysctlState),
- VMSTATE_PTIMER(ptimer1, MilkymistSysctlState),
- VMSTATE_END_OF_LIST()
- }
-};
-
-static Property milkymist_sysctl_properties[] = {
- DEFINE_PROP_UINT32("frequency", MilkymistSysctlState,
- freq_hz, 80000000),
- DEFINE_PROP_UINT32("capabilities", MilkymistSysctlState,
- capabilities, 0x00000000),
- DEFINE_PROP_UINT32("systemid", MilkymistSysctlState,
- systemid, 0x10014d31),
- DEFINE_PROP_UINT32("gpio_strappings", MilkymistSysctlState,
- strappings, 0x00000001),
- DEFINE_PROP_END_OF_LIST(),
-};
-
-static void milkymist_sysctl_class_init(ObjectClass *klass, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(klass);
-
- dc->realize = milkymist_sysctl_realize;
- dc->reset = milkymist_sysctl_reset;
- dc->vmsd = &vmstate_milkymist_sysctl;
- device_class_set_props(dc, milkymist_sysctl_properties);
-}
-
-static const TypeInfo milkymist_sysctl_info = {
- .name = TYPE_MILKYMIST_SYSCTL,
- .parent = TYPE_SYS_BUS_DEVICE,
- .instance_size = sizeof(MilkymistSysctlState),
- .instance_init = milkymist_sysctl_init,
- .class_init = milkymist_sysctl_class_init,
-};
-
-static void milkymist_sysctl_register_types(void)
-{
- type_register_static(&milkymist_sysctl_info);
-}
-
-type_init(milkymist_sysctl_register_types)
diff --git a/hw/timer/puv3_ost.c b/hw/timer/puv3_ost.c
deleted file mode 100644
index d5bf26b56b..0000000000
--- a/hw/timer/puv3_ost.c
+++ /dev/null
@@ -1,166 +0,0 @@
-/*
- * OSTimer device simulation in PKUnity SoC
- *
- * Copyright (C) 2010-2012 Guan Xuetao
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation, or any later version.
- * See the COPYING file in the top-level directory.
- */
-
-#include "qemu/osdep.h"
-#include "hw/sysbus.h"
-#include "hw/irq.h"
-#include "hw/ptimer.h"
-#include "qemu/module.h"
-#include "qemu/log.h"
-#include "qom/object.h"
-
-#undef DEBUG_PUV3
-#include "hw/unicore32/puv3.h"
-
-#define TYPE_PUV3_OST "puv3_ost"
-OBJECT_DECLARE_SIMPLE_TYPE(PUV3OSTState, PUV3_OST)
-
-/* puv3 ostimer implementation. */
-struct PUV3OSTState {
- SysBusDevice parent_obj;
-
- MemoryRegion iomem;
- qemu_irq irq;
- ptimer_state *ptimer;
-
- uint32_t reg_OSMR0;
- uint32_t reg_OSCR;
- uint32_t reg_OSSR;
- uint32_t reg_OIER;
-};
-
-static uint64_t puv3_ost_read(void *opaque, hwaddr offset,
- unsigned size)
-{
- PUV3OSTState *s = opaque;
- uint32_t ret = 0;
-
- switch (offset) {
- case 0x10: /* Counter Register */
- ret = s->reg_OSMR0 - (uint32_t)ptimer_get_count(s->ptimer);
- break;
- case 0x14: /* Status Register */
- ret = s->reg_OSSR;
- break;
- case 0x1c: /* Interrupt Enable Register */
- ret = s->reg_OIER;
- break;
- default:
- qemu_log_mask(LOG_GUEST_ERROR,
- "%s: Bad read offset 0x%"HWADDR_PRIx"\n",
- __func__, offset);
- }
- DPRINTF("offset 0x%x, value 0x%x\n", offset, ret);
- return ret;
-}
-
-static void puv3_ost_write(void *opaque, hwaddr offset,
- uint64_t value, unsigned size)
-{
- PUV3OSTState *s = opaque;
-
- DPRINTF("offset 0x%x, value 0x%x\n", offset, value);
- switch (offset) {
- case 0x00: /* Match Register 0 */
- ptimer_transaction_begin(s->ptimer);
- s->reg_OSMR0 = value;
- if (s->reg_OSMR0 > s->reg_OSCR) {
- ptimer_set_count(s->ptimer, s->reg_OSMR0 - s->reg_OSCR);
- } else {
- ptimer_set_count(s->ptimer, s->reg_OSMR0 +
- (0xffffffff - s->reg_OSCR));
- }
- ptimer_run(s->ptimer, 2);
- ptimer_transaction_commit(s->ptimer);
- break;
- case 0x14: /* Status Register */
- assert(value == 0);
- if (s->reg_OSSR) {
- s->reg_OSSR = value;
- qemu_irq_lower(s->irq);
- }
- break;
- case 0x1c: /* Interrupt Enable Register */
- s->reg_OIER = value;
- break;
- default:
- qemu_log_mask(LOG_GUEST_ERROR,
- "%s: Bad write offset 0x%"HWADDR_PRIx"\n",
- __func__, offset);
- }
-}
-
-static const MemoryRegionOps puv3_ost_ops = {
- .read = puv3_ost_read,
- .write = puv3_ost_write,
- .impl = {
- .min_access_size = 4,
- .max_access_size = 4,
- },
- .endianness = DEVICE_NATIVE_ENDIAN,
-};
-
-static void puv3_ost_tick(void *opaque)
-{
- PUV3OSTState *s = opaque;
-
- DPRINTF("ost hit when ptimer counter from 0x%x to 0x%x!\n",
- s->reg_OSCR, s->reg_OSMR0);
-
- s->reg_OSCR = s->reg_OSMR0;
- if (s->reg_OIER) {
- s->reg_OSSR = 1;
- qemu_irq_raise(s->irq);
- }
-}
-
-static void puv3_ost_realize(DeviceState *dev, Error **errp)
-{
- PUV3OSTState *s = PUV3_OST(dev);
- SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
-
- s->reg_OIER = 0;
- s->reg_OSSR = 0;
- s->reg_OSMR0 = 0;
- s->reg_OSCR = 0;
-
- sysbus_init_irq(sbd, &s->irq);
-
- s->ptimer = ptimer_init(puv3_ost_tick, s, PTIMER_POLICY_DEFAULT);
- ptimer_transaction_begin(s->ptimer);
- ptimer_set_freq(s->ptimer, 50 * 1000 * 1000);
- ptimer_transaction_commit(s->ptimer);
-
- memory_region_init_io(&s->iomem, OBJECT(s), &puv3_ost_ops, s, "puv3_ost",
- PUV3_REGS_OFFSET);
- sysbus_init_mmio(sbd, &s->iomem);
-}
-
-static void puv3_ost_class_init(ObjectClass *klass, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(klass);
-
- dc->realize = puv3_ost_realize;
-}
-
-static const TypeInfo puv3_ost_info = {
- .name = TYPE_PUV3_OST,
- .parent = TYPE_SYS_BUS_DEVICE,
- .instance_size = sizeof(PUV3OSTState),
- .class_init = puv3_ost_class_init,
-};
-
-static void puv3_ost_register_type(void)
-{
- type_register_static(&puv3_ost_info);
-}
-
-type_init(puv3_ost_register_type)
diff --git a/hw/timer/trace-events b/hw/timer/trace-events
index f8b9db25c2..029fb56280 100644
--- a/hw/timer/trace-events
+++ b/hw/timer/trace-events
@@ -24,23 +24,6 @@ grlib_gptimer_hit(int id) "timer:%d HIT"
grlib_gptimer_readl(int id, uint64_t addr, uint32_t val) "timer:%d addr 0x%"PRIx64" 0x%x"
grlib_gptimer_writel(int id, uint64_t addr, uint32_t val) "timer:%d addr 0x%"PRIx64" 0x%x"
-# lm32_timer.c
-lm32_timer_memory_write(uint32_t addr, uint32_t value) "addr 0x%08x value 0x%08x"
-lm32_timer_memory_read(uint32_t addr, uint32_t value) "addr 0x%08x value 0x%08x"
-lm32_timer_hit(void) "timer hit"
-lm32_timer_irq_state(int level) "irq state %d"
-
-# milkymist-sysctl.c
-milkymist_sysctl_memory_read(uint32_t addr, uint32_t value) "addr 0x%08x value 0x%08x"
-milkymist_sysctl_memory_write(uint32_t addr, uint32_t value) "addr 0x%08x value 0x%08x"
-milkymist_sysctl_icap_write(uint32_t value) "value 0x%08x"
-milkymist_sysctl_start_timer0(void) "Start timer0"
-milkymist_sysctl_stop_timer0(void) "Stop timer0"
-milkymist_sysctl_start_timer1(void) "Start timer1"
-milkymist_sysctl_stop_timer1(void) "Stop timer1"
-milkymist_sysctl_pulse_irq_timer0(void) "Pulse IRQ Timer0"
-milkymist_sysctl_pulse_irq_timer1(void) "Pulse IRQ Timer1"
-
# aspeed_timer.c
aspeed_timer_ctrl_enable(uint8_t i, bool enable) "Timer %" PRIu8 ": %d"
aspeed_timer_ctrl_external_clock(uint8_t i, bool enable) "Timer %" PRIu8 ": %d"
diff --git a/hw/unicore32/Kconfig b/hw/unicore32/Kconfig
deleted file mode 100644
index 4443a29dd2..0000000000
--- a/hw/unicore32/Kconfig
+++ /dev/null
@@ -1,5 +0,0 @@
-config PUV3
- bool
- select ISA_BUS
- select PCKBD
- select PTIMER
diff --git a/hw/unicore32/meson.build b/hw/unicore32/meson.build
deleted file mode 100644
index fc26d6bcab..0000000000
--- a/hw/unicore32/meson.build
+++ /dev/null
@@ -1,5 +0,0 @@
-unicore32_ss = ss.source_set()
-# PKUnity-v3 SoC and board information
-unicore32_ss.add(when: 'CONFIG_PUV3', if_true: files('puv3.c'))
-
-hw_arch += {'unicore32': unicore32_ss}
diff --git a/hw/unicore32/puv3.c b/hw/unicore32/puv3.c
deleted file mode 100644
index eacacb4249..0000000000
--- a/hw/unicore32/puv3.c
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- * Generic PKUnity SoC machine and board descriptor
- *
- * Copyright (C) 2010-2012 Guan Xuetao
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation, or any later version.
- * See the COPYING file in the top-level directory.
- */
-
-#include "qemu/osdep.h"
-#include "qapi/error.h"
-#include "cpu.h"
-#include "ui/console.h"
-#include "hw/boards.h"
-#include "hw/loader.h"
-#include "sysemu/qtest.h"
-#include "hw/unicore32/puv3.h"
-#include "hw/input/i8042.h"
-#include "hw/irq.h"
-
-#define KERNEL_LOAD_ADDR 0x03000000
-#define KERNEL_MAX_SIZE 0x00800000 /* Just a guess */
-
-/* PKUnity System bus (AHB): 0xc0000000 - 0xedffffff (640MB) */
-#define PUV3_DMA_BASE (0xc0200000) /* AHB-4 */
-
-/* PKUnity Peripheral bus (APB): 0xee000000 - 0xefffffff (128MB) */
-#define PUV3_GPIO_BASE (0xee500000) /* APB-5 */
-#define PUV3_INTC_BASE (0xee600000) /* APB-6 */
-#define PUV3_OST_BASE (0xee800000) /* APB-8 */
-#define PUV3_PM_BASE (0xeea00000) /* APB-10 */
-#define PUV3_PS2_BASE (0xeeb00000) /* APB-11 */
-
-static void puv3_intc_cpu_handler(void *opaque, int irq, int level)
-{
- UniCore32CPU *cpu = opaque;
- CPUState *cs = CPU(cpu);
-
- assert(irq == 0);
- if (level) {
- cpu_interrupt(cs, CPU_INTERRUPT_HARD);
- } else {
- cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD);
- }
-}
-
-static void puv3_soc_init(CPUUniCore32State *env)
-{
- qemu_irq cpu_intc, irqs[PUV3_IRQS_NR];
- DeviceState *dev;
- MemoryRegion *i8042 = g_new(MemoryRegion, 1);
- int i;
-
- /* Initialize interrupt controller */
- cpu_intc = qemu_allocate_irq(puv3_intc_cpu_handler,
- env_archcpu(env), 0);
- dev = sysbus_create_simple("puv3_intc", PUV3_INTC_BASE, cpu_intc);
- for (i = 0; i < PUV3_IRQS_NR; i++) {
- irqs[i] = qdev_get_gpio_in(dev, i);
- }
-
- /* Initialize minimal necessary devices for kernel booting */
- sysbus_create_simple("puv3_pm", PUV3_PM_BASE, NULL);
- sysbus_create_simple("puv3_dma", PUV3_DMA_BASE, NULL);
- sysbus_create_simple("puv3_ost", PUV3_OST_BASE, irqs[PUV3_IRQS_OST0]);
- sysbus_create_varargs("puv3_gpio", PUV3_GPIO_BASE,
- irqs[PUV3_IRQS_GPIOLOW0], irqs[PUV3_IRQS_GPIOLOW1],
- irqs[PUV3_IRQS_GPIOLOW2], irqs[PUV3_IRQS_GPIOLOW3],
- irqs[PUV3_IRQS_GPIOLOW4], irqs[PUV3_IRQS_GPIOLOW5],
- irqs[PUV3_IRQS_GPIOLOW6], irqs[PUV3_IRQS_GPIOLOW7],
- irqs[PUV3_IRQS_GPIOHIGH], NULL);
-
- /* Keyboard (i8042), mouse disabled for nographic */
- i8042_mm_init(irqs[PUV3_IRQS_PS2_KBD], NULL, i8042, PUV3_REGS_OFFSET, 4);
- memory_region_add_subregion(get_system_memory(), PUV3_PS2_BASE, i8042);
-}
-
-static void puv3_board_init(CPUUniCore32State *env, ram_addr_t ram_size)
-{
- MemoryRegion *ram_memory = g_new(MemoryRegion, 1);
-
- /* SDRAM at address zero. */
- memory_region_init_ram(ram_memory, NULL, "puv3.ram", ram_size,
- &error_fatal);
- memory_region_add_subregion(get_system_memory(), 0, ram_memory);
-}
-
-static const GraphicHwOps no_ops;
-
-static void puv3_load_kernel(const char *kernel_filename)
-{
- int size;
-
- if (kernel_filename == NULL && qtest_enabled()) {
- return;
- }
- if (kernel_filename == NULL) {
- error_report("kernel parameter cannot be empty");
- exit(1);
- }
-
- /* only zImage format supported */
- size = load_image_targphys(kernel_filename, KERNEL_LOAD_ADDR,
- KERNEL_MAX_SIZE);
- if (size < 0) {
- error_report("Load kernel error: '%s'", kernel_filename);
- exit(1);
- }
-
- /* cheat curses that we have a graphic console, only under ocd console */
- graphic_console_init(NULL, 0, &no_ops, NULL);
-}
-
-static void puv3_init(MachineState *machine)
-{
- ram_addr_t ram_size = machine->ram_size;
- const char *kernel_filename = machine->kernel_filename;
- const char *initrd_filename = machine->initrd_filename;
- CPUUniCore32State *env;
- UniCore32CPU *cpu;
-
- if (initrd_filename) {
- error_report("Please use kernel built-in initramdisk");
- exit(1);
- }
-
- cpu = UNICORE32_CPU(cpu_create(machine->cpu_type));
- env = &cpu->env;
-
- puv3_soc_init(env);
- puv3_board_init(env, ram_size);
- puv3_load_kernel(kernel_filename);
-}
-
-static void puv3_machine_init(MachineClass *mc)
-{
- mc->desc = "PKUnity Version-3 based on UniCore32";
- mc->init = puv3_init;
- mc->is_default = true;
- mc->default_cpu_type = UNICORE32_CPU_TYPE_NAME("UniCore-II");
-}
-
-DEFINE_MACHINE("puv3", puv3_machine_init)
diff --git a/hw/usb/quirks-ftdi-ids.h b/hw/usb/quirks-ftdi-ids.h
index 57c12ef662..01aca55ca7 100644
--- a/hw/usb/quirks-ftdi-ids.h
+++ b/hw/usb/quirks-ftdi-ids.h
@@ -1222,12 +1222,6 @@
#define FTDI_SCIENCESCOPE_HS_LOGBOOK_PID 0xFF1D
/*
- * Milkymist One JTAG/Serial
- */
-#define QIHARDWARE_VID 0x20B7
-#define MILKYMISTONE_JTAGSERIAL_PID 0x0713
-
-/*
* CTI GmbH RS485 Converter http://www.cti-lean.com/
*/
/* USB-485-Mini*/
diff --git a/hw/usb/quirks.h b/hw/usb/quirks.h
index 50ef2f9c2e..c3e595f40b 100644
--- a/hw/usb/quirks.h
+++ b/hw/usb/quirks.h
@@ -904,7 +904,6 @@ static const struct usb_device_id usbredir_ftdi_serial_ids[] = {
{ USB_DEVICE(FTDI_VID, FTDI_SCIENCESCOPE_HS_LOGBOOK_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_CINTERION_MC55I_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_DOTEC_PID) },
- { USB_DEVICE(QIHARDWARE_VID, MILKYMISTONE_JTAGSERIAL_PID) },
{ USB_DEVICE(ST_VID, ST_STMCLT1030_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_RF_R106) },
{ USB_DEVICE(FTDI_VID, FTDI_DISTORTEC_JTAG_LOCK_PICK_PID) },
diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c
index 01d2101d09..8f2fb9f10b 100644
--- a/hw/virtio/vhost-vdpa.c
+++ b/hw/virtio/vhost-vdpa.c
@@ -371,8 +371,8 @@ static int vhost_vdpa_set_backend_cap(struct vhost_dev *dev)
return 0;
}
-int vhost_vdpa_get_device_id(struct vhost_dev *dev,
- uint32_t *device_id)
+static int vhost_vdpa_get_device_id(struct vhost_dev *dev,
+ uint32_t *device_id)
{
int ret;
ret = vhost_vdpa_call(dev, VHOST_VDPA_GET_DEVICE_ID, device_id);
diff --git a/hw/virtio/virtio-balloon.c b/hw/virtio/virtio-balloon.c
index d120bf8f43..4b5d9e5e50 100644
--- a/hw/virtio/virtio-balloon.c
+++ b/hw/virtio/virtio-balloon.c
@@ -663,9 +663,6 @@ virtio_balloon_free_page_hint_notify(NotifierWithReturn *n, void *data)
}
switch (pnd->reason) {
- case PRECOPY_NOTIFY_SETUP:
- precopy_enable_free_page_optimization();
- break;
case PRECOPY_NOTIFY_BEFORE_BITMAP_SYNC:
virtio_balloon_free_page_stop(dev);
break;
@@ -685,6 +682,7 @@ virtio_balloon_free_page_hint_notify(NotifierWithReturn *n, void *data)
*/
virtio_balloon_free_page_done(dev);
break;
+ case PRECOPY_NOTIFY_SETUP:
case PRECOPY_NOTIFY_COMPLETE:
break;
default:
diff --git a/hw/virtio/virtio-mem.c b/hw/virtio/virtio-mem.c
index 655824ff81..75aa7d6f1b 100644
--- a/hw/virtio/virtio-mem.c
+++ b/hw/virtio/virtio-mem.c
@@ -902,9 +902,6 @@ static int virtio_mem_precopy_notify(NotifierWithReturn *n, void *data)
PrecopyNotifyData *pnd = data;
switch (pnd->reason) {
- case PRECOPY_NOTIFY_SETUP:
- precopy_enable_free_page_optimization();
- break;
case PRECOPY_NOTIFY_AFTER_BITMAP_SYNC:
virtio_mem_precopy_exclude_unplugged(vmem);
break;
diff --git a/hw/virtio/virtio-mmio.c b/hw/virtio/virtio-mmio.c
index 342c918ea7..5952471b38 100644
--- a/hw/virtio/virtio-mmio.c
+++ b/hw/virtio/virtio-mmio.c
@@ -36,7 +36,9 @@
static bool virtio_mmio_ioeventfd_enabled(DeviceState *d)
{
- return kvm_eventfds_enabled();
+ VirtIOMMIOProxy *proxy = VIRTIO_MMIO(d);
+
+ return (proxy->flags & VIRTIO_IOMMIO_FLAG_USE_IOEVENTFD) != 0;
}
static int virtio_mmio_ioeventfd_assign(DeviceState *d,
@@ -720,6 +722,8 @@ static Property virtio_mmio_properties[] = {
DEFINE_PROP_BOOL("format_transport_address", VirtIOMMIOProxy,
format_transport_address, true),
DEFINE_PROP_BOOL("force-legacy", VirtIOMMIOProxy, legacy, true),
+ DEFINE_PROP_BIT("ioeventfd", VirtIOMMIOProxy, flags,
+ VIRTIO_IOMMIO_FLAG_USE_IOEVENTFD_BIT, true),
DEFINE_PROP_END_OF_LIST(),
};
@@ -731,6 +735,11 @@ static void virtio_mmio_realizefn(DeviceState *d, Error **errp)
qbus_create_inplace(&proxy->bus, sizeof(proxy->bus), TYPE_VIRTIO_MMIO_BUS,
d, NULL);
sysbus_init_irq(sbd, &proxy->irq);
+
+ if (!kvm_eventfds_enabled()) {
+ proxy->flags &= ~VIRTIO_IOMMIO_FLAG_USE_IOEVENTFD;
+ }
+
if (proxy->legacy) {
memory_region_init_io(&proxy->iomem, OBJECT(d),
&virtio_legacy_mem_ops, proxy,
diff --git a/include/block/block_int.h b/include/block/block_int.h
index c823f5b1b3..b2c8b09d0f 100644
--- a/include/block/block_int.h
+++ b/include/block/block_int.h
@@ -357,7 +357,7 @@ struct BlockDriver {
* of in-flight requests, so don't waste the time if possible.
*
* One example usage is to avoid waiting for an nbd target node reconnect
- * timeout during job-cancel.
+ * timeout during job-cancel with force=true.
*/
void (*bdrv_cancel_in_flight)(BlockDriverState *bs);
@@ -954,12 +954,8 @@ struct BlockDriverState {
*/
int64_t total_sectors;
- /* Callback before write request is processed */
- NotifierWithReturnList before_write_notifiers;
-
/* threshold limit for writes, in bytes. "High water mark". */
uint64_t write_threshold_offset;
- NotifierWithReturn write_threshold_notifier;
/* Writing to the list requires the BQL _and_ the dirty_bitmap_mutex.
* Reading from the list can be done with either the BQL or the
@@ -1085,15 +1081,6 @@ bool bdrv_backing_overridden(BlockDriverState *bs);
/**
- * bdrv_add_before_write_notifier:
- *
- * Register a callback that is invoked before write requests are processed but
- * after any throttling or waiting for overlapping requests.
- */
-void bdrv_add_before_write_notifier(BlockDriverState *bs,
- NotifierWithReturn *notifier);
-
-/**
* bdrv_add_aio_context_notifier:
*
* If a long-running job intends to be always run in the same AioContext as a
diff --git a/include/block/write-threshold.h b/include/block/write-threshold.h
index c646f267a4..f50f923e7e 100644
--- a/include/block/write-threshold.h
+++ b/include/block/write-threshold.h
@@ -13,7 +13,7 @@
#ifndef BLOCK_WRITE_THRESHOLD_H
#define BLOCK_WRITE_THRESHOLD_H
-#include "block/block_int.h"
+#include "qemu/typedefs.h"
/*
* bdrv_write_threshold_set:
@@ -36,27 +36,12 @@ void bdrv_write_threshold_set(BlockDriverState *bs, uint64_t threshold_bytes);
uint64_t bdrv_write_threshold_get(const BlockDriverState *bs);
/*
- * bdrv_write_threshold_is_set
+ * bdrv_write_threshold_check_write
*
- * Tell if a write threshold is set for a given BDS.
+ * Check whether the specified request exceeds the write threshold.
+ * If so, send a corresponding event and disable write threshold checking.
*/
-bool bdrv_write_threshold_is_set(const BlockDriverState *bs);
-
-/*
- * bdrv_write_threshold_exceeded
- *
- * Return the extent of a write request that exceeded the threshold,
- * or zero if the request is below the threshold.
- * Return zero also if the threshold was not set.
- *
- * NOTE: here we assume the following holds for each request this code
- * deals with:
- *
- * assert((req->offset + req->bytes) <= UINT64_MAX)
- *
- * Please not there is *not* an actual C assert().
- */
-uint64_t bdrv_write_threshold_exceeded(const BlockDriverState *bs,
- const BdrvTrackedRequest *req);
+void bdrv_write_threshold_check_write(BlockDriverState *bs, int64_t offset,
+ int64_t bytes);
#endif
diff --git a/include/disas/dis-asm.h b/include/disas/dis-asm.h
index 4701445e80..524f29196d 100644
--- a/include/disas/dis-asm.h
+++ b/include/disas/dis-asm.h
@@ -249,8 +249,6 @@ enum bfd_architecture
#define bfd_mach_nios2 0
#define bfd_mach_nios2r1 1
#define bfd_mach_nios2r2 2
- bfd_arch_lm32, /* Lattice Mico32 */
-#define bfd_mach_lm32 1
bfd_arch_rx, /* Renesas RX */
#define bfd_mach_rx 0x75
#define bfd_mach_rx_v2 0x76
@@ -443,7 +441,6 @@ int print_insn_m32r (bfd_vma, disassemble_info*);
int print_insn_m88k (bfd_vma, disassemble_info*);
int print_insn_mn10200 (bfd_vma, disassemble_info*);
int print_insn_mn10300 (bfd_vma, disassemble_info*);
-int print_insn_moxie (bfd_vma, disassemble_info*);
int print_insn_ns32k (bfd_vma, disassemble_info*);
int print_insn_big_powerpc (bfd_vma, disassemble_info*);
int print_insn_little_powerpc (bfd_vma, disassemble_info*);
@@ -458,7 +455,6 @@ int print_insn_crisv32 (bfd_vma, disassemble_info*);
int print_insn_crisv10 (bfd_vma, disassemble_info*);
int print_insn_microblaze (bfd_vma, disassemble_info*);
int print_insn_ia64 (bfd_vma, disassemble_info*);
-int print_insn_lm32 (bfd_vma, disassemble_info*);
int print_insn_big_nios2 (bfd_vma, disassemble_info*);
int print_insn_little_nios2 (bfd_vma, disassemble_info*);
int print_insn_xtensa (bfd_vma, disassemble_info*);
diff --git a/include/elf.h b/include/elf.h
index 78237c9a87..033bcc9576 100644
--- a/include/elf.h
+++ b/include/elf.h
@@ -174,9 +174,8 @@ typedef struct mips_elf_abiflags_v0 {
#define EM_OPENRISC 92 /* OpenCores OpenRISC */
-#define EM_UNICORE32 110 /* UniCore32 */
-
#define EM_HEXAGON 164 /* Qualcomm Hexagon */
+
#define EM_RX 173 /* Renesas RX family */
#define EM_RISCV 243 /* RISC-V */
@@ -206,9 +205,6 @@ typedef struct mips_elf_abiflags_v0 {
#define EM_AARCH64 183
-#define EM_MOXIE 223 /* Moxie processor family */
-#define EM_MOXIE_OLD 0xFEED
-
#define EF_AVR_MACH 0x7F /* Mask for AVR e_flags to get core type */
/* This is the info that is needed to parse the dynamic section of the file */
diff --git a/include/exec/cpu-common.h b/include/exec/cpu-common.h
index 5a0a2d93e0..ccabed4003 100644
--- a/include/exec/cpu-common.h
+++ b/include/exec/cpu-common.h
@@ -57,6 +57,7 @@ const char *qemu_ram_get_idstr(RAMBlock *rb);
void *qemu_ram_get_host_addr(RAMBlock *rb);
ram_addr_t qemu_ram_get_offset(RAMBlock *rb);
ram_addr_t qemu_ram_get_used_length(RAMBlock *rb);
+ram_addr_t qemu_ram_get_max_length(RAMBlock *rb);
bool qemu_ram_is_shared(RAMBlock *rb);
bool qemu_ram_is_uf_zeroable(RAMBlock *rb);
void qemu_ram_set_uf_zeroable(RAMBlock *rb);
diff --git a/include/exec/memory.h b/include/exec/memory.h
index 5728a681b2..c8b9088924 100644
--- a/include/exec/memory.h
+++ b/include/exec/memory.h
@@ -131,7 +131,7 @@ typedef struct IOMMUTLBEvent {
#define RAM_SHARED (1 << 1)
/* Only a portion of RAM (used_length) is actually used, and migrated.
- * This used_length size can change across reboots.
+ * Resizing RAM while migrating can result in the migration being canceled.
*/
#define RAM_RESIZEABLE (1 << 2)
@@ -955,7 +955,9 @@ void memory_region_init_ram_shared_nomigrate(MemoryRegion *mr,
* RAM. Accesses into the region will
* modify memory directly. Only an initial
* portion of this RAM is actually used.
- * The used size can change across reboots.
+ * Changing the size while migrating
+ * can result in the migration being
+ * canceled.
*
* @mr: the #MemoryRegion to be initialized.
* @owner: the object that tracks the region's reference count
@@ -1586,8 +1588,8 @@ void *memory_region_get_ram_ptr(MemoryRegion *mr);
/* memory_region_ram_resize: Resize a RAM region.
*
- * Only legal before guest might have detected the memory size: e.g. on
- * incoming migration, or right after reset.
+ * Resizing RAM while migrating can result in the migration being canceled.
+ * Care has to be taken if the guest might have already detected the memory.
*
* @mr: a memory region created with @memory_region_init_resizeable_ram.
* @newsize: the new size the region
diff --git a/include/exec/poison.h b/include/exec/poison.h
index 4cd3f8abb4..7ad4ad18e8 100644
--- a/include/exec/poison.h
+++ b/include/exec/poison.h
@@ -4,6 +4,8 @@
#ifndef HW_POISON_H
#define HW_POISON_H
+#include "config-poison.h"
+
#pragma GCC poison TARGET_I386
#pragma GCC poison TARGET_X86_64
#pragma GCC poison TARGET_AARCH64
@@ -12,7 +14,6 @@
#pragma GCC poison TARGET_CRIS
#pragma GCC poison TARGET_HEXAGON
#pragma GCC poison TARGET_HPPA
-#pragma GCC poison TARGET_LM32
#pragma GCC poison TARGET_M68K
#pragma GCC poison TARGET_MICROBLAZE
#pragma GCC poison TARGET_MIPS
@@ -20,7 +21,6 @@
#pragma GCC poison TARGET_ABI_MIPSO32
#pragma GCC poison TARGET_MIPS64
#pragma GCC poison TARGET_ABI_MIPSN64
-#pragma GCC poison TARGET_MOXIE
#pragma GCC poison TARGET_NIOS2
#pragma GCC poison TARGET_OPENRISC
#pragma GCC poison TARGET_PPC
@@ -32,7 +32,6 @@
#pragma GCC poison TARGET_SPARC
#pragma GCC poison TARGET_SPARC64
#pragma GCC poison TARGET_TRICORE
-#pragma GCC poison TARGET_UNICORE32
#pragma GCC poison TARGET_XTENSA
#pragma GCC poison TARGET_ALIGNED_ONLY
@@ -74,12 +73,10 @@
#pragma GCC poison CONFIG_HPPA_DIS
#pragma GCC poison CONFIG_I386_DIS
#pragma GCC poison CONFIG_HEXAGON_DIS
-#pragma GCC poison CONFIG_LM32_DIS
#pragma GCC poison CONFIG_M68K_DIS
#pragma GCC poison CONFIG_MICROBLAZE_DIS
#pragma GCC poison CONFIG_MIPS_DIS
#pragma GCC poison CONFIG_NANOMIPS_DIS
-#pragma GCC poison CONFIG_MOXIE_DIS
#pragma GCC poison CONFIG_NIOS2_DIS
#pragma GCC poison CONFIG_PPC_DIS
#pragma GCC poison CONFIG_RISCV_DIS
@@ -88,8 +85,12 @@
#pragma GCC poison CONFIG_SPARC_DIS
#pragma GCC poison CONFIG_XTENSA_DIS
+#pragma GCC poison CONFIG_HAX
+#pragma GCC poison CONFIG_HVF
#pragma GCC poison CONFIG_LINUX_USER
#pragma GCC poison CONFIG_KVM
#pragma GCC poison CONFIG_SOFTMMU
+#pragma GCC poison CONFIG_WHPX
+#pragma GCC poison CONFIG_XEN
#endif
diff --git a/include/exec/ramblock.h b/include/exec/ramblock.h
index 07d50864d8..664701b759 100644
--- a/include/exec/ramblock.h
+++ b/include/exec/ramblock.h
@@ -59,6 +59,16 @@ struct RAMBlock {
*/
unsigned long *clear_bmap;
uint8_t clear_bmap_shift;
+
+ /*
+ * RAM block length that corresponds to the used_length on the migration
+ * source (after RAM block sizes were synchronized). Especially, after
+ * starting to run the guest, used_length and postcopy_length can differ.
+ * Used to register/unregister uffd handlers and as the size of the received
+ * bitmap. Receiving any page beyond this length will bail out, as it
+ * could not have been valid on the source.
+ */
+ ram_addr_t postcopy_length;
};
#endif
#endif
diff --git a/include/exec/ramlist.h b/include/exec/ramlist.h
index 26704aa3b0..ece6497ee2 100644
--- a/include/exec/ramlist.h
+++ b/include/exec/ramlist.h
@@ -65,15 +65,20 @@ void qemu_mutex_lock_ramlist(void);
void qemu_mutex_unlock_ramlist(void);
struct RAMBlockNotifier {
- void (*ram_block_added)(RAMBlockNotifier *n, void *host, size_t size);
- void (*ram_block_removed)(RAMBlockNotifier *n, void *host, size_t size);
+ void (*ram_block_added)(RAMBlockNotifier *n, void *host, size_t size,
+ size_t max_size);
+ void (*ram_block_removed)(RAMBlockNotifier *n, void *host, size_t size,
+ size_t max_size);
+ void (*ram_block_resized)(RAMBlockNotifier *n, void *host, size_t old_size,
+ size_t new_size);
QLIST_ENTRY(RAMBlockNotifier) next;
};
void ram_block_notifier_add(RAMBlockNotifier *n);
void ram_block_notifier_remove(RAMBlockNotifier *n);
-void ram_block_notify_add(void *host, size_t size);
-void ram_block_notify_remove(void *host, size_t size);
+void ram_block_notify_add(void *host, size_t size, size_t max_size);
+void ram_block_notify_remove(void *host, size_t size, size_t max_size);
+void ram_block_notify_resize(void *host, size_t old_size, size_t new_size);
void ram_block_dump(Monitor *mon);
diff --git a/include/hw/char/lm32_juart.h b/include/hw/char/lm32_juart.h
deleted file mode 100644
index 6fce278326..0000000000
--- a/include/hw/char/lm32_juart.h
+++ /dev/null
@@ -1,13 +0,0 @@
-#ifndef QEMU_HW_CHAR_LM32_JUART_H
-#define QEMU_HW_CHAR_LM32_JUART_H
-
-#include "hw/qdev-core.h"
-
-#define TYPE_LM32_JUART "lm32-juart"
-
-uint32_t lm32_juart_get_jtx(DeviceState *d);
-uint32_t lm32_juart_get_jrx(DeviceState *d);
-void lm32_juart_set_jtx(DeviceState *d, uint32_t jtx);
-void lm32_juart_set_jrx(DeviceState *d, uint32_t jrx);
-
-#endif /* QEMU_HW_CHAR_LM32_JUART_H */
diff --git a/include/hw/display/milkymist_tmu2.h b/include/hw/display/milkymist_tmu2.h
deleted file mode 100644
index fdce9535a1..0000000000
--- a/include/hw/display/milkymist_tmu2.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * QEMU model of the Milkymist texture mapping unit.
- *
- * Copyright (c) 2010 Michael Walle <michael@walle.cc>
- * Copyright (c) 2010 Sebastien Bourdeauducq
- * <sebastien.bourdeauducq@lekernel.net>
- *
- * 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.1 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/>.
- *
- *
- * Specification available at:
- * http://milkymist.walle.cc/socdoc/tmu2.pdf
- *
- */
-
-#ifndef HW_DISPLAY_MILKYMIST_TMU2_H
-#define HW_DISPLAY_MILKYMIST_TMU2_H
-
-#include "exec/hwaddr.h"
-#include "hw/qdev-core.h"
-
-#if defined(CONFIG_X11) && defined(CONFIG_OPENGL)
-DeviceState *milkymist_tmu2_create(hwaddr base, qemu_irq irq);
-#else
-static inline DeviceState *milkymist_tmu2_create(hwaddr base, qemu_irq irq)
-{
- return NULL;
-}
-#endif
-
-#endif /* HW_DISPLAY_MILKYMIST_TMU2_H */
diff --git a/include/hw/elf_ops.h b/include/hw/elf_ops.h
index 6ee458e7bc..1c37cec4ae 100644
--- a/include/hw/elf_ops.h
+++ b/include/hw/elf_ops.h
@@ -368,14 +368,6 @@ static int glue(load_elf, SZ)(const char *name, int fd,
}
}
break;
- case EM_MOXIE:
- if (ehdr.e_machine != EM_MOXIE) {
- if (ehdr.e_machine != EM_MOXIE_OLD) {
- ret = ELF_LOAD_WRONG_ARCH;
- goto fail;
- }
- }
- break;
case EM_MIPS:
case EM_NANOMIPS:
if ((ehdr.e_machine != EM_MIPS) &&
diff --git a/include/hw/firmware/smbios.h b/include/hw/firmware/smbios.h
index 02a0ced0a0..5a0dd0c8cf 100644
--- a/include/hw/firmware/smbios.h
+++ b/include/hw/firmware/smbios.h
@@ -258,6 +258,17 @@ struct smbios_type_32 {
uint8_t boot_status;
} QEMU_PACKED;
+/* SMBIOS type 41 - Onboard Devices Extended Information */
+struct smbios_type_41 {
+ struct smbios_structure_header header;
+ uint8_t reference_designation_str;
+ uint8_t device_type;
+ uint8_t device_type_instance;
+ uint16_t segment_group_number;
+ uint8_t bus_number;
+ uint8_t device_number;
+} QEMU_PACKED;
+
/* SMBIOS type 127 -- End-of-table */
struct smbios_type_127 {
struct smbios_structure_header header;
@@ -273,5 +284,6 @@ void smbios_get_tables(MachineState *ms,
const struct smbios_phys_mem_area *mem_array,
const unsigned int mem_array_size,
uint8_t **tables, size_t *tables_len,
- uint8_t **anchor, size_t *anchor_len);
+ uint8_t **anchor, size_t *anchor_len,
+ Error **errp);
#endif /* QEMU_SMBIOS_H */
diff --git a/include/hw/i2c/i2c.h b/include/hw/i2c/i2c.h
index 277dd9f2d6..ff4129ea70 100644
--- a/include/hw/i2c/i2c.h
+++ b/include/hw/i2c/i2c.h
@@ -16,6 +16,7 @@ enum i2c_event {
I2C_NACK /* Masker NACKed a receive byte. */
};
+typedef struct I2CNodeList I2CNodeList;
#define TYPE_I2C_SLAVE "i2c-slave"
OBJECT_DECLARE_TYPE(I2CSlave, I2CSlaveClass,
@@ -39,6 +40,16 @@ struct I2CSlaveClass {
* return code is not used and should be zero.
*/
int (*event)(I2CSlave *s, enum i2c_event event);
+
+ /*
+ * Check if this device matches the address provided. Returns bool of
+ * true if it matches (or broadcast), and updates the device list, false
+ * otherwise.
+ *
+ * If broadcast is true, match should add the device and return true.
+ */
+ bool (*match_and_add)(I2CSlave *candidate, uint8_t address, bool broadcast,
+ I2CNodeList *current_devs);
};
struct I2CSlave {
@@ -58,9 +69,11 @@ struct I2CNode {
QLIST_ENTRY(I2CNode) next;
};
+typedef QLIST_HEAD(I2CNodeList, I2CNode) I2CNodeList;
+
struct I2CBus {
BusState qbus;
- QLIST_HEAD(, I2CNode) current_devs;
+ I2CNodeList current_devs;
uint8_t saved_address;
bool broadcast;
};
@@ -74,6 +87,8 @@ void i2c_nack(I2CBus *bus);
int i2c_send_recv(I2CBus *bus, uint8_t *data, bool send);
int i2c_send(I2CBus *bus, uint8_t data);
uint8_t i2c_recv(I2CBus *bus);
+bool i2c_scan_bus(I2CBus *bus, uint8_t address, bool broadcast,
+ I2CNodeList *current_devs);
/**
* Create an I2C slave device on the heap.
diff --git a/include/hw/i2c/i2c_mux_pca954x.h b/include/hw/i2c/i2c_mux_pca954x.h
new file mode 100644
index 0000000000..8aaf9bbc39
--- /dev/null
+++ b/include/hw/i2c/i2c_mux_pca954x.h
@@ -0,0 +1,19 @@
+#ifndef QEMU_I2C_MUX_PCA954X
+#define QEMU_I2C_MUX_PCA954X
+
+#include "hw/i2c/i2c.h"
+
+#define TYPE_PCA9546 "pca9546"
+#define TYPE_PCA9548 "pca9548"
+
+/**
+ * Retrieves the i2c bus associated with the specified channel on this i2c
+ * mux.
+ * @mux: an i2c mux device.
+ * @channel: the i2c channel requested
+ *
+ * Returns: a pointer to the associated i2c bus.
+ */
+I2CBus *pca954x_i2c_get_bus(I2CSlave *mux, uint8_t channel);
+
+#endif
diff --git a/include/hw/lm32/lm32_pic.h b/include/hw/lm32/lm32_pic.h
deleted file mode 100644
index 9e5e038437..0000000000
--- a/include/hw/lm32/lm32_pic.h
+++ /dev/null
@@ -1,10 +0,0 @@
-#ifndef QEMU_HW_LM32_PIC_H
-#define QEMU_HW_LM32_PIC_H
-
-
-uint32_t lm32_pic_get_ip(DeviceState *d);
-uint32_t lm32_pic_get_im(DeviceState *d);
-void lm32_pic_set_ip(DeviceState *d, uint32_t ip);
-void lm32_pic_set_im(DeviceState *d, uint32_t im);
-
-#endif /* QEMU_HW_LM32_PIC_H */
diff --git a/include/hw/mem/pc-dimm.h b/include/hw/mem/pc-dimm.h
index 3d3db82641..1473e6db62 100644
--- a/include/hw/mem/pc-dimm.h
+++ b/include/hw/mem/pc-dimm.h
@@ -56,9 +56,6 @@ struct PCDIMMDevice {
* PCDIMMDeviceClass:
* @realize: called after common dimm is realized so that the dimm based
* devices get the chance to do specified operations.
- * @get_vmstate_memory_region: returns #MemoryRegion which indicates the
- * memory of @dimm should be kept during live migration. Will not fail
- * after the device was realized.
*/
struct PCDIMMDeviceClass {
/* private */
@@ -66,8 +63,6 @@ struct PCDIMMDeviceClass {
/* public */
void (*realize)(PCDIMMDevice *dimm, Error **errp);
- MemoryRegion *(*get_vmstate_memory_region)(PCDIMMDevice *dimm,
- Error **errp);
};
void pc_dimm_pre_plug(PCDIMMDevice *dimm, MachineState *machine,
diff --git a/include/hw/unicore32/puv3.h b/include/hw/unicore32/puv3.h
deleted file mode 100644
index f587a1f622..0000000000
--- a/include/hw/unicore32/puv3.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Misc PKUnity SoC declarations
- *
- * Copyright (C) 2010-2012 Guan Xuetao
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation, or any later version.
- * See the COPYING file in the top-level directory.
- */
-
-#ifndef QEMU_HW_PUV3_H
-#define QEMU_HW_PUV3_H
-
-#define PUV3_REGS_OFFSET (0x1000) /* 4K is reasonable */
-
-/* Hardware interrupts */
-#define PUV3_IRQS_NR (32)
-
-#define PUV3_IRQS_GPIOLOW0 (0)
-#define PUV3_IRQS_GPIOLOW1 (1)
-#define PUV3_IRQS_GPIOLOW2 (2)
-#define PUV3_IRQS_GPIOLOW3 (3)
-#define PUV3_IRQS_GPIOLOW4 (4)
-#define PUV3_IRQS_GPIOLOW5 (5)
-#define PUV3_IRQS_GPIOLOW6 (6)
-#define PUV3_IRQS_GPIOLOW7 (7)
-#define PUV3_IRQS_GPIOHIGH (8)
-#define PUV3_IRQS_PS2_KBD (22)
-#define PUV3_IRQS_PS2_AUX (23)
-#define PUV3_IRQS_OST0 (26)
-
-/* All puv3_*.c use DPRINTF for debug. */
-#ifdef DEBUG_PUV3
-#define DPRINTF(fmt, ...) printf("%s: " fmt , __func__, ## __VA_ARGS__)
-#else
-#define DPRINTF(fmt, ...) do {} while (0)
-#endif
-
-#endif /* QEMU_HW_PUV3_H */
diff --git a/include/hw/virtio/vhost-vdpa.h b/include/hw/virtio/vhost-vdpa.h
index 9b81a409da..28ca65018e 100644
--- a/include/hw/virtio/vhost-vdpa.h
+++ b/include/hw/virtio/vhost-vdpa.h
@@ -22,6 +22,4 @@ typedef struct vhost_vdpa {
} VhostVDPA;
extern AddressSpace address_space_memory;
-extern int vhost_vdpa_get_device_id(struct vhost_dev *dev,
- uint32_t *device_id);
#endif
diff --git a/include/hw/virtio/virtio-mmio.h b/include/hw/virtio/virtio-mmio.h
index d4c4c386ab..090f7730e7 100644
--- a/include/hw/virtio/virtio-mmio.h
+++ b/include/hw/virtio/virtio-mmio.h
@@ -49,12 +49,17 @@ typedef struct VirtIOMMIOQueue {
uint32_t used[2];
} VirtIOMMIOQueue;
+#define VIRTIO_IOMMIO_FLAG_USE_IOEVENTFD_BIT 1
+#define VIRTIO_IOMMIO_FLAG_USE_IOEVENTFD \
+ (1 << VIRTIO_IOMMIO_FLAG_USE_IOEVENTFD_BIT)
+
struct VirtIOMMIOProxy {
/* Generic */
SysBusDevice parent_obj;
MemoryRegion iomem;
qemu_irq irq;
bool legacy;
+ uint32_t flags;
/* Guest accessible state needing migration and reset */
uint32_t host_features_sel;
uint32_t guest_features_sel;
diff --git a/include/migration/misc.h b/include/migration/misc.h
index 738675ef52..465906710d 100644
--- a/include/migration/misc.h
+++ b/include/migration/misc.h
@@ -37,7 +37,6 @@ void precopy_infrastructure_init(void);
void precopy_add_notifier(NotifierWithReturn *n);
void precopy_remove_notifier(NotifierWithReturn *n);
int precopy_notify(PrecopyNotifyReason reason, Error **errp);
-void precopy_enable_free_page_optimization(void);
void ram_mig_init(void);
void qemu_guest_free_page_hint(void *addr, size_t len);
diff --git a/include/qemu/job.h b/include/qemu/job.h
index efc6fa7544..41162ed494 100644
--- a/include/qemu/job.h
+++ b/include/qemu/job.h
@@ -254,7 +254,7 @@ struct JobDriver {
/**
* If the callback is not NULL, it will be invoked in job_cancel_async
*/
- void (*cancel)(Job *job);
+ void (*cancel)(Job *job, bool force);
/** Called when the job is freed */
diff --git a/include/sysemu/arch_init.h b/include/sysemu/arch_init.h
index 16da279696..e723c467eb 100644
--- a/include/sysemu/arch_init.h
+++ b/include/sysemu/arch_init.h
@@ -9,7 +9,6 @@ enum {
QEMU_ARCH_CRIS = (1 << 2),
QEMU_ARCH_I386 = (1 << 3),
QEMU_ARCH_M68K = (1 << 4),
- QEMU_ARCH_LM32 = (1 << 5),
QEMU_ARCH_MICROBLAZE = (1 << 6),
QEMU_ARCH_MIPS = (1 << 7),
QEMU_ARCH_PPC = (1 << 8),
@@ -18,8 +17,6 @@ enum {
QEMU_ARCH_SPARC = (1 << 11),
QEMU_ARCH_XTENSA = (1 << 12),
QEMU_ARCH_OPENRISC = (1 << 13),
- QEMU_ARCH_UNICORE32 = (1 << 14),
- QEMU_ARCH_MOXIE = (1 << 15),
QEMU_ARCH_TRICORE = (1 << 16),
QEMU_ARCH_NIOS2 = (1 << 17),
QEMU_ARCH_HPPA = (1 << 18),
diff --git a/include/sysemu/hax.h b/include/sysemu/hax.h
index 12fb54f990..247f0661d1 100644
--- a/include/sysemu/hax.h
+++ b/include/sysemu/hax.h
@@ -24,6 +24,8 @@
int hax_sync_vcpus(void);
+#ifdef NEED_CPU_H
+
#ifdef CONFIG_HAX
int hax_enabled(void);
@@ -34,4 +36,6 @@ int hax_enabled(void);
#endif /* CONFIG_HAX */
+#endif /* NEED_CPU_H */
+
#endif /* QEMU_HAX_H */
diff --git a/include/sysemu/hvf.h b/include/sysemu/hvf.h
index c98636bc81..bb70082e45 100644
--- a/include/sysemu/hvf.h
+++ b/include/sysemu/hvf.h
@@ -16,6 +16,8 @@
#include "qemu/accel.h"
#include "qom/object.h"
+#ifdef NEED_CPU_H
+
#ifdef CONFIG_HVF
uint32_t hvf_get_supported_cpuid(uint32_t func, uint32_t idx,
int reg);
@@ -26,6 +28,8 @@ extern bool hvf_allowed;
#define hvf_get_supported_cpuid(func, idx, reg) 0
#endif /* !CONFIG_HVF */
+#endif /* NEED_CPU_H */
+
#define TYPE_HVF_ACCEL ACCEL_CLASS_NAME("hvf")
typedef struct HVFState HVFState;
diff --git a/include/sysemu/whpx.h b/include/sysemu/whpx.h
index 8ca1c1c4ac..2889fa2278 100644
--- a/include/sysemu/whpx.h
+++ b/include/sysemu/whpx.h
@@ -13,6 +13,8 @@
#ifndef QEMU_WHPX_H
#define QEMU_WHPX_H
+#ifdef NEED_CPU_H
+
#ifdef CONFIG_WHPX
int whpx_enabled(void);
@@ -25,4 +27,6 @@ bool whpx_apic_in_platform(void);
#endif /* CONFIG_WHPX */
+#endif /* NEED_CPU_H */
+
#endif /* QEMU_WHPX_H */
diff --git a/job.c b/job.c
index 4aff13d95a..8775c1803b 100644
--- a/job.c
+++ b/job.c
@@ -716,7 +716,7 @@ static int job_finalize_single(Job *job)
static void job_cancel_async(Job *job, bool force)
{
if (job->driver->cancel) {
- job->driver->cancel(job);
+ job->driver->cancel(job, force);
}
if (job->user_paused) {
/* Do not call job_enter here, the caller will handle it. */
diff --git a/meson.build b/meson.build
index 0b41ff4118..8e16e05c2a 100644
--- a/meson.build
+++ b/meson.build
@@ -847,7 +847,7 @@ if 'CONFIG_VTE' in config_host
link_args: config_host['VTE_LIBS'].split())
endif
x11 = not_found
-if gtkx11.found() or 'lm32-softmmu' in target_dirs
+if gtkx11.found()
x11 = dependency('x11', method: 'pkg-config', required: gtkx11.found(),
kwargs: static_kwargs)
endif
@@ -1210,11 +1210,9 @@ disassemblers = {
'i386' : ['CONFIG_I386_DIS'],
'x86_64' : ['CONFIG_I386_DIS'],
'x32' : ['CONFIG_I386_DIS'],
- 'lm32' : ['CONFIG_LM32_DIS'],
'm68k' : ['CONFIG_M68K_DIS'],
'microblaze' : ['CONFIG_MICROBLAZE_DIS'],
'mips' : ['CONFIG_MIPS_DIS'],
- 'moxie' : ['CONFIG_MOXIE_DIS'],
'nios2' : ['CONFIG_NIOS2_DIS'],
'or1k' : ['CONFIG_OPENRISC_DIS'],
'ppc' : ['CONFIG_PPC_DIS'],
@@ -2635,7 +2633,6 @@ if have_block
summary_info += {'vvfat support': config_host.has_key('CONFIG_VVFAT')}
summary_info += {'qed support': config_host.has_key('CONFIG_QED')}
summary_info += {'parallels support': config_host.has_key('CONFIG_PARALLELS')}
- summary_info += {'sheepdog support': config_host.has_key('CONFIG_SHEEPDOG')}
summary_info += {'FUSE exports': fuse.found()}
endif
summary(summary_info, bool_yn: true, section: 'Block layer support')
diff --git a/migration/meson.build b/migration/meson.build
index 3ecedce94d..f8714dcb15 100644
--- a/migration/meson.build
+++ b/migration/meson.build
@@ -31,4 +31,5 @@ softmmu_ss.add(when: ['CONFIG_RDMA', rdma], if_true: files('rdma.c'))
softmmu_ss.add(when: 'CONFIG_LIVE_BLOCK_MIGRATION', if_true: files('block.c'))
softmmu_ss.add(when: zstd, if_true: files('multifd-zstd.c'))
-specific_ss.add(when: 'CONFIG_SOFTMMU', if_true: files('dirtyrate.c', 'ram.c'))
+specific_ss.add(when: 'CONFIG_SOFTMMU',
+ if_true: files('dirtyrate.c', 'ram.c', 'target.c'))
diff --git a/migration/migration.c b/migration/migration.c
index 8ca034136b..1885860d7b 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -60,10 +60,6 @@
#include "qemu/yank.h"
#include "sysemu/cpus.h"
-#ifdef CONFIG_VFIO
-#include "hw/vfio/vfio-common.h"
-#endif
-
#define MAX_THROTTLE (128 << 20) /* Migration transfer speed throttling */
/* Amount of time to allocate to each "chunk" of bandwidth-throttled
@@ -223,13 +219,18 @@ void migration_object_init(void)
dirty_bitmap_mig_init();
}
+void migration_cancel(void)
+{
+ migrate_fd_cancel(current_migration);
+}
+
void migration_shutdown(void)
{
/*
* Cancel the current migration - that will (eventually)
* stop the migration using this structure
*/
- migrate_fd_cancel(current_migration);
+ migration_cancel();
object_unref(OBJECT(current_migration));
/*
@@ -1059,41 +1060,27 @@ static void populate_disk_info(MigrationInfo *info)
}
}
-static void populate_vfio_info(MigrationInfo *info)
-{
-#ifdef CONFIG_VFIO
- if (vfio_mig_active()) {
- info->has_vfio = true;
- info->vfio = g_malloc0(sizeof(*info->vfio));
- info->vfio->transferred = vfio_mig_bytes_transferred();
- }
-#endif
-}
-
static void fill_source_migration_info(MigrationInfo *info)
{
MigrationState *s = migrate_get_current();
+ GSList *cur_blocker = migration_blockers;
- info->blocked = migration_is_blocked(NULL);
- info->has_blocked_reasons = info->blocked;
info->blocked_reasons = NULL;
- if (info->blocked) {
- GSList *cur_blocker = migration_blockers;
- /*
- * There are two types of reasons a migration might be blocked;
- * a) devices marked in VMState as non-migratable, and
- * b) Explicit migration blockers
- * We need to add both of them here.
- */
- qemu_savevm_non_migratable_list(&info->blocked_reasons);
+ /*
+ * There are two types of reasons a migration might be blocked;
+ * a) devices marked in VMState as non-migratable, and
+ * b) Explicit migration blockers
+ * We need to add both of them here.
+ */
+ qemu_savevm_non_migratable_list(&info->blocked_reasons);
- while (cur_blocker) {
- QAPI_LIST_PREPEND(info->blocked_reasons,
- g_strdup(error_get_pretty(cur_blocker->data)));
- cur_blocker = g_slist_next(cur_blocker);
- }
+ while (cur_blocker) {
+ QAPI_LIST_PREPEND(info->blocked_reasons,
+ g_strdup(error_get_pretty(cur_blocker->data)));
+ cur_blocker = g_slist_next(cur_blocker);
}
+ info->has_blocked_reasons = info->blocked_reasons != NULL;
switch (s->state) {
case MIGRATION_STATUS_NONE:
@@ -2310,7 +2297,7 @@ void qmp_migrate(const char *uri, bool has_blk, bool blk,
void qmp_migrate_cancel(Error **errp)
{
- migrate_fd_cancel(migrate_get_current());
+ migration_cancel();
}
void qmp_migrate_continue(MigrationStatus state, Error **errp)
diff --git a/migration/migration.h b/migration/migration.h
index db6708326b..b88bd8fe07 100644
--- a/migration/migration.h
+++ b/migration/migration.h
@@ -375,5 +375,8 @@ int foreach_not_ignored_block(RAMBlockIterFunc func, void *opaque);
void migration_make_urgent_request(void);
void migration_consume_urgent_request(void);
bool migration_rate_limit(void);
+void migration_cancel(void);
+
+void populate_vfio_info(MigrationInfo *info);
#endif
diff --git a/migration/multifd.c b/migration/multifd.c
index a6677c45c8..0a4803cfcc 100644
--- a/migration/multifd.c
+++ b/migration/multifd.c
@@ -361,7 +361,7 @@ static int multifd_recv_unfill_packet(MultiFDRecvParams *p, Error **errp)
if (offset > (block->used_length - qemu_target_page_size())) {
error_setg(errp, "multifd: offset too long %" PRIu64
" (max " RAM_ADDR_FMT ")",
- offset, block->max_length);
+ offset, block->used_length);
return -1;
}
p->pages->iov[i].iov_base = block->host + offset;
diff --git a/migration/postcopy-ram.c b/migration/postcopy-ram.c
index ab482adef1..2e9697bdd2 100644
--- a/migration/postcopy-ram.c
+++ b/migration/postcopy-ram.c
@@ -17,6 +17,7 @@
*/
#include "qemu/osdep.h"
+#include "qemu/rcu.h"
#include "exec/target_page.h"
#include "migration.h"
#include "qemu-file.h"
@@ -30,6 +31,7 @@
#include "qemu/error-report.h"
#include "trace.h"
#include "hw/boards.h"
+#include "exec/ramblock.h"
/* Arbitrary limit on size of each discard command,
* keeps them around ~200 bytes
@@ -453,6 +455,13 @@ static int init_range(RAMBlock *rb, void *opaque)
trace_postcopy_init_range(block_name, host_addr, offset, length);
/*
+ * Save the used_length before running the guest. In case we have to
+ * resize RAM blocks when syncing RAM block sizes from the source during
+ * precopy, we'll update it manually via the ram block notifier.
+ */
+ rb->postcopy_length = length;
+
+ /*
* We need the whole of RAM to be truly empty for postcopy, so things
* like ROMs and any data tables built during init must be zero'd
* - we're going to get the copy from the source anyway.
@@ -474,7 +483,7 @@ static int cleanup_range(RAMBlock *rb, void *opaque)
const char *block_name = qemu_ram_get_idstr(rb);
void *host_addr = qemu_ram_get_host_addr(rb);
ram_addr_t offset = qemu_ram_get_offset(rb);
- ram_addr_t length = qemu_ram_get_used_length(rb);
+ ram_addr_t length = rb->postcopy_length;
MigrationIncomingState *mis = opaque;
struct uffdio_range range_struct;
trace_postcopy_cleanup_range(block_name, host_addr, offset, length);
@@ -580,7 +589,7 @@ static int nhp_range(RAMBlock *rb, void *opaque)
const char *block_name = qemu_ram_get_idstr(rb);
void *host_addr = qemu_ram_get_host_addr(rb);
ram_addr_t offset = qemu_ram_get_offset(rb);
- ram_addr_t length = qemu_ram_get_used_length(rb);
+ ram_addr_t length = rb->postcopy_length;
trace_postcopy_nhp_range(block_name, host_addr, offset, length);
/*
@@ -624,7 +633,7 @@ static int ram_block_enable_notify(RAMBlock *rb, void *opaque)
struct uffdio_register reg_struct;
reg_struct.range.start = (uintptr_t)qemu_ram_get_host_addr(rb);
- reg_struct.range.len = qemu_ram_get_used_length(rb);
+ reg_struct.range.len = rb->postcopy_length;
reg_struct.mode = UFFDIO_REGISTER_MODE_MISSING;
/* Now tell our userfault_fd that it's responsible for this area */
diff --git a/migration/ram.c b/migration/ram.c
index ace8ad431c..60ea913c54 100644
--- a/migration/ram.c
+++ b/migration/ram.c
@@ -240,7 +240,7 @@ int64_t ramblock_recv_bitmap_send(QEMUFile *file,
return -1;
}
- nbits = block->used_length >> TARGET_PAGE_BITS;
+ nbits = block->postcopy_length >> TARGET_PAGE_BITS;
/*
* Make sure the tmp bitmap buffer is big enough, e.g., on 32bit
@@ -311,10 +311,6 @@ struct RAMState {
ram_addr_t last_page;
/* last ram version we have seen */
uint32_t last_version;
- /* We are in the first round */
- bool ram_bulk_stage;
- /* The free page optimization is enabled */
- bool fpo_enabled;
/* How many times we have dirty too many pages */
int dirty_rate_high_cnt;
/* these variables are used for bitmap sync */
@@ -330,6 +326,8 @@ struct RAMState {
uint64_t xbzrle_pages_prev;
/* Amount of xbzrle encoded bytes since the beginning of the period */
uint64_t xbzrle_bytes_prev;
+ /* Start using XBZRLE (e.g., after the first round). */
+ bool xbzrle_enabled;
/* compression statistics since the beginning of the period */
/* amount of count that no free thread to compress data */
@@ -383,15 +381,6 @@ int precopy_notify(PrecopyNotifyReason reason, Error **errp)
return notifier_with_return_list_notify(&precopy_notifier_list, &pnd);
}
-void precopy_enable_free_page_optimization(void)
-{
- if (!ram_state) {
- return;
- }
-
- ram_state->fpo_enabled = true;
-}
-
uint64_t ram_bytes_remaining(void)
{
return ram_state ? (ram_state->migration_dirty_pages * TARGET_PAGE_SIZE) :
@@ -664,7 +653,7 @@ static void mig_throttle_guest_down(uint64_t bytes_dirty_period,
*/
static void xbzrle_cache_zero_page(RAMState *rs, ram_addr_t current_addr)
{
- if (rs->ram_bulk_stage || !migrate_use_xbzrle()) {
+ if (!rs->xbzrle_enabled) {
return;
}
@@ -792,23 +781,12 @@ unsigned long migration_bitmap_find_dirty(RAMState *rs, RAMBlock *rb,
{
unsigned long size = rb->used_length >> TARGET_PAGE_BITS;
unsigned long *bitmap = rb->bmap;
- unsigned long next;
if (ramblock_is_ignored(rb)) {
return size;
}
- /*
- * When the free page optimization is enabled, we need to check the bitmap
- * to send the non-free pages rather than all the pages in the bulk stage.
- */
- if (!rs->fpo_enabled && rs->ram_bulk_stage && start > 0) {
- next = start + 1;
- } else {
- next = find_next_bit(bitmap, size, start);
- }
-
- return next;
+ return find_next_bit(bitmap, size, start);
}
static inline bool migration_bitmap_clear_dirty(RAMState *rs,
@@ -1185,8 +1163,7 @@ static int ram_save_page(RAMState *rs, PageSearchStatus *pss, bool last_stage)
trace_ram_save_page(block->idstr, (uint64_t)offset, p);
XBZRLE_cache_lock();
- if (!rs->ram_bulk_stage && !migration_in_postcopy() &&
- migrate_use_xbzrle()) {
+ if (rs->xbzrle_enabled && !migration_in_postcopy()) {
pages = save_xbzrle_page(rs, &p, current_addr, block,
offset, last_stage);
if (!last_stage) {
@@ -1365,8 +1342,8 @@ static bool find_dirty_block(RAMState *rs, PageSearchStatus *pss, bool *again)
*again = false;
return false;
}
- if ((((ram_addr_t)pss->page) << TARGET_PAGE_BITS)
- >= pss->block->used_length) {
+ if (!offset_in_ramblock(pss->block,
+ ((ram_addr_t)pss->page) << TARGET_PAGE_BITS)) {
/* Didn't find anything in this RAM Block */
pss->page = 0;
pss->block = QLIST_NEXT_RCU(pss->block, next);
@@ -1386,7 +1363,10 @@ static bool find_dirty_block(RAMState *rs, PageSearchStatus *pss, bool *again)
pss->block = QLIST_FIRST_RCU(&ram_list.blocks);
/* Flag that we've looped */
pss->complete_round = true;
- rs->ram_bulk_stage = false;
+ /* After the first round, enable XBZRLE. */
+ if (migrate_use_xbzrle()) {
+ rs->xbzrle_enabled = true;
+ }
}
/* Didn't find anything this time, but try again on the new block */
*again = true;
@@ -1801,14 +1781,6 @@ static bool get_queued_page(RAMState *rs, PageSearchStatus *pss)
if (block) {
/*
- * As soon as we start servicing pages out of order, then we have
- * to kill the bulk stage, since the bulk stage assumes
- * in (migration_bitmap_find_and_reset_dirty) that every page is
- * dirty, that's no longer true.
- */
- rs->ram_bulk_stage = false;
-
- /*
* We want the background search to continue from the queued page
* since the guest is likely to want other pages near to the page
* it just requested.
@@ -1891,7 +1863,7 @@ int ram_save_queue_pages(const char *rbname, ram_addr_t start, ram_addr_t len)
rs->last_req_rb = ramblock;
}
trace_ram_save_queue_pages(ramblock->idstr, start, len);
- if (start + len > ramblock->used_length) {
+ if (!offset_in_ramblock(ramblock, start + len - 1)) {
error_report("%s request overrun start=" RAM_ADDR_FMT " len="
RAM_ADDR_FMT " blocklen=" RAM_ADDR_FMT,
__func__, start, len, ramblock->used_length);
@@ -1920,15 +1892,15 @@ static bool save_page_use_compression(RAMState *rs)
}
/*
- * If xbzrle is on, stop using the data compression after first
- * round of migration even if compression is enabled. In theory,
- * xbzrle can do better than compression.
+ * If xbzrle is enabled (e.g., after first round of migration), stop
+ * using the data compression. In theory, xbzrle can do better than
+ * compression.
*/
- if (rs->ram_bulk_stage || !migrate_use_xbzrle()) {
- return true;
+ if (rs->xbzrle_enabled) {
+ return false;
}
- return false;
+ return true;
}
/*
@@ -2041,6 +2013,8 @@ static int ram_save_host_page(RAMState *rs, PageSearchStatus *pss,
int tmppages, pages = 0;
size_t pagesize_bits =
qemu_ram_pagesize(pss->block) >> TARGET_PAGE_BITS;
+ unsigned long hostpage_boundary =
+ QEMU_ALIGN_UP(pss->page + 1, pagesize_bits);
unsigned long start_page = pss->page;
int res;
@@ -2051,25 +2025,27 @@ static int ram_save_host_page(RAMState *rs, PageSearchStatus *pss,
do {
/* Check the pages is dirty and if it is send it */
- if (!migration_bitmap_clear_dirty(rs, pss->block, pss->page)) {
- pss->page++;
- continue;
- }
+ if (migration_bitmap_clear_dirty(rs, pss->block, pss->page)) {
+ tmppages = ram_save_target_page(rs, pss, last_stage);
+ if (tmppages < 0) {
+ return tmppages;
+ }
- tmppages = ram_save_target_page(rs, pss, last_stage);
- if (tmppages < 0) {
- return tmppages;
+ pages += tmppages;
+ /*
+ * Allow rate limiting to happen in the middle of huge pages if
+ * something is sent in the current iteration.
+ */
+ if (pagesize_bits > 1 && tmppages > 0) {
+ migration_rate_limit();
+ }
}
-
- pages += tmppages;
- pss->page++;
- /* Allow rate limiting to happen in the middle of huge pages */
- migration_rate_limit();
- } while ((pss->page & (pagesize_bits - 1)) &&
+ pss->page = migration_bitmap_find_dirty(rs, pss->block, pss->page);
+ } while ((pss->page < hostpage_boundary) &&
offset_in_ramblock(pss->block,
((ram_addr_t)pss->page) << TARGET_PAGE_BITS));
- /* The offset we leave with is the last one we looked at */
- pss->page--;
+ /* The offset we leave with is the min boundary of host page and block */
+ pss->page = MIN(pss->page, hostpage_boundary) - 1;
res = ram_save_release_protection(rs, pss, start_page);
return (res < 0 ? res : pages);
@@ -2235,8 +2211,7 @@ static void ram_state_reset(RAMState *rs)
rs->last_sent_block = NULL;
rs->last_page = 0;
rs->last_version = ram_list.version;
- rs->ram_bulk_stage = true;
- rs->fpo_enabled = false;
+ rs->xbzrle_enabled = false;
}
#define MAX_WAIT 50 /* ms, half buffered_file limit */
@@ -2720,15 +2695,7 @@ static void ram_state_resume_prepare(RAMState *rs, QEMUFile *out)
/* This may not be aligned with current bitmaps. Recalculate. */
rs->migration_dirty_pages = pages;
- rs->last_seen_block = NULL;
- rs->last_sent_block = NULL;
- rs->last_page = 0;
- rs->last_version = ram_list.version;
- /*
- * Disable the bulk stage, otherwise we'll resend the whole RAM no
- * matter what we have sent.
- */
- rs->ram_bulk_stage = false;
+ ram_state_reset(rs);
/* Update RAMState cache of output QEMUFile */
rs->f = out;
@@ -3118,6 +3085,20 @@ static inline void *host_from_ram_block_offset(RAMBlock *block,
return block->host + offset;
}
+static void *host_page_from_ram_block_offset(RAMBlock *block,
+ ram_addr_t offset)
+{
+ /* Note: Explicitly no check against offset_in_ramblock(). */
+ return (void *)QEMU_ALIGN_DOWN((uintptr_t)(block->host + offset),
+ block->page_size);
+}
+
+static ram_addr_t host_page_offset_from_ram_block_offset(RAMBlock *block,
+ ram_addr_t offset)
+{
+ return ((uintptr_t)block->host + offset) & (block->page_size - 1);
+}
+
static inline void *colo_cache_from_block_offset(RAMBlock *block,
ram_addr_t offset, bool record_bitmap)
{
@@ -3345,16 +3326,9 @@ static void decompress_data_with_multi_threads(QEMUFile *f,
}
}
- /*
- * we must set ram_bulk_stage to false, otherwise in
- * migation_bitmap_find_dirty the bitmap will be unused and
- * all the pages in ram cache wil be flushed to the ram of
- * secondary VM.
- */
static void colo_init_ram_state(void)
{
ram_state_init(&ram_state);
- ram_state->ram_bulk_stage = false;
}
/*
@@ -3521,13 +3495,12 @@ static int ram_load_postcopy(QEMUFile *f)
MigrationIncomingState *mis = migration_incoming_get_current();
/* Temporary page that is later 'placed' */
void *postcopy_host_page = mis->postcopy_tmp_page;
- void *this_host = NULL;
+ void *host_page = NULL;
bool all_zero = true;
int target_pages = 0;
while (!ret && !(flags & RAM_SAVE_FLAG_EOS)) {
ram_addr_t addr;
- void *host = NULL;
void *page_buffer = NULL;
void *place_source = NULL;
RAMBlock *block = NULL;
@@ -3552,9 +3525,18 @@ static int ram_load_postcopy(QEMUFile *f)
if (flags & (RAM_SAVE_FLAG_ZERO | RAM_SAVE_FLAG_PAGE |
RAM_SAVE_FLAG_COMPRESS_PAGE)) {
block = ram_block_from_stream(f, flags);
+ if (!block) {
+ ret = -EINVAL;
+ break;
+ }
- host = host_from_ram_block_offset(block, addr);
- if (!host) {
+ /*
+ * Relying on used_length is racy and can result in false positives.
+ * We might place pages beyond used_length in case RAM was shrunk
+ * while in postcopy, which is fine - trying to place via
+ * UFFDIO_COPY/UFFDIO_ZEROPAGE will never segfault.
+ */
+ if (!block->host || addr >= block->postcopy_length) {
error_report("Illegal RAM offset " RAM_ADDR_FMT, addr);
ret = -EINVAL;
break;
@@ -3572,19 +3554,17 @@ static int ram_load_postcopy(QEMUFile *f)
* of a host page in one chunk.
*/
page_buffer = postcopy_host_page +
- ((uintptr_t)host & (block->page_size - 1));
+ host_page_offset_from_ram_block_offset(block, addr);
+ /* If all TP are zero then we can optimise the place */
if (target_pages == 1) {
- this_host = (void *)QEMU_ALIGN_DOWN((uintptr_t)host,
- block->page_size);
- } else {
+ host_page = host_page_from_ram_block_offset(block, addr);
+ } else if (host_page != host_page_from_ram_block_offset(block,
+ addr)) {
/* not the 1st TP within the HP */
- if (QEMU_ALIGN_DOWN((uintptr_t)host, block->page_size) !=
- (uintptr_t)this_host) {
- error_report("Non-same host page %p/%p",
- host, this_host);
- ret = -EINVAL;
- break;
- }
+ error_report("Non-same host page %p/%p", host_page,
+ host_page_from_ram_block_offset(block, addr));
+ ret = -EINVAL;
+ break;
}
/*
@@ -3663,16 +3643,11 @@ static int ram_load_postcopy(QEMUFile *f)
}
if (!ret && place_needed) {
- /* This gets called at the last target page in the host page */
- void *place_dest = (void *)QEMU_ALIGN_DOWN((uintptr_t)host,
- block->page_size);
-
if (all_zero) {
- ret = postcopy_place_page_zero(mis, place_dest,
- block);
+ ret = postcopy_place_page_zero(mis, host_page, block);
} else {
- ret = postcopy_place_page(mis, place_dest,
- place_source, block);
+ ret = postcopy_place_page(mis, host_page, place_source,
+ block);
}
place_needed = false;
target_pages = 0;
@@ -3721,8 +3696,8 @@ void colo_flush_ram_cache(void)
while (block) {
offset = migration_bitmap_find_dirty(ram_state, block, offset);
- if (((ram_addr_t)offset) << TARGET_PAGE_BITS
- >= block->used_length) {
+ if (!offset_in_ramblock(block,
+ ((ram_addr_t)offset) << TARGET_PAGE_BITS)) {
offset = 0;
block = QLIST_NEXT_RCU(block, next);
} else {
@@ -4136,8 +4111,69 @@ static SaveVMHandlers savevm_ram_handlers = {
.resume_prepare = ram_resume_prepare,
};
+static void ram_mig_ram_block_resized(RAMBlockNotifier *n, void *host,
+ size_t old_size, size_t new_size)
+{
+ PostcopyState ps = postcopy_state_get();
+ ram_addr_t offset;
+ RAMBlock *rb = qemu_ram_block_from_host(host, false, &offset);
+ Error *err = NULL;
+
+ if (ramblock_is_ignored(rb)) {
+ return;
+ }
+
+ if (!migration_is_idle()) {
+ /*
+ * Precopy code on the source cannot deal with the size of RAM blocks
+ * changing at random points in time - especially after sending the
+ * RAM block sizes in the migration stream, they must no longer change.
+ * Abort and indicate a proper reason.
+ */
+ error_setg(&err, "RAM block '%s' resized during precopy.", rb->idstr);
+ migrate_set_error(migrate_get_current(), err);
+ error_free(err);
+ migration_cancel();
+ }
+
+ switch (ps) {
+ case POSTCOPY_INCOMING_ADVISE:
+ /*
+ * Update what ram_postcopy_incoming_init()->init_range() does at the
+ * time postcopy was advised. Syncing RAM blocks with the source will
+ * result in RAM resizes.
+ */
+ if (old_size < new_size) {
+ if (ram_discard_range(rb->idstr, old_size, new_size - old_size)) {
+ error_report("RAM block '%s' discard of resized RAM failed",
+ rb->idstr);
+ }
+ }
+ rb->postcopy_length = new_size;
+ break;
+ case POSTCOPY_INCOMING_NONE:
+ case POSTCOPY_INCOMING_RUNNING:
+ case POSTCOPY_INCOMING_END:
+ /*
+ * Once our guest is running, postcopy does no longer care about
+ * resizes. When growing, the new memory was not available on the
+ * source, no handler needed.
+ */
+ break;
+ default:
+ error_report("RAM block '%s' resized during postcopy state: %d",
+ rb->idstr, ps);
+ exit(-1);
+ }
+}
+
+static RAMBlockNotifier ram_mig_ram_notifier = {
+ .ram_block_resized = ram_mig_ram_block_resized,
+};
+
void ram_mig_init(void)
{
qemu_mutex_init(&XBZRLE.lock);
register_savevm_live("ram", 0, 4, &savevm_ram_handlers, &ram_state);
+ ram_block_notifier_add(&ram_mig_ram_notifier);
}
diff --git a/migration/target.c b/migration/target.c
new file mode 100644
index 0000000000..907ebf0a0a
--- /dev/null
+++ b/migration/target.c
@@ -0,0 +1,25 @@
+/*
+ * QEMU live migration - functions that need to be compiled target-specific
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2
+ * or (at your option) any later version.
+ */
+
+#include "qemu/osdep.h"
+#include "qapi/qapi-types-migration.h"
+#include "migration.h"
+
+#ifdef CONFIG_VFIO
+#include "hw/vfio/vfio-common.h"
+#endif
+
+void populate_vfio_info(MigrationInfo *info)
+{
+#ifdef CONFIG_VFIO
+ if (vfio_mig_active()) {
+ info->has_vfio = true;
+ info->vfio = g_malloc0(sizeof(*info->vfio));
+ info->vfio->transferred = vfio_mig_bytes_transferred();
+ }
+#endif
+}
diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c
index 0ad5b77477..d9bef63373 100644
--- a/monitor/hmp-cmds.c
+++ b/monitor/hmp-cmds.c
@@ -224,7 +224,7 @@ void hmp_info_migrate(Monitor *mon, const QDict *qdict)
migration_global_dump(mon);
- if (info->blocked) {
+ if (info->blocked_reasons) {
strList *reasons = info->blocked_reasons;
monitor_printf(mon, "Outgoing migration blocked:\n");
while (reasons) {
diff --git a/monitor/qmp.c b/monitor/qmp.c
index 2b0308f933..092c527b6f 100644
--- a/monitor/qmp.c
+++ b/monitor/qmp.c
@@ -257,24 +257,6 @@ void coroutine_fn monitor_qmp_dispatcher_co(void *data)
trace_monitor_qmp_in_band_dequeue(req_obj,
req_obj->mon->qmp_requests->length);
- if (qatomic_xchg(&qmp_dispatcher_co_busy, true) == true) {
- /*
- * Someone rescheduled us (probably because a new requests
- * came in), but we didn't actually yield. Do that now,
- * only to be immediately reentered and removed from the
- * list of scheduled coroutines.
- */
- qemu_coroutine_yield();
- }
-
- /*
- * Move the coroutine from iohandler_ctx to qemu_aio_context for
- * executing the command handler so that it can make progress if it
- * involves an AIO_WAIT_WHILE().
- */
- aio_co_schedule(qemu_get_aio_context(), qmp_dispatcher_co);
- qemu_coroutine_yield();
-
/*
* @req_obj has a request, we hold req_obj->mon->qmp_queue_lock
*/
@@ -298,8 +280,30 @@ void coroutine_fn monitor_qmp_dispatcher_co(void *data)
monitor_resume(&mon->common);
}
+ /*
+ * Drop the queue mutex now, before yielding, otherwise we might
+ * deadlock if the main thread tries to lock it.
+ */
qemu_mutex_unlock(&mon->qmp_queue_lock);
+ if (qatomic_xchg(&qmp_dispatcher_co_busy, true) == true) {
+ /*
+ * Someone rescheduled us (probably because a new requests
+ * came in), but we didn't actually yield. Do that now,
+ * only to be immediately reentered and removed from the
+ * list of scheduled coroutines.
+ */
+ qemu_coroutine_yield();
+ }
+
+ /*
+ * Move the coroutine from iohandler_ctx to qemu_aio_context for
+ * executing the command handler so that it can make progress if it
+ * involves an AIO_WAIT_WHILE().
+ */
+ aio_co_schedule(qemu_get_aio_context(), qmp_dispatcher_co);
+ qemu_coroutine_yield();
+
/* Process request */
if (req_obj->req) {
if (trace_event_get_state(TRACE_MONITOR_QMP_CMD_IN_BAND)) {
diff --git a/pc-bios/s390-ccw/helper.h b/pc-bios/s390-ccw/helper.h
index dfcfea0ff0..3d0731c4c6 100644
--- a/pc-bios/s390-ccw/helper.h
+++ b/pc-bios/s390-ccw/helper.h
@@ -31,7 +31,7 @@ static inline void *u32toptr(uint32_t n)
static inline void yield(void)
{
- asm volatile ("diag 0,0,0x44"
+ asm volatile ("diag %%r0,%%r0,0x44"
: :
: "memory", "cc");
}
diff --git a/pc-bios/s390-ccw/jump2ipl.c b/pc-bios/s390-ccw/jump2ipl.c
index 73e4367e09..78f5f46533 100644
--- a/pc-bios/s390-ccw/jump2ipl.c
+++ b/pc-bios/s390-ccw/jump2ipl.c
@@ -64,8 +64,8 @@ void jump_to_IPL_code(uint64_t address)
* We use the load normal reset to keep r15 unchanged. jump_to_IPL_2
* can then use r15 as its stack pointer.
*/
- asm volatile("lghi 1,1\n\t"
- "diag 1,1,0x308\n\t"
+ asm volatile("lghi %%r1,1\n\t"
+ "diag %%r1,%%r1,0x308\n\t"
: : : "1", "memory");
panic("\n! IPL returns !\n");
}
diff --git a/pc-bios/s390-ccw/menu.c b/pc-bios/s390-ccw/menu.c
index de8260a5d6..d601952d3e 100644
--- a/pc-bios/s390-ccw/menu.c
+++ b/pc-bios/s390-ccw/menu.c
@@ -36,9 +36,9 @@ static inline void enable_clock_int(void)
uint64_t tmp = 0;
asm volatile(
- "stctg 0,0,%0\n"
+ "stctg %%c0,%%c0,%0\n"
"oi 6+%0, 0x8\n"
- "lctlg 0,0,%0"
+ "lctlg %%c0,%%c0,%0"
: : "Q" (tmp) : "memory"
);
}
@@ -48,9 +48,9 @@ static inline void disable_clock_int(void)
uint64_t tmp = 0;
asm volatile(
- "stctg 0,0,%0\n"
+ "stctg %%c0,%%c0,%0\n"
"ni 6+%0, 0xf7\n"
- "lctlg 0,0,%0"
+ "lctlg %%c0,%%c0,%0"
: : "Q" (tmp) : "memory"
);
}
diff --git a/pc-bios/s390-ccw/virtio.c b/pc-bios/s390-ccw/virtio.c
index ab49840db8..5d2c6e3381 100644
--- a/pc-bios/s390-ccw/virtio.c
+++ b/pc-bios/s390-ccw/virtio.c
@@ -54,7 +54,7 @@ static long kvm_hypercall(unsigned long nr, unsigned long param1,
register ulong r_param3 asm("4") = param3;
register long retval asm("2");
- asm volatile ("diag 2,4,0x500"
+ asm volatile ("diag %%r2,%%r4,0x500"
: "=d" (retval)
: "d" (r_nr), "0" (r_param1), "r"(r_param2), "d"(r_param3)
: "memory", "cc");
diff --git a/qapi/block-core.json b/qapi/block-core.json
index 6d227924d0..2ea294129e 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -2818,7 +2818,6 @@
'luks', 'nbd', 'nfs', 'null-aio', 'null-co', 'nvme', 'parallels',
'preallocate', 'qcow', 'qcow2', 'qed', 'quorum', 'raw', 'rbd',
{ 'name': 'replication', 'if': 'defined(CONFIG_REPLICATION)' },
- 'sheepdog',
'ssh', 'throttle', 'vdi', 'vhdx', 'vmdk', 'vpc', 'vvfat' ] }
##
@@ -3652,26 +3651,6 @@
'*server': ['InetSocketAddressBase'] } }
##
-# @BlockdevOptionsSheepdog:
-#
-# Driver specific block device options for sheepdog
-#
-# @vdi: Virtual disk image name
-# @server: The Sheepdog server to connect to
-# @snap-id: Snapshot ID
-# @tag: Snapshot tag name
-#
-# Only one of @snap-id and @tag may be present.
-#
-# Since: 2.9
-##
-{ 'struct': 'BlockdevOptionsSheepdog',
- 'data': { 'server': 'SocketAddress',
- 'vdi': 'str',
- '*snap-id': 'uint32',
- '*tag': 'str' } }
-
-##
# @ReplicationMode:
#
# An enumeration of replication modes.
@@ -4037,7 +4016,6 @@
'rbd': 'BlockdevOptionsRbd',
'replication': { 'type': 'BlockdevOptionsReplication',
'if': 'defined(CONFIG_REPLICATION)' },
- 'sheepdog': 'BlockdevOptionsSheepdog',
'ssh': 'BlockdevOptionsSsh',
'throttle': 'BlockdevOptionsThrottle',
'vdi': 'BlockdevOptionsGenericFormat',
@@ -4497,74 +4475,6 @@
##
-# @SheepdogRedundancyType:
-#
-# @full: Create a fully replicated vdi with x copies
-# @erasure-coded: Create an erasure coded vdi with x data strips and
-# y parity strips
-#
-# Since: 2.12
-##
-{ 'enum': 'SheepdogRedundancyType',
- 'data': [ 'full', 'erasure-coded' ] }
-
-##
-# @SheepdogRedundancyFull:
-#
-# @copies: Number of copies to use (between 1 and 31)
-#
-# Since: 2.12
-##
-{ 'struct': 'SheepdogRedundancyFull',
- 'data': { 'copies': 'int' }}
-
-##
-# @SheepdogRedundancyErasureCoded:
-#
-# @data-strips: Number of data strips to use (one of {2,4,8,16})
-# @parity-strips: Number of parity strips to use (between 1 and 15)
-#
-# Since: 2.12
-##
-{ 'struct': 'SheepdogRedundancyErasureCoded',
- 'data': { 'data-strips': 'int',
- 'parity-strips': 'int' }}
-
-##
-# @SheepdogRedundancy:
-#
-# Since: 2.12
-##
-{ 'union': 'SheepdogRedundancy',
- 'base': { 'type': 'SheepdogRedundancyType' },
- 'discriminator': 'type',
- 'data': { 'full': 'SheepdogRedundancyFull',
- 'erasure-coded': 'SheepdogRedundancyErasureCoded' } }
-
-##
-# @BlockdevCreateOptionsSheepdog:
-#
-# Driver specific image creation options for Sheepdog.
-#
-# @location: Where to store the new image file
-# @size: Size of the virtual disk in bytes
-# @backing-file: File name of a base image
-# @preallocation: Preallocation mode for the new image (default: off;
-# allowed values: off, full)
-# @redundancy: Redundancy of the image
-# @object-size: Object size of the image
-#
-# Since: 2.12
-##
-{ 'struct': 'BlockdevCreateOptionsSheepdog',
- 'data': { 'location': 'BlockdevOptionsSheepdog',
- 'size': 'size',
- '*backing-file': 'str',
- '*preallocation': 'PreallocMode',
- '*redundancy': 'SheepdogRedundancy',
- '*object-size': 'size' } }
-
-##
# @BlockdevCreateOptionsSsh:
#
# Driver specific image creation options for SSH.
@@ -4687,7 +4597,6 @@
'qcow2': 'BlockdevCreateOptionsQcow2',
'qed': 'BlockdevCreateOptionsQed',
'rbd': 'BlockdevCreateOptionsRbd',
- 'sheepdog': 'BlockdevCreateOptionsSheepdog',
'ssh': 'BlockdevCreateOptionsSsh',
'vdi': 'BlockdevCreateOptionsVdi',
'vhdx': 'BlockdevCreateOptionsVhdx',
@@ -5322,7 +5231,7 @@
#
# Notes: In transaction, if @name is empty, or any snapshot matching @name
# exists, the operation will fail. Only some image formats support it,
-# for example, qcow2, rbd, and sheepdog.
+# for example, qcow2, and rbd.
#
# Since: 1.7
##
diff --git a/qapi/machine.json b/qapi/machine.json
index 6e90d463fc..58a9c86b36 100644
--- a/qapi/machine.json
+++ b/qapi/machine.json
@@ -29,11 +29,11 @@
# Since: 3.0
##
{ 'enum' : 'SysEmuTarget',
- 'data' : [ 'aarch64', 'alpha', 'arm', 'avr', 'cris', 'hppa', 'i386', 'lm32',
+ 'data' : [ 'aarch64', 'alpha', 'arm', 'avr', 'cris', 'hppa', 'i386',
'm68k', 'microblaze', 'microblazeel', 'mips', 'mips64',
- 'mips64el', 'mipsel', 'moxie', 'nios2', 'or1k', 'ppc',
+ 'mips64el', 'mipsel', 'nios2', 'or1k', 'ppc',
'ppc64', 'riscv32', 'riscv64', 'rx', 's390x', 'sh4',
- 'sh4eb', 'sparc', 'sparc64', 'tricore', 'unicore32',
+ 'sh4eb', 'sparc', 'sparc64', 'tricore',
'x86_64', 'xtensa', 'xtensaeb' ] }
##
diff --git a/qapi/migration.json b/qapi/migration.json
index 0b17cce46b..7a5bdf9a0d 100644
--- a/qapi/migration.json
+++ b/qapi/migration.json
@@ -228,11 +228,6 @@
# Present and non-empty when migration is blocked.
# (since 6.0)
#
-# @blocked: True if outgoing migration is blocked (since 6.0)
-#
-# Features:
-# @deprecated: Member @blocked is deprecated. Use @blocked-reasons instead.
-#
# Since: 0.14
##
{ 'struct': 'MigrationInfo',
@@ -246,7 +241,6 @@
'*setup-time': 'int',
'*cpu-throttle-percentage': 'int',
'*error-desc': 'str',
- 'blocked': { 'type': 'bool', 'features': [ 'deprecated' ] },
'*blocked-reasons': ['str'],
'*postcopy-blocktime' : 'uint32',
'*postcopy-vcpu-blocktime': ['uint32'],
diff --git a/qapi/misc-target.json b/qapi/misc-target.json
index 0c7491cd82..6200c671be 100644
--- a/qapi/misc-target.json
+++ b/qapi/misc-target.json
@@ -23,7 +23,7 @@
##
{ 'event': 'RTC_CHANGE',
'data': { 'offset': 'int' },
- 'if': 'defined(TARGET_ALPHA) || defined(TARGET_ARM) || defined(TARGET_HPPA) || defined(TARGET_I386) || defined(TARGET_MIPS) || defined(TARGET_MIPS64) || defined(TARGET_MOXIE) || defined(TARGET_PPC) || defined(TARGET_PPC64) || defined(TARGET_S390X) || defined(TARGET_SH4) || defined(TARGET_SPARC)' }
+ 'if': 'defined(TARGET_ALPHA) || defined(TARGET_ARM) || defined(TARGET_HPPA) || defined(TARGET_I386) || defined(TARGET_MIPS) || defined(TARGET_MIPS64) || defined(TARGET_PPC) || defined(TARGET_PPC64) || defined(TARGET_S390X) || defined(TARGET_SH4) || defined(TARGET_SPARC)' }
##
# @rtc-reset-reinjection:
diff --git a/qapi/transaction.json b/qapi/transaction.json
index 15ddebdbc3..894258d9e2 100644
--- a/qapi/transaction.json
+++ b/qapi/transaction.json
@@ -112,10 +112,10 @@
#
# On failure, the original disks pre-snapshot attempt will be used.
#
-# For internal snapshots, the dictionary contains the device and the snapshot's
-# name. If an internal snapshot matching name already exists, the request will
-# be rejected. Only some image formats support it, for example, qcow2, rbd,
-# and sheepdog.
+# For internal snapshots, the dictionary contains the device and the
+# snapshot's name. If an internal snapshot matching name already exists,
+# the request will be rejected. Only some image formats support it, for
+# example, qcow2, and rbd,
#
# On failure, qemu will try delete the newly created internal snapshot in the
# transaction. When an I/O error occurs during deletion, the user needs to fix
diff --git a/qemu-io-cmds.c b/qemu-io-cmds.c
index 97611969cb..998b67186d 100644
--- a/qemu-io-cmds.c
+++ b/qemu-io-cmds.c
@@ -2457,9 +2457,12 @@ static const cmdinfo_t help_cmd = {
.oneline = "help for one or all commands",
};
+/*
+ * Called with aio context of blk acquired. Or with qemu_get_aio_context()
+ * context acquired if blk is NULL.
+ */
int qemuio_command(BlockBackend *blk, const char *cmd)
{
- AioContext *ctx;
char *input;
const cmdinfo_t *ct;
char **v;
@@ -2471,10 +2474,7 @@ int qemuio_command(BlockBackend *blk, const char *cmd)
if (c) {
ct = find_command(v[0]);
if (ct) {
- ctx = blk ? blk_get_aio_context(blk) : qemu_get_aio_context();
- aio_context_acquire(ctx);
ret = command(blk, ct, c, v);
- aio_context_release(ctx);
} else {
fprintf(stderr, "command \"%s\" not found\n", v[0]);
ret = -EINVAL;
diff --git a/qemu-io.c b/qemu-io.c
index bf902302e9..57f07501df 100644
--- a/qemu-io.c
+++ b/qemu-io.c
@@ -411,6 +411,19 @@ static void prep_fetchline(void *opaque)
*fetchable= 1;
}
+static int do_qemuio_command(const char *cmd)
+{
+ int ret;
+ AioContext *ctx =
+ qemuio_blk ? blk_get_aio_context(qemuio_blk) : qemu_get_aio_context();
+
+ aio_context_acquire(ctx);
+ ret = qemuio_command(qemuio_blk, cmd);
+ aio_context_release(ctx);
+
+ return ret;
+}
+
static int command_loop(void)
{
int i, fetchable = 0, prompted = 0;
@@ -418,7 +431,7 @@ static int command_loop(void)
char *input;
for (i = 0; !quit_qemu_io && i < ncmdline; i++) {
- ret = qemuio_command(qemuio_blk, cmdline[i]);
+ ret = do_qemuio_command(cmdline[i]);
if (ret < 0) {
last_error = ret;
}
@@ -446,7 +459,7 @@ static int command_loop(void)
if (input == NULL) {
break;
}
- ret = qemuio_command(qemuio_blk, input);
+ ret = do_qemuio_command(input);
g_free(input);
if (ret < 0) {
diff --git a/qemu-options.hx b/qemu-options.hx
index 7c825f81fc..e22fb94d99 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -2370,7 +2370,9 @@ DEF("smbios", HAS_ARG, QEMU_OPTION_smbios,
" specify SMBIOS type 11 fields\n"
"-smbios type=17[,loc_pfx=str][,bank=str][,manufacturer=str][,serial=str]\n"
" [,asset=str][,part=str][,speed=%d]\n"
- " specify SMBIOS type 17 fields\n",
+ " specify SMBIOS type 17 fields\n"
+ "-smbios type=41[,designation=str][,kind=str][,instance=%d][,pcidev=str]\n"
+ " specify SMBIOS type 41 fields\n",
QEMU_ARCH_I386 | QEMU_ARCH_ARM)
SRST
``-smbios file=binary``
@@ -2432,6 +2434,32 @@ SRST
``-smbios type=17[,loc_pfx=str][,bank=str][,manufacturer=str][,serial=str][,asset=str][,part=str][,speed=%d]``
Specify SMBIOS type 17 fields
+
+``-smbios type=41[,designation=str][,kind=str][,instance=%d][,pcidev=str]``
+ Specify SMBIOS type 41 fields
+
+ This argument can be repeated multiple times. Its main use is to allow network interfaces be created
+ as ``enoX`` on Linux, with X being the instance number, instead of the name depending on the interface
+ position on the PCI bus.
+
+ Here is an example of use:
+
+ .. parsed-literal::
+
+ -netdev user,id=internet \\
+ -device virtio-net-pci,mac=50:54:00:00:00:42,netdev=internet,id=internet-dev \\
+ -smbios type=41,designation='Onboard LAN',instance=1,kind=ethernet,pcidev=internet-dev
+
+ In the guest OS, the device should then appear as ``eno1``:
+
+ ..parsed-literal::
+
+ $ ip -brief l
+ lo UNKNOWN 00:00:00:00:00:00 <LOOPBACK,UP,LOWER_UP>
+ eno1 UP 50:54:00:00:00:42 <BROADCAST,MULTICAST,UP,LOWER_UP>
+
+ Currently, the PCI device has to be attached to the root bus.
+
ERST
DEFHEADING()
@@ -4288,7 +4316,7 @@ SRST
ERST
DEF("semihosting", 0, QEMU_OPTION_semihosting,
"-semihosting semihosting mode\n",
- QEMU_ARCH_ARM | QEMU_ARCH_M68K | QEMU_ARCH_XTENSA | QEMU_ARCH_LM32 |
+ QEMU_ARCH_ARM | QEMU_ARCH_M68K | QEMU_ARCH_XTENSA |
QEMU_ARCH_MIPS | QEMU_ARCH_NIOS2 | QEMU_ARCH_RISCV)
SRST
``-semihosting``
@@ -4303,7 +4331,7 @@ ERST
DEF("semihosting-config", HAS_ARG, QEMU_OPTION_semihosting_config,
"-semihosting-config [enable=on|off][,target=native|gdb|auto][,chardev=id][,arg=str[,...]]\n" \
" semihosting configuration\n",
-QEMU_ARCH_ARM | QEMU_ARCH_M68K | QEMU_ARCH_XTENSA | QEMU_ARCH_LM32 |
+QEMU_ARCH_ARM | QEMU_ARCH_M68K | QEMU_ARCH_XTENSA |
QEMU_ARCH_MIPS | QEMU_ARCH_NIOS2 | QEMU_ARCH_RISCV)
SRST
``-semihosting-config [enable=on|off][,target=native|gdb|auto][,chardev=id][,arg=str[,...]]``
diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl
index 8f7053ec9b..3d185cceac 100755
--- a/scripts/checkpatch.pl
+++ b/scripts/checkpatch.pl
@@ -1532,6 +1532,7 @@ sub process {
($line =~ /\{\s*([\w\/\.\-]*)\s*\=\>\s*([\w\/\.\-]*)\s*\}/ &&
(defined($1) || defined($2)))) &&
!(($realfile ne '') &&
+ defined($acpi_testexpected) &&
($realfile eq $acpi_testexpected))) {
$reported_maintainer_file = 1;
WARN("added, moved or deleted file(s), does MAINTAINERS need updating?\n" . $herecurr);
diff --git a/softmmu/arch_init.c b/softmmu/arch_init.c
index f09bab830c..6ff9f30bad 100644
--- a/softmmu/arch_init.c
+++ b/softmmu/arch_init.c
@@ -56,16 +56,12 @@ int graphic_depth = 32;
#define QEMU_ARCH QEMU_ARCH_HPPA
#elif defined(TARGET_I386)
#define QEMU_ARCH QEMU_ARCH_I386
-#elif defined(TARGET_LM32)
-#define QEMU_ARCH QEMU_ARCH_LM32
#elif defined(TARGET_M68K)
#define QEMU_ARCH QEMU_ARCH_M68K
#elif defined(TARGET_MICROBLAZE)
#define QEMU_ARCH QEMU_ARCH_MICROBLAZE
#elif defined(TARGET_MIPS)
#define QEMU_ARCH QEMU_ARCH_MIPS
-#elif defined(TARGET_MOXIE)
-#define QEMU_ARCH QEMU_ARCH_MOXIE
#elif defined(TARGET_NIOS2)
#define QEMU_ARCH QEMU_ARCH_NIOS2
#elif defined(TARGET_OPENRISC)
@@ -84,8 +80,6 @@ int graphic_depth = 32;
#define QEMU_ARCH QEMU_ARCH_SPARC
#elif defined(TARGET_TRICORE)
#define QEMU_ARCH QEMU_ARCH_TRICORE
-#elif defined(TARGET_UNICORE32)
-#define QEMU_ARCH QEMU_ARCH_UNICORE32
#elif defined(TARGET_XTENSA)
#define QEMU_ARCH QEMU_ARCH_XTENSA
#elif defined(TARGET_AVR)
diff --git a/softmmu/physmem.c b/softmmu/physmem.c
index 5232696571..e1da81ed2f 100644
--- a/softmmu/physmem.c
+++ b/softmmu/physmem.c
@@ -1694,6 +1694,11 @@ ram_addr_t qemu_ram_get_used_length(RAMBlock *rb)
return rb->used_length;
}
+ram_addr_t qemu_ram_get_max_length(RAMBlock *rb)
+{
+ return rb->max_length;
+}
+
bool qemu_ram_is_shared(RAMBlock *rb)
{
return rb->flags & RAM_SHARED;
@@ -1793,8 +1798,9 @@ static int memory_try_enable_merging(void *addr, size_t len)
return qemu_madvise(addr, len, QEMU_MADV_MERGEABLE);
}
-/* Only legal before guest might have detected the memory size: e.g. on
- * incoming migration, or right after reset.
+/*
+ * Resizing RAM while migrating can result in the migration being canceled.
+ * Care has to be taken if the guest might have already detected the memory.
*
* As memory core doesn't know how is memory accessed, it is up to
* resize callback to update device state and/or add assertions to detect
@@ -1802,6 +1808,7 @@ static int memory_try_enable_merging(void *addr, size_t len)
*/
int qemu_ram_resize(RAMBlock *block, ram_addr_t newsize, Error **errp)
{
+ const ram_addr_t oldsize = block->used_length;
const ram_addr_t unaligned_size = newsize;
assert(block);
@@ -1838,6 +1845,11 @@ int qemu_ram_resize(RAMBlock *block, ram_addr_t newsize, Error **errp)
return -EINVAL;
}
+ /* Notify before modifying the ram block and touching the bitmaps. */
+ if (block->host) {
+ ram_block_notify_resize(block->host, oldsize, newsize);
+ }
+
cpu_physical_memory_clear_dirty_range(block->offset, block->used_length);
block->used_length = newsize;
cpu_physical_memory_set_dirty_range(block->offset, block->used_length,
@@ -2005,7 +2017,8 @@ static void ram_block_add(RAMBlock *new_block, Error **errp, bool shared)
qemu_madvise(new_block->host, new_block->max_length,
QEMU_MADV_DONTFORK);
}
- ram_block_notify_add(new_block->host, new_block->max_length);
+ ram_block_notify_add(new_block->host, new_block->used_length,
+ new_block->max_length);
}
}
@@ -2184,7 +2197,8 @@ void qemu_ram_free(RAMBlock *block)
}
if (block->host) {
- ram_block_notify_remove(block->host, block->max_length);
+ ram_block_notify_remove(block->host, block->used_length,
+ block->max_length);
}
qemu_mutex_lock_ramlist();
@@ -3486,7 +3500,7 @@ int ram_block_discard_range(RAMBlock *rb, uint64_t start, size_t length)
goto err;
}
- if ((start + length) <= rb->used_length) {
+ if ((start + length) <= rb->max_length) {
bool need_madvise, need_fallocate;
if (!QEMU_IS_ALIGNED(length, rb->page_size)) {
error_report("ram_block_discard_range: Unaligned length: %zx",
@@ -3553,7 +3567,7 @@ int ram_block_discard_range(RAMBlock *rb, uint64_t start, size_t length)
} else {
error_report("ram_block_discard_range: Overrun block '%s' (%" PRIu64
"/%zx/" RAM_ADDR_FMT")",
- rb->idstr, start, length, rb->used_length);
+ rb->idstr, start, length, rb->max_length);
}
err:
diff --git a/target/i386/hax/hax-mem.c b/target/i386/hax/hax-mem.c
index 35495f5e82..8d44edbffd 100644
--- a/target/i386/hax/hax-mem.c
+++ b/target/i386/hax/hax-mem.c
@@ -293,7 +293,8 @@ static MemoryListener hax_memory_listener = {
.priority = 10,
};
-static void hax_ram_block_added(RAMBlockNotifier *n, void *host, size_t size)
+static void hax_ram_block_added(RAMBlockNotifier *n, void *host, size_t size,
+ size_t max_size)
{
/*
* We must register each RAM block with the HAXM kernel module, or
@@ -304,7 +305,7 @@ static void hax_ram_block_added(RAMBlockNotifier *n, void *host, size_t size)
* host physical pages for the RAM block as part of this registration
* process, hence the name hax_populate_ram().
*/
- if (hax_populate_ram((uint64_t)(uintptr_t)host, size) < 0) {
+ if (hax_populate_ram((uint64_t)(uintptr_t)host, max_size) < 0) {
fprintf(stderr, "HAX failed to populate RAM\n");
abort();
}
diff --git a/target/i386/sev.c b/target/i386/sev.c
index 9a43be11cb..41f7800b5f 100644
--- a/target/i386/sev.c
+++ b/target/i386/sev.c
@@ -180,7 +180,8 @@ sev_set_guest_state(SevGuestState *sev, SevState new_state)
}
static void
-sev_ram_block_added(RAMBlockNotifier *n, void *host, size_t size)
+sev_ram_block_added(RAMBlockNotifier *n, void *host, size_t size,
+ size_t max_size)
{
int r;
struct kvm_enc_region range;
@@ -197,19 +198,20 @@ sev_ram_block_added(RAMBlockNotifier *n, void *host, size_t size)
}
range.addr = (__u64)(unsigned long)host;
- range.size = size;
+ range.size = max_size;
- trace_kvm_memcrypt_register_region(host, size);
+ trace_kvm_memcrypt_register_region(host, max_size);
r = kvm_vm_ioctl(kvm_state, KVM_MEMORY_ENCRYPT_REG_REGION, &range);
if (r) {
error_report("%s: failed to register region (%p+%#zx) error '%s'",
- __func__, host, size, strerror(errno));
+ __func__, host, max_size, strerror(errno));
exit(1);
}
}
static void
-sev_ram_block_removed(RAMBlockNotifier *n, void *host, size_t size)
+sev_ram_block_removed(RAMBlockNotifier *n, void *host, size_t size,
+ size_t max_size)
{
int r;
struct kvm_enc_region range;
@@ -226,13 +228,13 @@ sev_ram_block_removed(RAMBlockNotifier *n, void *host, size_t size)
}
range.addr = (__u64)(unsigned long)host;
- range.size = size;
+ range.size = max_size;
- trace_kvm_memcrypt_unregister_region(host, size);
+ trace_kvm_memcrypt_unregister_region(host, max_size);
r = kvm_vm_ioctl(kvm_state, KVM_MEMORY_ENCRYPT_UNREG_REGION, &range);
if (r) {
error_report("%s: failed to unregister region (%p+%#zx)",
- __func__, host, size);
+ __func__, host, max_size);
}
}
diff --git a/target/lm32/README b/target/lm32/README
deleted file mode 100644
index ba3508a711..0000000000
--- a/target/lm32/README
+++ /dev/null
@@ -1,45 +0,0 @@
-LatticeMico32 target
---------------------
-
-General
--------
-All opcodes including the JUART CSRs are supported.
-
-
-JTAG UART
----------
-JTAG UART is routed to a serial console device. For the current boards it
-is the second one. Ie to enable it in the qemu virtual console window use
-the following command line parameters:
- -serial vc -serial vc
-This will make serial0 (the lm32_uart) and serial1 (the JTAG UART)
-available as virtual consoles.
-
-
-Semihosting
------------
-Semihosting on this target is supported. Some system calls like read, write
-and exit are executed on the host if semihosting is enabled. See
-target/lm32-semi.c for all supported system calls. Emulation aware programs
-can use this mechanism to shut down the virtual machine and print to the
-host console. See the tcg tests for an example.
-
-
-Special instructions
---------------------
-The translation recognizes one special instruction to halt the cpu:
- and r0, r0, r0
-On real hardware this instruction is a nop. It is not used by GCC and
-should (hopefully) not be used within hand-crafted assembly.
-Insert this instruction in your idle loop to reduce the cpu load on the
-host.
-
-
-Ignoring the MSB of the address bus
------------------------------------
-Some SoC ignores the MSB on the address bus. Thus creating a shadow memory
-area. As a general rule, 0x00000000-0x7fffffff is cached, whereas
-0x80000000-0xffffffff is not cached and used to access IO devices. This
-behaviour can be enabled with:
- cpu_lm32_set_phys_msb_ignore(env, 1);
-
diff --git a/target/lm32/TODO b/target/lm32/TODO
deleted file mode 100644
index e163c42ebe..0000000000
--- a/target/lm32/TODO
+++ /dev/null
@@ -1 +0,0 @@
-* linux-user emulation
diff --git a/target/lm32/cpu-param.h b/target/lm32/cpu-param.h
deleted file mode 100644
index d89574ad19..0000000000
--- a/target/lm32/cpu-param.h
+++ /dev/null
@@ -1,17 +0,0 @@
-/*
- * LatticeMico32 cpu parameters for qemu.
- *
- * Copyright (c) 2010 Michael Walle <michael@walle.cc>
- * SPDX-License-Identifier: LGPL-2.0+
- */
-
-#ifndef LM32_CPU_PARAM_H
-#define LM32_CPU_PARAM_H 1
-
-#define TARGET_LONG_BITS 32
-#define TARGET_PAGE_BITS 12
-#define TARGET_PHYS_ADDR_SPACE_BITS 32
-#define TARGET_VIRT_ADDR_SPACE_BITS 32
-#define NB_MMU_MODES 1
-
-#endif
diff --git a/target/lm32/cpu-qom.h b/target/lm32/cpu-qom.h
deleted file mode 100644
index 245b35cd1d..0000000000
--- a/target/lm32/cpu-qom.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * QEMU LatticeMico32 CPU
- *
- * Copyright (c) 2012 SUSE LINUX Products GmbH
- *
- * 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.1 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/lgpl-2.1.html>
- */
-#ifndef QEMU_LM32_CPU_QOM_H
-#define QEMU_LM32_CPU_QOM_H
-
-#include "hw/core/cpu.h"
-#include "qom/object.h"
-
-#define TYPE_LM32_CPU "lm32-cpu"
-
-OBJECT_DECLARE_TYPE(LM32CPU, LM32CPUClass,
- LM32_CPU)
-
-/**
- * LM32CPUClass:
- * @parent_realize: The parent class' realize handler.
- * @parent_reset: The parent class' reset handler.
- *
- * A LatticeMico32 CPU model.
- */
-struct LM32CPUClass {
- /*< private >*/
- CPUClass parent_class;
- /*< public >*/
-
- DeviceRealize parent_realize;
- DeviceReset parent_reset;
-};
-
-
-#endif
diff --git a/target/lm32/cpu.c b/target/lm32/cpu.c
deleted file mode 100644
index c23d72874c..0000000000
--- a/target/lm32/cpu.c
+++ /dev/null
@@ -1,274 +0,0 @@
-/*
- * QEMU LatticeMico32 CPU
- *
- * Copyright (c) 2012 SUSE LINUX Products GmbH
- *
- * 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.1 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/lgpl-2.1.html>
- */
-
-#include "qemu/osdep.h"
-#include "qapi/error.h"
-#include "qemu/qemu-print.h"
-#include "cpu.h"
-
-
-static void lm32_cpu_set_pc(CPUState *cs, vaddr value)
-{
- LM32CPU *cpu = LM32_CPU(cs);
-
- cpu->env.pc = value;
-}
-
-static void lm32_cpu_list_entry(gpointer data, gpointer user_data)
-{
- ObjectClass *oc = data;
- const char *typename = object_class_get_name(oc);
- char *name;
-
- name = g_strndup(typename, strlen(typename) - strlen(LM32_CPU_TYPE_SUFFIX));
- qemu_printf(" %s\n", name);
- g_free(name);
-}
-
-
-void lm32_cpu_list(void)
-{
- GSList *list;
-
- list = object_class_get_list_sorted(TYPE_LM32_CPU, false);
- qemu_printf("Available CPUs:\n");
- g_slist_foreach(list, lm32_cpu_list_entry, NULL);
- g_slist_free(list);
-}
-
-static void lm32_cpu_init_cfg_reg(LM32CPU *cpu)
-{
- CPULM32State *env = &cpu->env;
- uint32_t cfg = 0;
-
- if (cpu->features & LM32_FEATURE_MULTIPLY) {
- cfg |= CFG_M;
- }
-
- if (cpu->features & LM32_FEATURE_DIVIDE) {
- cfg |= CFG_D;
- }
-
- if (cpu->features & LM32_FEATURE_SHIFT) {
- cfg |= CFG_S;
- }
-
- if (cpu->features & LM32_FEATURE_SIGN_EXTEND) {
- cfg |= CFG_X;
- }
-
- if (cpu->features & LM32_FEATURE_I_CACHE) {
- cfg |= CFG_IC;
- }
-
- if (cpu->features & LM32_FEATURE_D_CACHE) {
- cfg |= CFG_DC;
- }
-
- if (cpu->features & LM32_FEATURE_CYCLE_COUNT) {
- cfg |= CFG_CC;
- }
-
- cfg |= (cpu->num_interrupts << CFG_INT_SHIFT);
- cfg |= (cpu->num_breakpoints << CFG_BP_SHIFT);
- cfg |= (cpu->num_watchpoints << CFG_WP_SHIFT);
- cfg |= (cpu->revision << CFG_REV_SHIFT);
-
- env->cfg = cfg;
-}
-
-static bool lm32_cpu_has_work(CPUState *cs)
-{
- return cs->interrupt_request & CPU_INTERRUPT_HARD;
-}
-
-static void lm32_cpu_reset(DeviceState *dev)
-{
- CPUState *s = CPU(dev);
- LM32CPU *cpu = LM32_CPU(s);
- LM32CPUClass *lcc = LM32_CPU_GET_CLASS(cpu);
- CPULM32State *env = &cpu->env;
-
- lcc->parent_reset(dev);
-
- /* reset cpu state */
- memset(env, 0, offsetof(CPULM32State, end_reset_fields));
-
- lm32_cpu_init_cfg_reg(cpu);
-}
-
-static void lm32_cpu_disas_set_info(CPUState *cpu, disassemble_info *info)
-{
- info->mach = bfd_mach_lm32;
- info->print_insn = print_insn_lm32;
-}
-
-static void lm32_cpu_realizefn(DeviceState *dev, Error **errp)
-{
- CPUState *cs = CPU(dev);
- LM32CPUClass *lcc = LM32_CPU_GET_CLASS(dev);
- Error *local_err = NULL;
-
- cpu_exec_realizefn(cs, &local_err);
- if (local_err != NULL) {
- error_propagate(errp, local_err);
- return;
- }
-
- cpu_reset(cs);
-
- qemu_init_vcpu(cs);
-
- lcc->parent_realize(dev, errp);
-}
-
-static void lm32_cpu_initfn(Object *obj)
-{
- LM32CPU *cpu = LM32_CPU(obj);
- CPULM32State *env = &cpu->env;
-
- cpu_set_cpustate_pointers(cpu);
-
- env->flags = 0;
-}
-
-static void lm32_basic_cpu_initfn(Object *obj)
-{
- LM32CPU *cpu = LM32_CPU(obj);
-
- cpu->revision = 3;
- cpu->num_interrupts = 32;
- cpu->num_breakpoints = 4;
- cpu->num_watchpoints = 4;
- cpu->features = LM32_FEATURE_SHIFT
- | LM32_FEATURE_SIGN_EXTEND
- | LM32_FEATURE_CYCLE_COUNT;
-}
-
-static void lm32_standard_cpu_initfn(Object *obj)
-{
- LM32CPU *cpu = LM32_CPU(obj);
-
- cpu->revision = 3;
- cpu->num_interrupts = 32;
- cpu->num_breakpoints = 4;
- cpu->num_watchpoints = 4;
- cpu->features = LM32_FEATURE_MULTIPLY
- | LM32_FEATURE_DIVIDE
- | LM32_FEATURE_SHIFT
- | LM32_FEATURE_SIGN_EXTEND
- | LM32_FEATURE_I_CACHE
- | LM32_FEATURE_CYCLE_COUNT;
-}
-
-static void lm32_full_cpu_initfn(Object *obj)
-{
- LM32CPU *cpu = LM32_CPU(obj);
-
- cpu->revision = 3;
- cpu->num_interrupts = 32;
- cpu->num_breakpoints = 4;
- cpu->num_watchpoints = 4;
- cpu->features = LM32_FEATURE_MULTIPLY
- | LM32_FEATURE_DIVIDE
- | LM32_FEATURE_SHIFT
- | LM32_FEATURE_SIGN_EXTEND
- | LM32_FEATURE_I_CACHE
- | LM32_FEATURE_D_CACHE
- | LM32_FEATURE_CYCLE_COUNT;
-}
-
-static ObjectClass *lm32_cpu_class_by_name(const char *cpu_model)
-{
- ObjectClass *oc;
- char *typename;
-
- typename = g_strdup_printf(LM32_CPU_TYPE_NAME("%s"), cpu_model);
- oc = object_class_by_name(typename);
- g_free(typename);
- if (oc != NULL && (!object_class_dynamic_cast(oc, TYPE_LM32_CPU) ||
- object_class_is_abstract(oc))) {
- oc = NULL;
- }
- return oc;
-}
-
-#include "hw/core/tcg-cpu-ops.h"
-
-static struct TCGCPUOps lm32_tcg_ops = {
- .initialize = lm32_translate_init,
- .cpu_exec_interrupt = lm32_cpu_exec_interrupt,
- .tlb_fill = lm32_cpu_tlb_fill,
- .debug_excp_handler = lm32_debug_excp_handler,
-
-#ifndef CONFIG_USER_ONLY
- .do_interrupt = lm32_cpu_do_interrupt,
-#endif /* !CONFIG_USER_ONLY */
-};
-
-static void lm32_cpu_class_init(ObjectClass *oc, void *data)
-{
- LM32CPUClass *lcc = LM32_CPU_CLASS(oc);
- CPUClass *cc = CPU_CLASS(oc);
- DeviceClass *dc = DEVICE_CLASS(oc);
-
- device_class_set_parent_realize(dc, lm32_cpu_realizefn,
- &lcc->parent_realize);
- device_class_set_parent_reset(dc, lm32_cpu_reset, &lcc->parent_reset);
-
- cc->class_by_name = lm32_cpu_class_by_name;
- cc->has_work = lm32_cpu_has_work;
- cc->dump_state = lm32_cpu_dump_state;
- cc->set_pc = lm32_cpu_set_pc;
- cc->gdb_read_register = lm32_cpu_gdb_read_register;
- cc->gdb_write_register = lm32_cpu_gdb_write_register;
-#ifndef CONFIG_USER_ONLY
- cc->get_phys_page_debug = lm32_cpu_get_phys_page_debug;
- cc->vmsd = &vmstate_lm32_cpu;
-#endif
- cc->gdb_num_core_regs = 32 + 7;
- cc->gdb_stop_before_watchpoint = true;
- cc->disas_set_info = lm32_cpu_disas_set_info;
- cc->tcg_ops = &lm32_tcg_ops;
-}
-
-#define DEFINE_LM32_CPU_TYPE(cpu_model, initfn) \
- { \
- .parent = TYPE_LM32_CPU, \
- .name = LM32_CPU_TYPE_NAME(cpu_model), \
- .instance_init = initfn, \
- }
-
-static const TypeInfo lm32_cpus_type_infos[] = {
- { /* base class should be registered first */
- .name = TYPE_LM32_CPU,
- .parent = TYPE_CPU,
- .instance_size = sizeof(LM32CPU),
- .instance_init = lm32_cpu_initfn,
- .abstract = true,
- .class_size = sizeof(LM32CPUClass),
- .class_init = lm32_cpu_class_init,
- },
- DEFINE_LM32_CPU_TYPE("lm32-basic", lm32_basic_cpu_initfn),
- DEFINE_LM32_CPU_TYPE("lm32-standard", lm32_standard_cpu_initfn),
- DEFINE_LM32_CPU_TYPE("lm32-full", lm32_full_cpu_initfn),
-};
-
-DEFINE_TYPES(lm32_cpus_type_infos)
diff --git a/target/lm32/cpu.h b/target/lm32/cpu.h
deleted file mode 100644
index ea7c01ca8b..0000000000
--- a/target/lm32/cpu.h
+++ /dev/null
@@ -1,262 +0,0 @@
-/*
- * LatticeMico32 virtual CPU header.
- *
- * Copyright (c) 2010 Michael Walle <michael@walle.cc>
- *
- * 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.1 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/>.
- */
-
-#ifndef LM32_CPU_H
-#define LM32_CPU_H
-
-#include "cpu-qom.h"
-#include "exec/cpu-defs.h"
-
-typedef struct CPULM32State CPULM32State;
-
-static inline int cpu_mmu_index(CPULM32State *env, bool ifetch)
-{
- return 0;
-}
-
-/* Exceptions indices */
-enum {
- EXCP_RESET = 0,
- EXCP_BREAKPOINT,
- EXCP_INSN_BUS_ERROR,
- EXCP_WATCHPOINT,
- EXCP_DATA_BUS_ERROR,
- EXCP_DIVIDE_BY_ZERO,
- EXCP_IRQ,
- EXCP_SYSTEMCALL
-};
-
-/* Registers */
-enum {
- R_R0 = 0, R_R1, R_R2, R_R3, R_R4, R_R5, R_R6, R_R7, R_R8, R_R9, R_R10,
- R_R11, R_R12, R_R13, R_R14, R_R15, R_R16, R_R17, R_R18, R_R19, R_R20,
- R_R21, R_R22, R_R23, R_R24, R_R25, R_R26, R_R27, R_R28, R_R29, R_R30,
- R_R31
-};
-
-/* Register aliases */
-enum {
- R_GP = R_R26,
- R_FP = R_R27,
- R_SP = R_R28,
- R_RA = R_R29,
- R_EA = R_R30,
- R_BA = R_R31
-};
-
-/* IE flags */
-enum {
- IE_IE = (1<<0),
- IE_EIE = (1<<1),
- IE_BIE = (1<<2),
-};
-
-/* DC flags */
-enum {
- DC_SS = (1<<0),
- DC_RE = (1<<1),
- DC_C0 = (1<<2),
- DC_C1 = (1<<3),
- DC_C2 = (1<<4),
- DC_C3 = (1<<5),
-};
-
-/* CFG mask */
-enum {
- CFG_M = (1<<0),
- CFG_D = (1<<1),
- CFG_S = (1<<2),
- CFG_U = (1<<3),
- CFG_X = (1<<4),
- CFG_CC = (1<<5),
- CFG_IC = (1<<6),
- CFG_DC = (1<<7),
- CFG_G = (1<<8),
- CFG_H = (1<<9),
- CFG_R = (1<<10),
- CFG_J = (1<<11),
- CFG_INT_SHIFT = 12,
- CFG_BP_SHIFT = 18,
- CFG_WP_SHIFT = 22,
- CFG_REV_SHIFT = 26,
-};
-
-/* CSRs */
-enum {
- CSR_IE = 0x00,
- CSR_IM = 0x01,
- CSR_IP = 0x02,
- CSR_ICC = 0x03,
- CSR_DCC = 0x04,
- CSR_CC = 0x05,
- CSR_CFG = 0x06,
- CSR_EBA = 0x07,
- CSR_DC = 0x08,
- CSR_DEBA = 0x09,
- CSR_JTX = 0x0e,
- CSR_JRX = 0x0f,
- CSR_BP0 = 0x10,
- CSR_BP1 = 0x11,
- CSR_BP2 = 0x12,
- CSR_BP3 = 0x13,
- CSR_WP0 = 0x18,
- CSR_WP1 = 0x19,
- CSR_WP2 = 0x1a,
- CSR_WP3 = 0x1b,
-};
-
-enum {
- LM32_FEATURE_MULTIPLY = 1,
- LM32_FEATURE_DIVIDE = 2,
- LM32_FEATURE_SHIFT = 4,
- LM32_FEATURE_SIGN_EXTEND = 8,
- LM32_FEATURE_I_CACHE = 16,
- LM32_FEATURE_D_CACHE = 32,
- LM32_FEATURE_CYCLE_COUNT = 64,
-};
-
-enum {
- LM32_FLAG_IGNORE_MSB = 1,
-};
-
-struct CPULM32State {
- /* general registers */
- uint32_t regs[32];
-
- /* special registers */
- uint32_t pc; /* program counter */
- uint32_t ie; /* interrupt enable */
- uint32_t icc; /* instruction cache control */
- uint32_t dcc; /* data cache control */
- uint32_t cc; /* cycle counter */
- uint32_t cfg; /* configuration */
-
- /* debug registers */
- uint32_t dc; /* debug control */
- uint32_t bp[4]; /* breakpoints */
- uint32_t wp[4]; /* watchpoints */
-
- struct CPUBreakpoint *cpu_breakpoint[4];
- struct CPUWatchpoint *cpu_watchpoint[4];
-
- /* Fields up to this point are cleared by a CPU reset */
- struct {} end_reset_fields;
-
- /* Fields from here on are preserved across CPU reset. */
- uint32_t eba; /* exception base address */
- uint32_t deba; /* debug exception base address */
-
- /* interrupt controller handle for callbacks */
- DeviceState *pic_state;
- /* JTAG UART handle for callbacks */
- DeviceState *juart_state;
-
- /* processor core features */
- uint32_t flags;
-
-};
-
-/**
- * LM32CPU:
- * @env: #CPULM32State
- *
- * A LatticeMico32 CPU.
- */
-struct LM32CPU {
- /*< private >*/
- CPUState parent_obj;
- /*< public >*/
-
- CPUNegativeOffsetState neg;
- CPULM32State env;
-
- uint32_t revision;
- uint8_t num_interrupts;
- uint8_t num_breakpoints;
- uint8_t num_watchpoints;
- uint32_t features;
-};
-
-
-#ifndef CONFIG_USER_ONLY
-extern const VMStateDescription vmstate_lm32_cpu;
-#endif
-
-void lm32_cpu_do_interrupt(CPUState *cpu);
-bool lm32_cpu_exec_interrupt(CPUState *cs, int int_req);
-void lm32_cpu_dump_state(CPUState *cpu, FILE *f, int flags);
-hwaddr lm32_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
-int lm32_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg);
-int lm32_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
-
-typedef enum {
- LM32_WP_DISABLED = 0,
- LM32_WP_READ,
- LM32_WP_WRITE,
- LM32_WP_READ_WRITE,
-} lm32_wp_t;
-
-static inline lm32_wp_t lm32_wp_type(uint32_t dc, int idx)
-{
- assert(idx < 4);
- return (dc >> (idx+1)*2) & 0x3;
-}
-
-/* you can call this signal handler from your SIGBUS and SIGSEGV
- signal handlers to inform the virtual CPU of exceptions. non zero
- is returned if the signal was handled by the virtual CPU. */
-int cpu_lm32_signal_handler(int host_signum, void *pinfo,
- void *puc);
-void lm32_cpu_list(void);
-void lm32_translate_init(void);
-void cpu_lm32_set_phys_msb_ignore(CPULM32State *env, int value);
-void QEMU_NORETURN raise_exception(CPULM32State *env, int index);
-void lm32_debug_excp_handler(CPUState *cs);
-void lm32_breakpoint_insert(CPULM32State *env, int index, target_ulong address);
-void lm32_breakpoint_remove(CPULM32State *env, int index);
-void lm32_watchpoint_insert(CPULM32State *env, int index, target_ulong address,
- lm32_wp_t wp_type);
-void lm32_watchpoint_remove(CPULM32State *env, int index);
-bool lm32_cpu_do_semihosting(CPUState *cs);
-
-#define LM32_CPU_TYPE_SUFFIX "-" TYPE_LM32_CPU
-#define LM32_CPU_TYPE_NAME(model) model LM32_CPU_TYPE_SUFFIX
-#define CPU_RESOLVING_TYPE TYPE_LM32_CPU
-
-#define cpu_list lm32_cpu_list
-#define cpu_signal_handler cpu_lm32_signal_handler
-
-bool lm32_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
- MMUAccessType access_type, int mmu_idx,
- bool probe, uintptr_t retaddr);
-
-typedef CPULM32State CPUArchState;
-typedef LM32CPU ArchCPU;
-
-#include "exec/cpu-all.h"
-
-static inline void cpu_get_tb_cpu_state(CPULM32State *env, target_ulong *pc,
- target_ulong *cs_base, uint32_t *flags)
-{
- *pc = env->pc;
- *cs_base = 0;
- *flags = 0;
-}
-
-#endif
diff --git a/target/lm32/gdbstub.c b/target/lm32/gdbstub.c
deleted file mode 100644
index 56f508a5b6..0000000000
--- a/target/lm32/gdbstub.c
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * LM32 gdb server stub
- *
- * Copyright (c) 2003-2005 Fabrice Bellard
- * Copyright (c) 2013 SUSE LINUX Products GmbH
- *
- * 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.1 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/gdbstub.h"
-#include "hw/lm32/lm32_pic.h"
-
-int lm32_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n)
-{
- LM32CPU *cpu = LM32_CPU(cs);
- CPULM32State *env = &cpu->env;
-
- if (n < 32) {
- return gdb_get_reg32(mem_buf, env->regs[n]);
- } else {
- switch (n) {
- case 32:
- return gdb_get_reg32(mem_buf, env->pc);
- /* FIXME: put in right exception ID */
- case 33:
- return gdb_get_reg32(mem_buf, 0);
- case 34:
- return gdb_get_reg32(mem_buf, env->eba);
- case 35:
- return gdb_get_reg32(mem_buf, env->deba);
- case 36:
- return gdb_get_reg32(mem_buf, env->ie);
- case 37:
- return gdb_get_reg32(mem_buf, lm32_pic_get_im(env->pic_state));
- case 38:
- return gdb_get_reg32(mem_buf, lm32_pic_get_ip(env->pic_state));
- }
- }
- return 0;
-}
-
-int lm32_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
-{
- LM32CPU *cpu = LM32_CPU(cs);
- CPUClass *cc = CPU_GET_CLASS(cs);
- CPULM32State *env = &cpu->env;
- uint32_t tmp;
-
- if (n > cc->gdb_num_core_regs) {
- return 0;
- }
-
- tmp = ldl_p(mem_buf);
-
- if (n < 32) {
- env->regs[n] = tmp;
- } else {
- switch (n) {
- case 32:
- env->pc = tmp;
- break;
- case 34:
- env->eba = tmp;
- break;
- case 35:
- env->deba = tmp;
- break;
- case 36:
- env->ie = tmp;
- break;
- case 37:
- lm32_pic_set_im(env->pic_state, tmp);
- break;
- case 38:
- lm32_pic_set_ip(env->pic_state, tmp);
- break;
- }
- }
- return 4;
-}
diff --git a/target/lm32/helper.c b/target/lm32/helper.c
deleted file mode 100644
index 01cc3c53a5..0000000000
--- a/target/lm32/helper.c
+++ /dev/null
@@ -1,224 +0,0 @@
-/*
- * LatticeMico32 helper routines.
- *
- * Copyright (c) 2010-2014 Michael Walle <michael@walle.cc>
- *
- * 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.1 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/exec-all.h"
-#include "qemu/host-utils.h"
-#include "semihosting/semihost.h"
-#include "exec/log.h"
-
-bool lm32_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
- MMUAccessType access_type, int mmu_idx,
- bool probe, uintptr_t retaddr)
-{
- LM32CPU *cpu = LM32_CPU(cs);
- CPULM32State *env = &cpu->env;
- int prot;
-
- address &= TARGET_PAGE_MASK;
- prot = PAGE_BITS;
- if (env->flags & LM32_FLAG_IGNORE_MSB) {
- tlb_set_page(cs, address, address & 0x7fffffff, prot, mmu_idx,
- TARGET_PAGE_SIZE);
- } else {
- tlb_set_page(cs, address, address, prot, mmu_idx, TARGET_PAGE_SIZE);
- }
- return true;
-}
-
-hwaddr lm32_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
-{
- LM32CPU *cpu = LM32_CPU(cs);
-
- addr &= TARGET_PAGE_MASK;
- if (cpu->env.flags & LM32_FLAG_IGNORE_MSB) {
- return addr & 0x7fffffff;
- } else {
- return addr;
- }
-}
-
-void lm32_breakpoint_insert(CPULM32State *env, int idx, target_ulong address)
-{
- cpu_breakpoint_insert(env_cpu(env), address, BP_CPU,
- &env->cpu_breakpoint[idx]);
-}
-
-void lm32_breakpoint_remove(CPULM32State *env, int idx)
-{
- if (!env->cpu_breakpoint[idx]) {
- return;
- }
-
- cpu_breakpoint_remove_by_ref(env_cpu(env), env->cpu_breakpoint[idx]);
- env->cpu_breakpoint[idx] = NULL;
-}
-
-void lm32_watchpoint_insert(CPULM32State *env, int idx, target_ulong address,
- lm32_wp_t wp_type)
-{
- int flags = 0;
-
- switch (wp_type) {
- case LM32_WP_DISABLED:
- /* nothing to do */
- break;
- case LM32_WP_READ:
- flags = BP_CPU | BP_STOP_BEFORE_ACCESS | BP_MEM_READ;
- break;
- case LM32_WP_WRITE:
- flags = BP_CPU | BP_STOP_BEFORE_ACCESS | BP_MEM_WRITE;
- break;
- case LM32_WP_READ_WRITE:
- flags = BP_CPU | BP_STOP_BEFORE_ACCESS | BP_MEM_ACCESS;
- break;
- }
-
- if (flags != 0) {
- cpu_watchpoint_insert(env_cpu(env), address, 1, flags,
- &env->cpu_watchpoint[idx]);
- }
-}
-
-void lm32_watchpoint_remove(CPULM32State *env, int idx)
-{
- if (!env->cpu_watchpoint[idx]) {
- return;
- }
-
- cpu_watchpoint_remove_by_ref(env_cpu(env), env->cpu_watchpoint[idx]);
- env->cpu_watchpoint[idx] = NULL;
-}
-
-static bool check_watchpoints(CPULM32State *env)
-{
- LM32CPU *cpu = env_archcpu(env);
- int i;
-
- for (i = 0; i < cpu->num_watchpoints; i++) {
- if (env->cpu_watchpoint[i] &&
- env->cpu_watchpoint[i]->flags & BP_WATCHPOINT_HIT) {
- return true;
- }
- }
- return false;
-}
-
-void lm32_debug_excp_handler(CPUState *cs)
-{
- LM32CPU *cpu = LM32_CPU(cs);
- CPULM32State *env = &cpu->env;
- CPUBreakpoint *bp;
-
- if (cs->watchpoint_hit) {
- if (cs->watchpoint_hit->flags & BP_CPU) {
- cs->watchpoint_hit = NULL;
- if (check_watchpoints(env)) {
- raise_exception(env, EXCP_WATCHPOINT);
- } else {
- cpu_loop_exit_noexc(cs);
- }
- }
- } else {
- QTAILQ_FOREACH(bp, &cs->breakpoints, entry) {
- if (bp->pc == env->pc) {
- if (bp->flags & BP_CPU) {
- raise_exception(env, EXCP_BREAKPOINT);
- }
- break;
- }
- }
- }
-}
-
-void lm32_cpu_do_interrupt(CPUState *cs)
-{
- LM32CPU *cpu = LM32_CPU(cs);
- CPULM32State *env = &cpu->env;
-
- qemu_log_mask(CPU_LOG_INT,
- "exception at pc=%x type=%x\n", env->pc, cs->exception_index);
-
- switch (cs->exception_index) {
- case EXCP_SYSTEMCALL:
- if (unlikely(semihosting_enabled())) {
- /* do_semicall() returns true if call was handled. Otherwise
- * do the normal exception handling. */
- if (lm32_cpu_do_semihosting(cs)) {
- env->pc += 4;
- break;
- }
- }
- /* fall through */
- case EXCP_INSN_BUS_ERROR:
- case EXCP_DATA_BUS_ERROR:
- case EXCP_DIVIDE_BY_ZERO:
- case EXCP_IRQ:
- /* non-debug exceptions */
- env->regs[R_EA] = env->pc;
- env->ie |= (env->ie & IE_IE) ? IE_EIE : 0;
- env->ie &= ~IE_IE;
- if (env->dc & DC_RE) {
- env->pc = env->deba + (cs->exception_index * 32);
- } else {
- env->pc = env->eba + (cs->exception_index * 32);
- }
- log_cpu_state_mask(CPU_LOG_INT, cs, 0);
- break;
- case EXCP_BREAKPOINT:
- case EXCP_WATCHPOINT:
- /* debug exceptions */
- env->regs[R_BA] = env->pc;
- env->ie |= (env->ie & IE_IE) ? IE_BIE : 0;
- env->ie &= ~IE_IE;
- env->pc = env->deba + (cs->exception_index * 32);
- log_cpu_state_mask(CPU_LOG_INT, cs, 0);
- break;
- default:
- cpu_abort(cs, "unhandled exception type=%d\n",
- cs->exception_index);
- break;
- }
-}
-
-bool lm32_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
-{
- LM32CPU *cpu = LM32_CPU(cs);
- CPULM32State *env = &cpu->env;
-
- if ((interrupt_request & CPU_INTERRUPT_HARD) && (env->ie & IE_IE)) {
- cs->exception_index = EXCP_IRQ;
- lm32_cpu_do_interrupt(cs);
- return true;
- }
- return false;
-}
-
-/* Some soc ignores the MSB on the address bus. Thus creating a shadow memory
- * area. As a general rule, 0x00000000-0x7fffffff is cached, whereas
- * 0x80000000-0xffffffff is not cached and used to access IO devices. */
-void cpu_lm32_set_phys_msb_ignore(CPULM32State *env, int value)
-{
- if (value) {
- env->flags |= LM32_FLAG_IGNORE_MSB;
- } else {
- env->flags &= ~LM32_FLAG_IGNORE_MSB;
- }
-}
diff --git a/target/lm32/helper.h b/target/lm32/helper.h
deleted file mode 100644
index 445578c439..0000000000
--- a/target/lm32/helper.h
+++ /dev/null
@@ -1,14 +0,0 @@
-DEF_HELPER_2(raise_exception, void, env, i32)
-DEF_HELPER_1(hlt, void, env)
-DEF_HELPER_3(wcsr_bp, void, env, i32, i32)
-DEF_HELPER_3(wcsr_wp, void, env, i32, i32)
-DEF_HELPER_2(wcsr_dc, void, env, i32)
-DEF_HELPER_2(wcsr_im, void, env, i32)
-DEF_HELPER_2(wcsr_ip, void, env, i32)
-DEF_HELPER_2(wcsr_jtx, void, env, i32)
-DEF_HELPER_2(wcsr_jrx, void, env, i32)
-DEF_HELPER_1(rcsr_im, i32, env)
-DEF_HELPER_1(rcsr_ip, i32, env)
-DEF_HELPER_1(rcsr_jtx, i32, env)
-DEF_HELPER_1(rcsr_jrx, i32, env)
-DEF_HELPER_1(ill, void, env)
diff --git a/target/lm32/lm32-semi.c b/target/lm32/lm32-semi.c
deleted file mode 100644
index 661a770249..0000000000
--- a/target/lm32/lm32-semi.c
+++ /dev/null
@@ -1,211 +0,0 @@
-/*
- * Lattice Mico32 semihosting syscall interface
- *
- * Copyright (c) 2014 Michael Walle <michael@walle.cc>
- *
- * 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.
- * See the COPYING file in the top-level directory.
- */
-
-#include "qemu/osdep.h"
-#include "cpu.h"
-#include "exec/helper-proto.h"
-#include "exec/softmmu-semi.h"
-
-enum {
- TARGET_SYS_exit = 1,
- TARGET_SYS_open = 2,
- TARGET_SYS_close = 3,
- TARGET_SYS_read = 4,
- TARGET_SYS_write = 5,
- TARGET_SYS_lseek = 6,
- TARGET_SYS_fstat = 10,
- TARGET_SYS_stat = 15,
-};
-
-enum {
- NEWLIB_O_RDONLY = 0x0,
- NEWLIB_O_WRONLY = 0x1,
- NEWLIB_O_RDWR = 0x2,
- NEWLIB_O_APPEND = 0x8,
- NEWLIB_O_CREAT = 0x200,
- NEWLIB_O_TRUNC = 0x400,
- NEWLIB_O_EXCL = 0x800,
-};
-
-static int translate_openflags(int flags)
-{
- int hf;
-
- if (flags & NEWLIB_O_WRONLY) {
- hf = O_WRONLY;
- } else if (flags & NEWLIB_O_RDWR) {
- hf = O_RDWR;
- } else {
- hf = O_RDONLY;
- }
-
- if (flags & NEWLIB_O_APPEND) {
- hf |= O_APPEND;
- }
-
- if (flags & NEWLIB_O_CREAT) {
- hf |= O_CREAT;
- }
-
- if (flags & NEWLIB_O_TRUNC) {
- hf |= O_TRUNC;
- }
-
- if (flags & NEWLIB_O_EXCL) {
- hf |= O_EXCL;
- }
-
- return hf;
-}
-
-struct newlib_stat {
- int16_t newlib_st_dev; /* device */
- uint16_t newlib_st_ino; /* inode */
- uint16_t newlib_st_mode; /* protection */
- uint16_t newlib_st_nlink; /* number of hard links */
- uint16_t newlib_st_uid; /* user ID of owner */
- uint16_t newlib_st_gid; /* group ID of owner */
- int16_t newlib_st_rdev; /* device type (if inode device) */
- int32_t newlib_st_size; /* total size, in bytes */
- int32_t newlib_st_atime; /* time of last access */
- uint32_t newlib_st_spare1;
- int32_t newlib_st_mtime; /* time of last modification */
- uint32_t newlib_st_spare2;
- int32_t newlib_st_ctime; /* time of last change */
- uint32_t newlib_st_spare3;
-} QEMU_PACKED;
-
-static int translate_stat(CPULM32State *env, target_ulong addr,
- struct stat *s)
-{
- struct newlib_stat *p;
-
- p = lock_user(VERIFY_WRITE, addr, sizeof(struct newlib_stat), 0);
- if (!p) {
- return 0;
- }
- p->newlib_st_dev = cpu_to_be16(s->st_dev);
- p->newlib_st_ino = cpu_to_be16(s->st_ino);
- p->newlib_st_mode = cpu_to_be16(s->st_mode);
- p->newlib_st_nlink = cpu_to_be16(s->st_nlink);
- p->newlib_st_uid = cpu_to_be16(s->st_uid);
- p->newlib_st_gid = cpu_to_be16(s->st_gid);
- p->newlib_st_rdev = cpu_to_be16(s->st_rdev);
- p->newlib_st_size = cpu_to_be32(s->st_size);
- p->newlib_st_atime = cpu_to_be32(s->st_atime);
- p->newlib_st_mtime = cpu_to_be32(s->st_mtime);
- p->newlib_st_ctime = cpu_to_be32(s->st_ctime);
- unlock_user(p, addr, sizeof(struct newlib_stat));
-
- return 1;
-}
-
-bool lm32_cpu_do_semihosting(CPUState *cs)
-{
- LM32CPU *cpu = LM32_CPU(cs);
- CPULM32State *env = &cpu->env;
-
- int ret = -1;
- target_ulong nr, arg0, arg1, arg2;
- void *p;
- struct stat s;
-
- nr = env->regs[R_R8];
- arg0 = env->regs[R_R1];
- arg1 = env->regs[R_R2];
- arg2 = env->regs[R_R3];
-
- switch (nr) {
- case TARGET_SYS_exit:
- /* void _exit(int rc) */
- exit(arg0);
-
- case TARGET_SYS_open:
- /* int open(const char *pathname, int flags) */
- p = lock_user_string(arg0);
- if (!p) {
- ret = -1;
- } else {
- ret = open(p, translate_openflags(arg2));
- unlock_user(p, arg0, 0);
- }
- break;
-
- case TARGET_SYS_read:
- /* ssize_t read(int fd, const void *buf, size_t count) */
- p = lock_user(VERIFY_WRITE, arg1, arg2, 0);
- if (!p) {
- ret = -1;
- } else {
- ret = read(arg0, p, arg2);
- unlock_user(p, arg1, arg2);
- }
- break;
-
- case TARGET_SYS_write:
- /* ssize_t write(int fd, const void *buf, size_t count) */
- p = lock_user(VERIFY_READ, arg1, arg2, 1);
- if (!p) {
- ret = -1;
- } else {
- ret = write(arg0, p, arg2);
- unlock_user(p, arg1, 0);
- }
- break;
-
- case TARGET_SYS_close:
- /* int close(int fd) */
- /* don't close stdin/stdout/stderr */
- if (arg0 > 2) {
- ret = close(arg0);
- } else {
- ret = 0;
- }
- break;
-
- case TARGET_SYS_lseek:
- /* off_t lseek(int fd, off_t offset, int whence */
- ret = lseek(arg0, arg1, arg2);
- break;
-
- case TARGET_SYS_stat:
- /* int stat(const char *path, struct stat *buf) */
- p = lock_user_string(arg0);
- if (!p) {
- ret = -1;
- } else {
- ret = stat(p, &s);
- unlock_user(p, arg0, 0);
- if (translate_stat(env, arg1, &s) == 0) {
- ret = -1;
- }
- }
- break;
-
- case TARGET_SYS_fstat:
- /* int stat(int fd, struct stat *buf) */
- ret = fstat(arg0, &s);
- if (ret == 0) {
- if (translate_stat(env, arg1, &s) == 0) {
- ret = -1;
- }
- }
- break;
-
- default:
- /* unhandled */
- return false;
- }
-
- env->regs[R_R1] = ret;
- return true;
-}
diff --git a/target/lm32/machine.c b/target/lm32/machine.c
deleted file mode 100644
index 365eaa2e47..0000000000
--- a/target/lm32/machine.c
+++ /dev/null
@@ -1,33 +0,0 @@
-#include "qemu/osdep.h"
-#include "cpu.h"
-#include "migration/cpu.h"
-
-static const VMStateDescription vmstate_env = {
- .name = "env",
- .version_id = 1,
- .minimum_version_id = 1,
- .fields = (VMStateField[]) {
- VMSTATE_UINT32_ARRAY(regs, CPULM32State, 32),
- VMSTATE_UINT32(pc, CPULM32State),
- VMSTATE_UINT32(ie, CPULM32State),
- VMSTATE_UINT32(icc, CPULM32State),
- VMSTATE_UINT32(dcc, CPULM32State),
- VMSTATE_UINT32(cc, CPULM32State),
- VMSTATE_UINT32(eba, CPULM32State),
- VMSTATE_UINT32(dc, CPULM32State),
- VMSTATE_UINT32(deba, CPULM32State),
- VMSTATE_UINT32_ARRAY(bp, CPULM32State, 4),
- VMSTATE_UINT32_ARRAY(wp, CPULM32State, 4),
- VMSTATE_END_OF_LIST()
- }
-};
-
-const VMStateDescription vmstate_lm32_cpu = {
- .name = "cpu",
- .version_id = 1,
- .minimum_version_id = 1,
- .fields = (VMStateField[]) {
- VMSTATE_STRUCT(env, LM32CPU, 1, vmstate_env, CPULM32State),
- VMSTATE_END_OF_LIST()
- }
-};
diff --git a/target/lm32/meson.build b/target/lm32/meson.build
deleted file mode 100644
index ef0eef07f1..0000000000
--- a/target/lm32/meson.build
+++ /dev/null
@@ -1,15 +0,0 @@
-lm32_ss = ss.source_set()
-lm32_ss.add(files(
- 'cpu.c',
- 'gdbstub.c',
- 'helper.c',
- 'lm32-semi.c',
- 'op_helper.c',
- 'translate.c',
-))
-
-lm32_softmmu_ss = ss.source_set()
-lm32_softmmu_ss.add(files('machine.c'))
-
-target_arch += {'lm32': lm32_ss}
-target_softmmu_arch += {'lm32': lm32_softmmu_ss}
diff --git a/target/lm32/op_helper.c b/target/lm32/op_helper.c
deleted file mode 100644
index e39fcd5647..0000000000
--- a/target/lm32/op_helper.c
+++ /dev/null
@@ -1,148 +0,0 @@
-#include "qemu/osdep.h"
-#include "cpu.h"
-#include "exec/helper-proto.h"
-#include "qemu/host-utils.h"
-#include "qemu/main-loop.h"
-#include "sysemu/runstate.h"
-
-#include "hw/lm32/lm32_pic.h"
-#include "hw/char/lm32_juart.h"
-
-#include "exec/exec-all.h"
-#include "exec/cpu_ldst.h"
-
-#ifndef CONFIG_USER_ONLY
-#endif
-
-#if !defined(CONFIG_USER_ONLY)
-void raise_exception(CPULM32State *env, int index)
-{
- CPUState *cs = env_cpu(env);
-
- cs->exception_index = index;
- cpu_loop_exit(cs);
-}
-
-void HELPER(raise_exception)(CPULM32State *env, uint32_t index)
-{
- raise_exception(env, index);
-}
-
-void HELPER(hlt)(CPULM32State *env)
-{
- CPUState *cs = env_cpu(env);
-
- cs->halted = 1;
- cs->exception_index = EXCP_HLT;
- cpu_loop_exit(cs);
-}
-
-void HELPER(ill)(CPULM32State *env)
-{
-#ifndef CONFIG_USER_ONLY
- CPUState *cs = env_cpu(env);
- fprintf(stderr, "VM paused due to illegal instruction. "
- "Connect a debugger or switch to the monitor console "
- "to find out more.\n");
- vm_stop(RUN_STATE_PAUSED);
- cs->halted = 1;
- raise_exception(env, EXCP_HALTED);
-#endif
-}
-
-void HELPER(wcsr_bp)(CPULM32State *env, uint32_t bp, uint32_t idx)
-{
- uint32_t addr = bp & ~1;
-
- assert(idx < 4);
-
- env->bp[idx] = bp;
- lm32_breakpoint_remove(env, idx);
- if (bp & 1) {
- lm32_breakpoint_insert(env, idx, addr);
- }
-}
-
-void HELPER(wcsr_wp)(CPULM32State *env, uint32_t wp, uint32_t idx)
-{
- lm32_wp_t wp_type;
-
- assert(idx < 4);
-
- env->wp[idx] = wp;
-
- wp_type = lm32_wp_type(env->dc, idx);
- lm32_watchpoint_remove(env, idx);
- if (wp_type != LM32_WP_DISABLED) {
- lm32_watchpoint_insert(env, idx, wp, wp_type);
- }
-}
-
-void HELPER(wcsr_dc)(CPULM32State *env, uint32_t dc)
-{
- uint32_t old_dc;
- int i;
- lm32_wp_t old_type;
- lm32_wp_t new_type;
-
- old_dc = env->dc;
- env->dc = dc;
-
- for (i = 0; i < 4; i++) {
- old_type = lm32_wp_type(old_dc, i);
- new_type = lm32_wp_type(dc, i);
-
- if (old_type != new_type) {
- lm32_watchpoint_remove(env, i);
- if (new_type != LM32_WP_DISABLED) {
- lm32_watchpoint_insert(env, i, env->wp[i], new_type);
- }
- }
- }
-}
-
-void HELPER(wcsr_im)(CPULM32State *env, uint32_t im)
-{
- qemu_mutex_lock_iothread();
- lm32_pic_set_im(env->pic_state, im);
- qemu_mutex_unlock_iothread();
-}
-
-void HELPER(wcsr_ip)(CPULM32State *env, uint32_t im)
-{
- qemu_mutex_lock_iothread();
- lm32_pic_set_ip(env->pic_state, im);
- qemu_mutex_unlock_iothread();
-}
-
-void HELPER(wcsr_jtx)(CPULM32State *env, uint32_t jtx)
-{
- lm32_juart_set_jtx(env->juart_state, jtx);
-}
-
-void HELPER(wcsr_jrx)(CPULM32State *env, uint32_t jrx)
-{
- lm32_juart_set_jrx(env->juart_state, jrx);
-}
-
-uint32_t HELPER(rcsr_im)(CPULM32State *env)
-{
- return lm32_pic_get_im(env->pic_state);
-}
-
-uint32_t HELPER(rcsr_ip)(CPULM32State *env)
-{
- return lm32_pic_get_ip(env->pic_state);
-}
-
-uint32_t HELPER(rcsr_jtx)(CPULM32State *env)
-{
- return lm32_juart_get_jtx(env->juart_state);
-}
-
-uint32_t HELPER(rcsr_jrx)(CPULM32State *env)
-{
- return lm32_juart_get_jrx(env->juart_state);
-}
-#endif
-
diff --git a/target/lm32/translate.c b/target/lm32/translate.c
deleted file mode 100644
index 20c70d03f1..0000000000
--- a/target/lm32/translate.c
+++ /dev/null
@@ -1,1237 +0,0 @@
-/*
- * LatticeMico32 main translation routines.
- *
- * Copyright (c) 2010 Michael Walle <michael@walle.cc>
- *
- * 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.1 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 "disas/disas.h"
-#include "exec/helper-proto.h"
-#include "exec/exec-all.h"
-#include "exec/translator.h"
-#include "tcg/tcg-op.h"
-#include "qemu/qemu-print.h"
-
-#include "exec/cpu_ldst.h"
-#include "hw/lm32/lm32_pic.h"
-
-#include "exec/helper-gen.h"
-
-#include "trace-tcg.h"
-#include "exec/log.h"
-
-
-#define DISAS_LM32 0
-
-#define LOG_DIS(...) \
- do { \
- if (DISAS_LM32) { \
- qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__); \
- } \
- } while (0)
-
-#define EXTRACT_FIELD(src, start, end) \
- (((src) >> start) & ((1 << (end - start + 1)) - 1))
-
-#define MEM_INDEX 0
-
-/* is_jmp field values */
-#define DISAS_JUMP DISAS_TARGET_0 /* only pc was modified dynamically */
-#define DISAS_UPDATE DISAS_TARGET_1 /* cpu state was modified dynamically */
-#define DISAS_TB_JUMP DISAS_TARGET_2 /* only pc was modified statically */
-
-static TCGv cpu_R[32];
-static TCGv cpu_pc;
-static TCGv cpu_ie;
-static TCGv cpu_icc;
-static TCGv cpu_dcc;
-static TCGv cpu_cc;
-static TCGv cpu_cfg;
-static TCGv cpu_eba;
-static TCGv cpu_dc;
-static TCGv cpu_deba;
-static TCGv cpu_bp[4];
-static TCGv cpu_wp[4];
-
-#include "exec/gen-icount.h"
-
-enum {
- OP_FMT_RI,
- OP_FMT_RR,
- OP_FMT_CR,
- OP_FMT_I
-};
-
-/* This is the state at translation time. */
-typedef struct DisasContext {
- target_ulong pc;
-
- /* Decoder. */
- int format;
- uint32_t ir;
- uint8_t opcode;
- uint8_t r0, r1, r2, csr;
- uint16_t imm5;
- uint16_t imm16;
- uint32_t imm26;
-
- unsigned int delayed_branch;
- unsigned int tb_flags, synced_flags; /* tb dependent flags. */
- int is_jmp;
-
- TranslationBlock *tb;
- int singlestep_enabled;
-
- uint32_t features;
- uint8_t num_breakpoints;
- uint8_t num_watchpoints;
-} DisasContext;
-
-static const char *regnames[] = {
- "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
- "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
- "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
- "r24", "r25", "r26/gp", "r27/fp", "r28/sp", "r29/ra",
- "r30/ea", "r31/ba", "bp0", "bp1", "bp2", "bp3", "wp0",
- "wp1", "wp2", "wp3"
-};
-
-static inline int zero_extend(unsigned int val, int width)
-{
- return val & ((1 << width) - 1);
-}
-
-static inline int sign_extend(unsigned int val, int width)
-{
- int sval;
-
- /* LSL. */
- val <<= 32 - width;
- sval = val;
- /* ASR. */
- sval >>= 32 - width;
-
- return sval;
-}
-
-static inline void t_gen_raise_exception(DisasContext *dc, uint32_t index)
-{
- TCGv_i32 tmp = tcg_const_i32(index);
-
- gen_helper_raise_exception(cpu_env, tmp);
- tcg_temp_free_i32(tmp);
-}
-
-static inline void t_gen_illegal_insn(DisasContext *dc)
-{
- tcg_gen_movi_tl(cpu_pc, dc->pc);
- gen_helper_ill(cpu_env);
-}
-
-static inline bool use_goto_tb(DisasContext *dc, target_ulong dest)
-{
- if (unlikely(dc->singlestep_enabled)) {
- return false;
- }
-
-#ifndef CONFIG_USER_ONLY
- return (dc->tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK);
-#else
- return true;
-#endif
-}
-
-static void gen_goto_tb(DisasContext *dc, int n, target_ulong dest)
-{
- if (use_goto_tb(dc, dest)) {
- tcg_gen_goto_tb(n);
- tcg_gen_movi_tl(cpu_pc, dest);
- tcg_gen_exit_tb(dc->tb, n);
- } else {
- tcg_gen_movi_tl(cpu_pc, dest);
- if (dc->singlestep_enabled) {
- t_gen_raise_exception(dc, EXCP_DEBUG);
- }
- tcg_gen_exit_tb(NULL, 0);
- }
-}
-
-static void dec_add(DisasContext *dc)
-{
- if (dc->format == OP_FMT_RI) {
- if (dc->r0 == R_R0) {
- if (dc->r1 == R_R0 && dc->imm16 == 0) {
- LOG_DIS("nop\n");
- } else {
- LOG_DIS("mvi r%d, %d\n", dc->r1, sign_extend(dc->imm16, 16));
- }
- } else {
- LOG_DIS("addi r%d, r%d, %d\n", dc->r1, dc->r0,
- sign_extend(dc->imm16, 16));
- }
- } else {
- LOG_DIS("add r%d, r%d, r%d\n", dc->r2, dc->r0, dc->r1);
- }
-
- if (dc->format == OP_FMT_RI) {
- tcg_gen_addi_tl(cpu_R[dc->r1], cpu_R[dc->r0],
- sign_extend(dc->imm16, 16));
- } else {
- tcg_gen_add_tl(cpu_R[dc->r2], cpu_R[dc->r0], cpu_R[dc->r1]);
- }
-}
-
-static void dec_and(DisasContext *dc)
-{
- if (dc->format == OP_FMT_RI) {
- LOG_DIS("andi r%d, r%d, %d\n", dc->r1, dc->r0,
- zero_extend(dc->imm16, 16));
- } else {
- LOG_DIS("and r%d, r%d, r%d\n", dc->r2, dc->r0, dc->r1);
- }
-
- if (dc->format == OP_FMT_RI) {
- tcg_gen_andi_tl(cpu_R[dc->r1], cpu_R[dc->r0],
- zero_extend(dc->imm16, 16));
- } else {
- if (dc->r0 == 0 && dc->r1 == 0 && dc->r2 == 0) {
- tcg_gen_movi_tl(cpu_pc, dc->pc + 4);
- gen_helper_hlt(cpu_env);
- } else {
- tcg_gen_and_tl(cpu_R[dc->r2], cpu_R[dc->r0], cpu_R[dc->r1]);
- }
- }
-}
-
-static void dec_andhi(DisasContext *dc)
-{
- LOG_DIS("andhi r%d, r%d, %d\n", dc->r1, dc->r0, dc->imm16);
-
- tcg_gen_andi_tl(cpu_R[dc->r1], cpu_R[dc->r0], (dc->imm16 << 16));
-}
-
-static void dec_b(DisasContext *dc)
-{
- if (dc->r0 == R_RA) {
- LOG_DIS("ret\n");
- } else if (dc->r0 == R_EA) {
- LOG_DIS("eret\n");
- } else if (dc->r0 == R_BA) {
- LOG_DIS("bret\n");
- } else {
- LOG_DIS("b r%d\n", dc->r0);
- }
-
- /* restore IE.IE in case of an eret */
- if (dc->r0 == R_EA) {
- TCGv t0 = tcg_temp_new();
- TCGLabel *l1 = gen_new_label();
- tcg_gen_andi_tl(t0, cpu_ie, IE_EIE);
- tcg_gen_ori_tl(cpu_ie, cpu_ie, IE_IE);
- tcg_gen_brcondi_tl(TCG_COND_EQ, t0, IE_EIE, l1);
- tcg_gen_andi_tl(cpu_ie, cpu_ie, ~IE_IE);
- gen_set_label(l1);
- tcg_temp_free(t0);
- } else if (dc->r0 == R_BA) {
- TCGv t0 = tcg_temp_new();
- TCGLabel *l1 = gen_new_label();
- tcg_gen_andi_tl(t0, cpu_ie, IE_BIE);
- tcg_gen_ori_tl(cpu_ie, cpu_ie, IE_IE);
- tcg_gen_brcondi_tl(TCG_COND_EQ, t0, IE_BIE, l1);
- tcg_gen_andi_tl(cpu_ie, cpu_ie, ~IE_IE);
- gen_set_label(l1);
- tcg_temp_free(t0);
- }
- tcg_gen_mov_tl(cpu_pc, cpu_R[dc->r0]);
-
- dc->is_jmp = DISAS_JUMP;
-}
-
-static void dec_bi(DisasContext *dc)
-{
- LOG_DIS("bi %d\n", sign_extend(dc->imm26 << 2, 26));
-
- gen_goto_tb(dc, 0, dc->pc + (sign_extend(dc->imm26 << 2, 26)));
-
- dc->is_jmp = DISAS_TB_JUMP;
-}
-
-static inline void gen_cond_branch(DisasContext *dc, int cond)
-{
- TCGLabel *l1 = gen_new_label();
- tcg_gen_brcond_tl(cond, cpu_R[dc->r0], cpu_R[dc->r1], l1);
- gen_goto_tb(dc, 0, dc->pc + 4);
- gen_set_label(l1);
- gen_goto_tb(dc, 1, dc->pc + (sign_extend(dc->imm16 << 2, 16)));
- dc->is_jmp = DISAS_TB_JUMP;
-}
-
-static void dec_be(DisasContext *dc)
-{
- LOG_DIS("be r%d, r%d, %d\n", dc->r1, dc->r0,
- sign_extend(dc->imm16, 16) * 4);
-
- gen_cond_branch(dc, TCG_COND_EQ);
-}
-
-static void dec_bg(DisasContext *dc)
-{
- LOG_DIS("bg r%d, r%d, %d\n", dc->r1, dc->r0,
- sign_extend(dc->imm16, 16 * 4));
-
- gen_cond_branch(dc, TCG_COND_GT);
-}
-
-static void dec_bge(DisasContext *dc)
-{
- LOG_DIS("bge r%d, r%d, %d\n", dc->r1, dc->r0,
- sign_extend(dc->imm16, 16) * 4);
-
- gen_cond_branch(dc, TCG_COND_GE);
-}
-
-static void dec_bgeu(DisasContext *dc)
-{
- LOG_DIS("bgeu r%d, r%d, %d\n", dc->r1, dc->r0,
- sign_extend(dc->imm16, 16) * 4);
-
- gen_cond_branch(dc, TCG_COND_GEU);
-}
-
-static void dec_bgu(DisasContext *dc)
-{
- LOG_DIS("bgu r%d, r%d, %d\n", dc->r1, dc->r0,
- sign_extend(dc->imm16, 16) * 4);
-
- gen_cond_branch(dc, TCG_COND_GTU);
-}
-
-static void dec_bne(DisasContext *dc)
-{
- LOG_DIS("bne r%d, r%d, %d\n", dc->r1, dc->r0,
- sign_extend(dc->imm16, 16) * 4);
-
- gen_cond_branch(dc, TCG_COND_NE);
-}
-
-static void dec_call(DisasContext *dc)
-{
- LOG_DIS("call r%d\n", dc->r0);
-
- tcg_gen_movi_tl(cpu_R[R_RA], dc->pc + 4);
- tcg_gen_mov_tl(cpu_pc, cpu_R[dc->r0]);
-
- dc->is_jmp = DISAS_JUMP;
-}
-
-static void dec_calli(DisasContext *dc)
-{
- LOG_DIS("calli %d\n", sign_extend(dc->imm26, 26) * 4);
-
- tcg_gen_movi_tl(cpu_R[R_RA], dc->pc + 4);
- gen_goto_tb(dc, 0, dc->pc + (sign_extend(dc->imm26 << 2, 26)));
-
- dc->is_jmp = DISAS_TB_JUMP;
-}
-
-static inline void gen_compare(DisasContext *dc, int cond)
-{
- int i;
-
- if (dc->format == OP_FMT_RI) {
- switch (cond) {
- case TCG_COND_GEU:
- case TCG_COND_GTU:
- i = zero_extend(dc->imm16, 16);
- break;
- default:
- i = sign_extend(dc->imm16, 16);
- break;
- }
-
- tcg_gen_setcondi_tl(cond, cpu_R[dc->r1], cpu_R[dc->r0], i);
- } else {
- tcg_gen_setcond_tl(cond, cpu_R[dc->r2], cpu_R[dc->r0], cpu_R[dc->r1]);
- }
-}
-
-static void dec_cmpe(DisasContext *dc)
-{
- if (dc->format == OP_FMT_RI) {
- LOG_DIS("cmpei r%d, r%d, %d\n", dc->r1, dc->r0,
- sign_extend(dc->imm16, 16));
- } else {
- LOG_DIS("cmpe r%d, r%d, r%d\n", dc->r2, dc->r0, dc->r1);
- }
-
- gen_compare(dc, TCG_COND_EQ);
-}
-
-static void dec_cmpg(DisasContext *dc)
-{
- if (dc->format == OP_FMT_RI) {
- LOG_DIS("cmpgi r%d, r%d, %d\n", dc->r1, dc->r0,
- sign_extend(dc->imm16, 16));
- } else {
- LOG_DIS("cmpg r%d, r%d, r%d\n", dc->r2, dc->r0, dc->r1);
- }
-
- gen_compare(dc, TCG_COND_GT);
-}
-
-static void dec_cmpge(DisasContext *dc)
-{
- if (dc->format == OP_FMT_RI) {
- LOG_DIS("cmpgei r%d, r%d, %d\n", dc->r1, dc->r0,
- sign_extend(dc->imm16, 16));
- } else {
- LOG_DIS("cmpge r%d, r%d, r%d\n", dc->r2, dc->r0, dc->r1);
- }
-
- gen_compare(dc, TCG_COND_GE);
-}
-
-static void dec_cmpgeu(DisasContext *dc)
-{
- if (dc->format == OP_FMT_RI) {
- LOG_DIS("cmpgeui r%d, r%d, %d\n", dc->r1, dc->r0,
- zero_extend(dc->imm16, 16));
- } else {
- LOG_DIS("cmpgeu r%d, r%d, r%d\n", dc->r2, dc->r0, dc->r1);
- }
-
- gen_compare(dc, TCG_COND_GEU);
-}
-
-static void dec_cmpgu(DisasContext *dc)
-{
- if (dc->format == OP_FMT_RI) {
- LOG_DIS("cmpgui r%d, r%d, %d\n", dc->r1, dc->r0,
- zero_extend(dc->imm16, 16));
- } else {
- LOG_DIS("cmpgu r%d, r%d, r%d\n", dc->r2, dc->r0, dc->r1);
- }
-
- gen_compare(dc, TCG_COND_GTU);
-}
-
-static void dec_cmpne(DisasContext *dc)
-{
- if (dc->format == OP_FMT_RI) {
- LOG_DIS("cmpnei r%d, r%d, %d\n", dc->r1, dc->r0,
- sign_extend(dc->imm16, 16));
- } else {
- LOG_DIS("cmpne r%d, r%d, r%d\n", dc->r2, dc->r0, dc->r1);
- }
-
- gen_compare(dc, TCG_COND_NE);
-}
-
-static void dec_divu(DisasContext *dc)
-{
- TCGLabel *l1;
-
- LOG_DIS("divu r%d, r%d, r%d\n", dc->r2, dc->r0, dc->r1);
-
- if (!(dc->features & LM32_FEATURE_DIVIDE)) {
- qemu_log_mask(LOG_GUEST_ERROR, "hardware divider is not available\n");
- t_gen_illegal_insn(dc);
- return;
- }
-
- l1 = gen_new_label();
- tcg_gen_brcondi_tl(TCG_COND_NE, cpu_R[dc->r1], 0, l1);
- tcg_gen_movi_tl(cpu_pc, dc->pc);
- t_gen_raise_exception(dc, EXCP_DIVIDE_BY_ZERO);
- gen_set_label(l1);
- tcg_gen_divu_tl(cpu_R[dc->r2], cpu_R[dc->r0], cpu_R[dc->r1]);
-}
-
-static void dec_lb(DisasContext *dc)
-{
- TCGv t0;
-
- LOG_DIS("lb r%d, (r%d+%d)\n", dc->r1, dc->r0, dc->imm16);
-
- t0 = tcg_temp_new();
- tcg_gen_addi_tl(t0, cpu_R[dc->r0], sign_extend(dc->imm16, 16));
- tcg_gen_qemu_ld8s(cpu_R[dc->r1], t0, MEM_INDEX);
- tcg_temp_free(t0);
-}
-
-static void dec_lbu(DisasContext *dc)
-{
- TCGv t0;
-
- LOG_DIS("lbu r%d, (r%d+%d)\n", dc->r1, dc->r0, dc->imm16);
-
- t0 = tcg_temp_new();
- tcg_gen_addi_tl(t0, cpu_R[dc->r0], sign_extend(dc->imm16, 16));
- tcg_gen_qemu_ld8u(cpu_R[dc->r1], t0, MEM_INDEX);
- tcg_temp_free(t0);
-}
-
-static void dec_lh(DisasContext *dc)
-{
- TCGv t0;
-
- LOG_DIS("lh r%d, (r%d+%d)\n", dc->r1, dc->r0, dc->imm16);
-
- t0 = tcg_temp_new();
- tcg_gen_addi_tl(t0, cpu_R[dc->r0], sign_extend(dc->imm16, 16));
- tcg_gen_qemu_ld16s(cpu_R[dc->r1], t0, MEM_INDEX);
- tcg_temp_free(t0);
-}
-
-static void dec_lhu(DisasContext *dc)
-{
- TCGv t0;
-
- LOG_DIS("lhu r%d, (r%d+%d)\n", dc->r1, dc->r0, dc->imm16);
-
- t0 = tcg_temp_new();
- tcg_gen_addi_tl(t0, cpu_R[dc->r0], sign_extend(dc->imm16, 16));
- tcg_gen_qemu_ld16u(cpu_R[dc->r1], t0, MEM_INDEX);
- tcg_temp_free(t0);
-}
-
-static void dec_lw(DisasContext *dc)
-{
- TCGv t0;
-
- LOG_DIS("lw r%d, (r%d+%d)\n", dc->r1, dc->r0, sign_extend(dc->imm16, 16));
-
- t0 = tcg_temp_new();
- tcg_gen_addi_tl(t0, cpu_R[dc->r0], sign_extend(dc->imm16, 16));
- tcg_gen_qemu_ld32s(cpu_R[dc->r1], t0, MEM_INDEX);
- tcg_temp_free(t0);
-}
-
-static void dec_modu(DisasContext *dc)
-{
- TCGLabel *l1;
-
- LOG_DIS("modu r%d, r%d, %d\n", dc->r2, dc->r0, dc->r1);
-
- if (!(dc->features & LM32_FEATURE_DIVIDE)) {
- qemu_log_mask(LOG_GUEST_ERROR, "hardware divider is not available\n");
- t_gen_illegal_insn(dc);
- return;
- }
-
- l1 = gen_new_label();
- tcg_gen_brcondi_tl(TCG_COND_NE, cpu_R[dc->r1], 0, l1);
- tcg_gen_movi_tl(cpu_pc, dc->pc);
- t_gen_raise_exception(dc, EXCP_DIVIDE_BY_ZERO);
- gen_set_label(l1);
- tcg_gen_remu_tl(cpu_R[dc->r2], cpu_R[dc->r0], cpu_R[dc->r1]);
-}
-
-static void dec_mul(DisasContext *dc)
-{
- if (dc->format == OP_FMT_RI) {
- LOG_DIS("muli r%d, r%d, %d\n", dc->r1, dc->r0,
- sign_extend(dc->imm16, 16));
- } else {
- LOG_DIS("mul r%d, r%d, r%d\n", dc->r2, dc->r0, dc->r1);
- }
-
- if (!(dc->features & LM32_FEATURE_MULTIPLY)) {
- qemu_log_mask(LOG_GUEST_ERROR,
- "hardware multiplier is not available\n");
- t_gen_illegal_insn(dc);
- return;
- }
-
- if (dc->format == OP_FMT_RI) {
- tcg_gen_muli_tl(cpu_R[dc->r1], cpu_R[dc->r0],
- sign_extend(dc->imm16, 16));
- } else {
- tcg_gen_mul_tl(cpu_R[dc->r2], cpu_R[dc->r0], cpu_R[dc->r1]);
- }
-}
-
-static void dec_nor(DisasContext *dc)
-{
- if (dc->format == OP_FMT_RI) {
- LOG_DIS("nori r%d, r%d, %d\n", dc->r1, dc->r0,
- zero_extend(dc->imm16, 16));
- } else {
- LOG_DIS("nor r%d, r%d, r%d\n", dc->r2, dc->r0, dc->r1);
- }
-
- if (dc->format == OP_FMT_RI) {
- TCGv t0 = tcg_temp_new();
- tcg_gen_movi_tl(t0, zero_extend(dc->imm16, 16));
- tcg_gen_nor_tl(cpu_R[dc->r1], cpu_R[dc->r0], t0);
- tcg_temp_free(t0);
- } else {
- tcg_gen_nor_tl(cpu_R[dc->r2], cpu_R[dc->r0], cpu_R[dc->r1]);
- }
-}
-
-static void dec_or(DisasContext *dc)
-{
- if (dc->format == OP_FMT_RI) {
- LOG_DIS("ori r%d, r%d, %d\n", dc->r1, dc->r0,
- zero_extend(dc->imm16, 16));
- } else {
- if (dc->r1 == R_R0) {
- LOG_DIS("mv r%d, r%d\n", dc->r2, dc->r0);
- } else {
- LOG_DIS("or r%d, r%d, r%d\n", dc->r2, dc->r0, dc->r1);
- }
- }
-
- if (dc->format == OP_FMT_RI) {
- tcg_gen_ori_tl(cpu_R[dc->r1], cpu_R[dc->r0],
- zero_extend(dc->imm16, 16));
- } else {
- tcg_gen_or_tl(cpu_R[dc->r2], cpu_R[dc->r0], cpu_R[dc->r1]);
- }
-}
-
-static void dec_orhi(DisasContext *dc)
-{
- if (dc->r0 == R_R0) {
- LOG_DIS("mvhi r%d, %d\n", dc->r1, dc->imm16);
- } else {
- LOG_DIS("orhi r%d, r%d, %d\n", dc->r1, dc->r0, dc->imm16);
- }
-
- tcg_gen_ori_tl(cpu_R[dc->r1], cpu_R[dc->r0], (dc->imm16 << 16));
-}
-
-static void dec_scall(DisasContext *dc)
-{
- switch (dc->imm5) {
- case 2:
- LOG_DIS("break\n");
- tcg_gen_movi_tl(cpu_pc, dc->pc);
- t_gen_raise_exception(dc, EXCP_BREAKPOINT);
- break;
- case 7:
- LOG_DIS("scall\n");
- tcg_gen_movi_tl(cpu_pc, dc->pc);
- t_gen_raise_exception(dc, EXCP_SYSTEMCALL);
- break;
- default:
- qemu_log_mask(LOG_GUEST_ERROR, "invalid opcode @0x%x", dc->pc);
- t_gen_illegal_insn(dc);
- break;
- }
-}
-
-static void dec_rcsr(DisasContext *dc)
-{
- LOG_DIS("rcsr r%d, %d\n", dc->r2, dc->csr);
-
- switch (dc->csr) {
- case CSR_IE:
- tcg_gen_mov_tl(cpu_R[dc->r2], cpu_ie);
- break;
- case CSR_IM:
- gen_helper_rcsr_im(cpu_R[dc->r2], cpu_env);
- break;
- case CSR_IP:
- gen_helper_rcsr_ip(cpu_R[dc->r2], cpu_env);
- break;
- case CSR_CC:
- tcg_gen_mov_tl(cpu_R[dc->r2], cpu_cc);
- break;
- case CSR_CFG:
- tcg_gen_mov_tl(cpu_R[dc->r2], cpu_cfg);
- break;
- case CSR_EBA:
- tcg_gen_mov_tl(cpu_R[dc->r2], cpu_eba);
- break;
- case CSR_DC:
- tcg_gen_mov_tl(cpu_R[dc->r2], cpu_dc);
- break;
- case CSR_DEBA:
- tcg_gen_mov_tl(cpu_R[dc->r2], cpu_deba);
- break;
- case CSR_JTX:
- gen_helper_rcsr_jtx(cpu_R[dc->r2], cpu_env);
- break;
- case CSR_JRX:
- gen_helper_rcsr_jrx(cpu_R[dc->r2], cpu_env);
- break;
- case CSR_ICC:
- case CSR_DCC:
- case CSR_BP0:
- case CSR_BP1:
- case CSR_BP2:
- case CSR_BP3:
- case CSR_WP0:
- case CSR_WP1:
- case CSR_WP2:
- case CSR_WP3:
- qemu_log_mask(LOG_GUEST_ERROR, "invalid read access csr=%x\n", dc->csr);
- break;
- default:
- qemu_log_mask(LOG_GUEST_ERROR, "read_csr: unknown csr=%x\n", dc->csr);
- break;
- }
-}
-
-static void dec_sb(DisasContext *dc)
-{
- TCGv t0;
-
- LOG_DIS("sb (r%d+%d), r%d\n", dc->r0, dc->imm16, dc->r1);
-
- t0 = tcg_temp_new();
- tcg_gen_addi_tl(t0, cpu_R[dc->r0], sign_extend(dc->imm16, 16));
- tcg_gen_qemu_st8(cpu_R[dc->r1], t0, MEM_INDEX);
- tcg_temp_free(t0);
-}
-
-static void dec_sextb(DisasContext *dc)
-{
- LOG_DIS("sextb r%d, r%d\n", dc->r2, dc->r0);
-
- if (!(dc->features & LM32_FEATURE_SIGN_EXTEND)) {
- qemu_log_mask(LOG_GUEST_ERROR,
- "hardware sign extender is not available\n");
- t_gen_illegal_insn(dc);
- return;
- }
-
- tcg_gen_ext8s_tl(cpu_R[dc->r2], cpu_R[dc->r0]);
-}
-
-static void dec_sexth(DisasContext *dc)
-{
- LOG_DIS("sexth r%d, r%d\n", dc->r2, dc->r0);
-
- if (!(dc->features & LM32_FEATURE_SIGN_EXTEND)) {
- qemu_log_mask(LOG_GUEST_ERROR,
- "hardware sign extender is not available\n");
- t_gen_illegal_insn(dc);
- return;
- }
-
- tcg_gen_ext16s_tl(cpu_R[dc->r2], cpu_R[dc->r0]);
-}
-
-static void dec_sh(DisasContext *dc)
-{
- TCGv t0;
-
- LOG_DIS("sh (r%d+%d), r%d\n", dc->r0, dc->imm16, dc->r1);
-
- t0 = tcg_temp_new();
- tcg_gen_addi_tl(t0, cpu_R[dc->r0], sign_extend(dc->imm16, 16));
- tcg_gen_qemu_st16(cpu_R[dc->r1], t0, MEM_INDEX);
- tcg_temp_free(t0);
-}
-
-static void dec_sl(DisasContext *dc)
-{
- if (dc->format == OP_FMT_RI) {
- LOG_DIS("sli r%d, r%d, %d\n", dc->r1, dc->r0, dc->imm5);
- } else {
- LOG_DIS("sl r%d, r%d, r%d\n", dc->r2, dc->r0, dc->r1);
- }
-
- if (!(dc->features & LM32_FEATURE_SHIFT)) {
- qemu_log_mask(LOG_GUEST_ERROR, "hardware shifter is not available\n");
- t_gen_illegal_insn(dc);
- return;
- }
-
- if (dc->format == OP_FMT_RI) {
- tcg_gen_shli_tl(cpu_R[dc->r1], cpu_R[dc->r0], dc->imm5);
- } else {
- TCGv t0 = tcg_temp_new();
- tcg_gen_andi_tl(t0, cpu_R[dc->r1], 0x1f);
- tcg_gen_shl_tl(cpu_R[dc->r2], cpu_R[dc->r0], t0);
- tcg_temp_free(t0);
- }
-}
-
-static void dec_sr(DisasContext *dc)
-{
- if (dc->format == OP_FMT_RI) {
- LOG_DIS("sri r%d, r%d, %d\n", dc->r1, dc->r0, dc->imm5);
- } else {
- LOG_DIS("sr r%d, r%d, r%d\n", dc->r2, dc->r0, dc->r1);
- }
-
- /* The real CPU (w/o hardware shifter) only supports right shift by exactly
- * one bit */
- if (dc->format == OP_FMT_RI) {
- if (!(dc->features & LM32_FEATURE_SHIFT) && (dc->imm5 != 1)) {
- qemu_log_mask(LOG_GUEST_ERROR,
- "hardware shifter is not available\n");
- t_gen_illegal_insn(dc);
- return;
- }
- tcg_gen_sari_tl(cpu_R[dc->r1], cpu_R[dc->r0], dc->imm5);
- } else {
- TCGLabel *l1 = gen_new_label();
- TCGLabel *l2 = gen_new_label();
- TCGv t0 = tcg_temp_local_new();
- tcg_gen_andi_tl(t0, cpu_R[dc->r1], 0x1f);
-
- if (!(dc->features & LM32_FEATURE_SHIFT)) {
- tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 1, l1);
- t_gen_illegal_insn(dc);
- tcg_gen_br(l2);
- }
-
- gen_set_label(l1);
- tcg_gen_sar_tl(cpu_R[dc->r2], cpu_R[dc->r0], t0);
- gen_set_label(l2);
-
- tcg_temp_free(t0);
- }
-}
-
-static void dec_sru(DisasContext *dc)
-{
- if (dc->format == OP_FMT_RI) {
- LOG_DIS("srui r%d, r%d, %d\n", dc->r1, dc->r0, dc->imm5);
- } else {
- LOG_DIS("sru r%d, r%d, r%d\n", dc->r2, dc->r0, dc->r1);
- }
-
- if (dc->format == OP_FMT_RI) {
- if (!(dc->features & LM32_FEATURE_SHIFT) && (dc->imm5 != 1)) {
- qemu_log_mask(LOG_GUEST_ERROR,
- "hardware shifter is not available\n");
- t_gen_illegal_insn(dc);
- return;
- }
- tcg_gen_shri_tl(cpu_R[dc->r1], cpu_R[dc->r0], dc->imm5);
- } else {
- TCGLabel *l1 = gen_new_label();
- TCGLabel *l2 = gen_new_label();
- TCGv t0 = tcg_temp_local_new();
- tcg_gen_andi_tl(t0, cpu_R[dc->r1], 0x1f);
-
- if (!(dc->features & LM32_FEATURE_SHIFT)) {
- tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 1, l1);
- t_gen_illegal_insn(dc);
- tcg_gen_br(l2);
- }
-
- gen_set_label(l1);
- tcg_gen_shr_tl(cpu_R[dc->r2], cpu_R[dc->r0], t0);
- gen_set_label(l2);
-
- tcg_temp_free(t0);
- }
-}
-
-static void dec_sub(DisasContext *dc)
-{
- LOG_DIS("sub r%d, r%d, r%d\n", dc->r2, dc->r0, dc->r1);
-
- tcg_gen_sub_tl(cpu_R[dc->r2], cpu_R[dc->r0], cpu_R[dc->r1]);
-}
-
-static void dec_sw(DisasContext *dc)
-{
- TCGv t0;
-
- LOG_DIS("sw (r%d+%d), r%d\n", dc->r0, sign_extend(dc->imm16, 16), dc->r1);
-
- t0 = tcg_temp_new();
- tcg_gen_addi_tl(t0, cpu_R[dc->r0], sign_extend(dc->imm16, 16));
- tcg_gen_qemu_st32(cpu_R[dc->r1], t0, MEM_INDEX);
- tcg_temp_free(t0);
-}
-
-static void dec_user(DisasContext *dc)
-{
- LOG_DIS("user");
-
- qemu_log_mask(LOG_GUEST_ERROR, "user instruction undefined\n");
- t_gen_illegal_insn(dc);
-}
-
-static void dec_wcsr(DisasContext *dc)
-{
- int no;
-
- LOG_DIS("wcsr %d, r%d\n", dc->csr, dc->r1);
-
- switch (dc->csr) {
- case CSR_IE:
- tcg_gen_mov_tl(cpu_ie, cpu_R[dc->r1]);
- tcg_gen_movi_tl(cpu_pc, dc->pc + 4);
- dc->is_jmp = DISAS_UPDATE;
- break;
- case CSR_IM:
- /* mark as an io operation because it could cause an interrupt */
- if (tb_cflags(dc->tb) & CF_USE_ICOUNT) {
- gen_io_start();
- }
- gen_helper_wcsr_im(cpu_env, cpu_R[dc->r1]);
- tcg_gen_movi_tl(cpu_pc, dc->pc + 4);
- dc->is_jmp = DISAS_UPDATE;
- break;
- case CSR_IP:
- /* mark as an io operation because it could cause an interrupt */
- if (tb_cflags(dc->tb) & CF_USE_ICOUNT) {
- gen_io_start();
- }
- gen_helper_wcsr_ip(cpu_env, cpu_R[dc->r1]);
- tcg_gen_movi_tl(cpu_pc, dc->pc + 4);
- dc->is_jmp = DISAS_UPDATE;
- break;
- case CSR_ICC:
- /* TODO */
- break;
- case CSR_DCC:
- /* TODO */
- break;
- case CSR_EBA:
- tcg_gen_mov_tl(cpu_eba, cpu_R[dc->r1]);
- break;
- case CSR_DEBA:
- tcg_gen_mov_tl(cpu_deba, cpu_R[dc->r1]);
- break;
- case CSR_JTX:
- gen_helper_wcsr_jtx(cpu_env, cpu_R[dc->r1]);
- break;
- case CSR_JRX:
- gen_helper_wcsr_jrx(cpu_env, cpu_R[dc->r1]);
- break;
- case CSR_DC:
- gen_helper_wcsr_dc(cpu_env, cpu_R[dc->r1]);
- break;
- case CSR_BP0:
- case CSR_BP1:
- case CSR_BP2:
- case CSR_BP3:
- no = dc->csr - CSR_BP0;
- if (dc->num_breakpoints <= no) {
- qemu_log_mask(LOG_GUEST_ERROR,
- "breakpoint #%i is not available\n", no);
- t_gen_illegal_insn(dc);
- break;
- }
- gen_helper_wcsr_bp(cpu_env, cpu_R[dc->r1], tcg_const_i32(no));
- break;
- case CSR_WP0:
- case CSR_WP1:
- case CSR_WP2:
- case CSR_WP3:
- no = dc->csr - CSR_WP0;
- if (dc->num_watchpoints <= no) {
- qemu_log_mask(LOG_GUEST_ERROR,
- "watchpoint #%i is not available\n", no);
- t_gen_illegal_insn(dc);
- break;
- }
- gen_helper_wcsr_wp(cpu_env, cpu_R[dc->r1], tcg_const_i32(no));
- break;
- case CSR_CC:
- case CSR_CFG:
- qemu_log_mask(LOG_GUEST_ERROR, "invalid write access csr=%x\n",
- dc->csr);
- break;
- default:
- qemu_log_mask(LOG_GUEST_ERROR, "write_csr: unknown csr=%x\n",
- dc->csr);
- break;
- }
-}
-
-static void dec_xnor(DisasContext *dc)
-{
- if (dc->format == OP_FMT_RI) {
- LOG_DIS("xnori r%d, r%d, %d\n", dc->r1, dc->r0,
- zero_extend(dc->imm16, 16));
- } else {
- if (dc->r1 == R_R0) {
- LOG_DIS("not r%d, r%d\n", dc->r2, dc->r0);
- } else {
- LOG_DIS("xnor r%d, r%d, r%d\n", dc->r2, dc->r0, dc->r1);
- }
- }
-
- if (dc->format == OP_FMT_RI) {
- tcg_gen_xori_tl(cpu_R[dc->r1], cpu_R[dc->r0],
- zero_extend(dc->imm16, 16));
- tcg_gen_not_tl(cpu_R[dc->r1], cpu_R[dc->r1]);
- } else {
- tcg_gen_eqv_tl(cpu_R[dc->r2], cpu_R[dc->r0], cpu_R[dc->r1]);
- }
-}
-
-static void dec_xor(DisasContext *dc)
-{
- if (dc->format == OP_FMT_RI) {
- LOG_DIS("xori r%d, r%d, %d\n", dc->r1, dc->r0,
- zero_extend(dc->imm16, 16));
- } else {
- LOG_DIS("xor r%d, r%d, r%d\n", dc->r2, dc->r0, dc->r1);
- }
-
- if (dc->format == OP_FMT_RI) {
- tcg_gen_xori_tl(cpu_R[dc->r1], cpu_R[dc->r0],
- zero_extend(dc->imm16, 16));
- } else {
- tcg_gen_xor_tl(cpu_R[dc->r2], cpu_R[dc->r0], cpu_R[dc->r1]);
- }
-}
-
-static void dec_ill(DisasContext *dc)
-{
- qemu_log_mask(LOG_GUEST_ERROR, "invalid opcode 0x%02x\n", dc->opcode);
- t_gen_illegal_insn(dc);
-}
-
-typedef void (*DecoderInfo)(DisasContext *dc);
-static const DecoderInfo decinfo[] = {
- dec_sru, dec_nor, dec_mul, dec_sh, dec_lb, dec_sr, dec_xor, dec_lh,
- dec_and, dec_xnor, dec_lw, dec_lhu, dec_sb, dec_add, dec_or, dec_sl,
- dec_lbu, dec_be, dec_bg, dec_bge, dec_bgeu, dec_bgu, dec_sw, dec_bne,
- dec_andhi, dec_cmpe, dec_cmpg, dec_cmpge, dec_cmpgeu, dec_cmpgu, dec_orhi,
- dec_cmpne,
- dec_sru, dec_nor, dec_mul, dec_divu, dec_rcsr, dec_sr, dec_xor, dec_ill,
- dec_and, dec_xnor, dec_ill, dec_scall, dec_sextb, dec_add, dec_or, dec_sl,
- dec_b, dec_modu, dec_sub, dec_user, dec_wcsr, dec_ill, dec_call, dec_sexth,
- dec_bi, dec_cmpe, dec_cmpg, dec_cmpge, dec_cmpgeu, dec_cmpgu, dec_calli,
- dec_cmpne
-};
-
-static inline void decode(DisasContext *dc, uint32_t ir)
-{
- dc->ir = ir;
- LOG_DIS("%8.8x\t", dc->ir);
-
- dc->opcode = EXTRACT_FIELD(ir, 26, 31);
-
- dc->imm5 = EXTRACT_FIELD(ir, 0, 4);
- dc->imm16 = EXTRACT_FIELD(ir, 0, 15);
- dc->imm26 = EXTRACT_FIELD(ir, 0, 25);
-
- dc->csr = EXTRACT_FIELD(ir, 21, 25);
- dc->r0 = EXTRACT_FIELD(ir, 21, 25);
- dc->r1 = EXTRACT_FIELD(ir, 16, 20);
- dc->r2 = EXTRACT_FIELD(ir, 11, 15);
-
- /* bit 31 seems to indicate insn type. */
- if (ir & (1 << 31)) {
- dc->format = OP_FMT_RR;
- } else {
- dc->format = OP_FMT_RI;
- }
-
- assert(ARRAY_SIZE(decinfo) == 64);
- assert(dc->opcode < 64);
-
- decinfo[dc->opcode](dc);
-}
-
-/* generate intermediate code for basic block 'tb'. */
-void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
-{
- CPULM32State *env = cs->env_ptr;
- LM32CPU *cpu = env_archcpu(env);
- struct DisasContext ctx, *dc = &ctx;
- uint32_t pc_start;
- uint32_t page_start;
- int num_insns;
-
- pc_start = tb->pc;
- dc->features = cpu->features;
- dc->num_breakpoints = cpu->num_breakpoints;
- dc->num_watchpoints = cpu->num_watchpoints;
- dc->tb = tb;
-
- dc->is_jmp = DISAS_NEXT;
- dc->pc = pc_start;
- dc->singlestep_enabled = cs->singlestep_enabled;
-
- if (pc_start & 3) {
- qemu_log_mask(LOG_GUEST_ERROR,
- "unaligned PC=%x. Ignoring lowest bits.\n", pc_start);
- pc_start &= ~3;
- }
-
- page_start = pc_start & TARGET_PAGE_MASK;
- num_insns = 0;
-
- gen_tb_start(tb);
- do {
- tcg_gen_insn_start(dc->pc);
- num_insns++;
-
- if (unlikely(cpu_breakpoint_test(cs, dc->pc, BP_ANY))) {
- tcg_gen_movi_tl(cpu_pc, dc->pc);
- t_gen_raise_exception(dc, EXCP_DEBUG);
- dc->is_jmp = DISAS_UPDATE;
- /* The address covered by the breakpoint must be included in
- [tb->pc, tb->pc + tb->size) in order to for it to be
- properly cleared -- thus we increment the PC here so that
- the logic setting tb->size below does the right thing. */
- dc->pc += 4;
- break;
- }
-
- /* Pretty disas. */
- LOG_DIS("%8.8x:\t", dc->pc);
-
- if (num_insns == max_insns && (tb_cflags(tb) & CF_LAST_IO)) {
- gen_io_start();
- }
-
- decode(dc, cpu_ldl_code(env, dc->pc));
- dc->pc += 4;
- } while (!dc->is_jmp
- && !tcg_op_buf_full()
- && !cs->singlestep_enabled
- && !singlestep
- && (dc->pc - page_start < TARGET_PAGE_SIZE)
- && num_insns < max_insns);
-
-
- if (unlikely(cs->singlestep_enabled)) {
- if (dc->is_jmp == DISAS_NEXT) {
- tcg_gen_movi_tl(cpu_pc, dc->pc);
- }
- t_gen_raise_exception(dc, EXCP_DEBUG);
- } else {
- switch (dc->is_jmp) {
- case DISAS_NEXT:
- gen_goto_tb(dc, 1, dc->pc);
- break;
- default:
- case DISAS_JUMP:
- case DISAS_UPDATE:
- /* indicate that the hash table must be used
- to find the next TB */
- tcg_gen_exit_tb(NULL, 0);
- break;
- case DISAS_TB_JUMP:
- /* nothing more to generate */
- break;
- }
- }
-
- gen_tb_end(tb, num_insns);
-
- tb->size = dc->pc - pc_start;
- tb->icount = num_insns;
-
-#ifdef DEBUG_DISAS
- if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)
- && qemu_log_in_addr_range(pc_start)) {
- FILE *logfile = qemu_log_lock();
- qemu_log("\n");
- log_target_disas(cs, pc_start, dc->pc - pc_start);
- qemu_log_unlock(logfile);
- }
-#endif
-}
-
-void lm32_cpu_dump_state(CPUState *cs, FILE *f, int flags)
-{
- LM32CPU *cpu = LM32_CPU(cs);
- CPULM32State *env = &cpu->env;
- int i;
-
- if (!env) {
- return;
- }
-
- qemu_fprintf(f, "IN: PC=%x %s\n",
- env->pc, lookup_symbol(env->pc));
-
- qemu_fprintf(f, "ie=%8.8x (IE=%x EIE=%x BIE=%x) im=%8.8x ip=%8.8x\n",
- env->ie,
- (env->ie & IE_IE) ? 1 : 0,
- (env->ie & IE_EIE) ? 1 : 0,
- (env->ie & IE_BIE) ? 1 : 0,
- lm32_pic_get_im(env->pic_state),
- lm32_pic_get_ip(env->pic_state));
- qemu_fprintf(f, "eba=%8.8x deba=%8.8x\n",
- env->eba,
- env->deba);
-
- for (i = 0; i < 32; i++) {
- qemu_fprintf(f, "r%2.2d=%8.8x ", i, env->regs[i]);
- if ((i + 1) % 4 == 0) {
- qemu_fprintf(f, "\n");
- }
- }
- qemu_fprintf(f, "\n\n");
-}
-
-void restore_state_to_opc(CPULM32State *env, TranslationBlock *tb,
- target_ulong *data)
-{
- env->pc = data[0];
-}
-
-void lm32_translate_init(void)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(cpu_R); i++) {
- cpu_R[i] = tcg_global_mem_new(cpu_env,
- offsetof(CPULM32State, regs[i]),
- regnames[i]);
- }
-
- for (i = 0; i < ARRAY_SIZE(cpu_bp); i++) {
- cpu_bp[i] = tcg_global_mem_new(cpu_env,
- offsetof(CPULM32State, bp[i]),
- regnames[32+i]);
- }
-
- for (i = 0; i < ARRAY_SIZE(cpu_wp); i++) {
- cpu_wp[i] = tcg_global_mem_new(cpu_env,
- offsetof(CPULM32State, wp[i]),
- regnames[36+i]);
- }
-
- cpu_pc = tcg_global_mem_new(cpu_env,
- offsetof(CPULM32State, pc),
- "pc");
- cpu_ie = tcg_global_mem_new(cpu_env,
- offsetof(CPULM32State, ie),
- "ie");
- cpu_icc = tcg_global_mem_new(cpu_env,
- offsetof(CPULM32State, icc),
- "icc");
- cpu_dcc = tcg_global_mem_new(cpu_env,
- offsetof(CPULM32State, dcc),
- "dcc");
- cpu_cc = tcg_global_mem_new(cpu_env,
- offsetof(CPULM32State, cc),
- "cc");
- cpu_cfg = tcg_global_mem_new(cpu_env,
- offsetof(CPULM32State, cfg),
- "cfg");
- cpu_eba = tcg_global_mem_new(cpu_env,
- offsetof(CPULM32State, eba),
- "eba");
- cpu_dc = tcg_global_mem_new(cpu_env,
- offsetof(CPULM32State, dc),
- "dc");
- cpu_deba = tcg_global_mem_new(cpu_env,
- offsetof(CPULM32State, deba),
- "deba");
-}
-
diff --git a/target/meson.build b/target/meson.build
index 0e2c4b69cb..2f6940255e 100644
--- a/target/meson.build
+++ b/target/meson.build
@@ -5,11 +5,9 @@ subdir('cris')
subdir('hexagon')
subdir('hppa')
subdir('i386')
-subdir('lm32')
subdir('m68k')
subdir('microblaze')
subdir('mips')
-subdir('moxie')
subdir('nios2')
subdir('openrisc')
subdir('ppc')
@@ -19,5 +17,4 @@ subdir('s390x')
subdir('sh4')
subdir('sparc')
subdir('tricore')
-subdir('unicore32')
subdir('xtensa')
diff --git a/target/moxie/cpu-param.h b/target/moxie/cpu-param.h
deleted file mode 100644
index 9a40ef525c..0000000000
--- a/target/moxie/cpu-param.h
+++ /dev/null
@@ -1,17 +0,0 @@
-/*
- * Moxie cpu parameters for qemu.
- *
- * Copyright (c) 2008, 2010, 2013 Anthony Green
- * SPDX-License-Identifier: LGPL-2.1+
- */
-
-#ifndef MOXIE_CPU_PARAM_H
-#define MOXIE_CPU_PARAM_H 1
-
-#define TARGET_LONG_BITS 32
-#define TARGET_PAGE_BITS 12 /* 4k */
-#define TARGET_PHYS_ADDR_SPACE_BITS 32
-#define TARGET_VIRT_ADDR_SPACE_BITS 32
-#define NB_MMU_MODES 1
-
-#endif
diff --git a/target/moxie/cpu.c b/target/moxie/cpu.c
deleted file mode 100644
index 83bec34d36..0000000000
--- a/target/moxie/cpu.c
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
- * QEMU Moxie CPU
- *
- * Copyright (c) 2013 Anthony Green
- *
- * 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.1 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 program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "qemu/osdep.h"
-#include "qapi/error.h"
-#include "cpu.h"
-#include "migration/vmstate.h"
-#include "machine.h"
-
-static void moxie_cpu_set_pc(CPUState *cs, vaddr value)
-{
- MoxieCPU *cpu = MOXIE_CPU(cs);
-
- cpu->env.pc = value;
-}
-
-static bool moxie_cpu_has_work(CPUState *cs)
-{
- return cs->interrupt_request & CPU_INTERRUPT_HARD;
-}
-
-static void moxie_cpu_reset(DeviceState *dev)
-{
- CPUState *s = CPU(dev);
- MoxieCPU *cpu = MOXIE_CPU(s);
- MoxieCPUClass *mcc = MOXIE_CPU_GET_CLASS(cpu);
- CPUMoxieState *env = &cpu->env;
-
- mcc->parent_reset(dev);
-
- memset(env, 0, offsetof(CPUMoxieState, end_reset_fields));
- env->pc = 0x1000;
-}
-
-static void moxie_cpu_disas_set_info(CPUState *cpu, disassemble_info *info)
-{
- info->mach = bfd_arch_moxie;
- info->print_insn = print_insn_moxie;
-}
-
-static void moxie_cpu_realizefn(DeviceState *dev, Error **errp)
-{
- CPUState *cs = CPU(dev);
- MoxieCPUClass *mcc = MOXIE_CPU_GET_CLASS(dev);
- Error *local_err = NULL;
-
- cpu_exec_realizefn(cs, &local_err);
- if (local_err != NULL) {
- error_propagate(errp, local_err);
- return;
- }
-
- qemu_init_vcpu(cs);
- cpu_reset(cs);
-
- mcc->parent_realize(dev, errp);
-}
-
-static void moxie_cpu_initfn(Object *obj)
-{
- MoxieCPU *cpu = MOXIE_CPU(obj);
-
- cpu_set_cpustate_pointers(cpu);
-}
-
-static ObjectClass *moxie_cpu_class_by_name(const char *cpu_model)
-{
- ObjectClass *oc;
- char *typename;
-
- typename = g_strdup_printf(MOXIE_CPU_TYPE_NAME("%s"), cpu_model);
- oc = object_class_by_name(typename);
- g_free(typename);
- if (oc != NULL && (!object_class_dynamic_cast(oc, TYPE_MOXIE_CPU) ||
- object_class_is_abstract(oc))) {
- return NULL;
- }
- return oc;
-}
-
-#include "hw/core/tcg-cpu-ops.h"
-
-static struct TCGCPUOps moxie_tcg_ops = {
- .initialize = moxie_translate_init,
- .tlb_fill = moxie_cpu_tlb_fill,
-
-#ifndef CONFIG_USER_ONLY
- .do_interrupt = moxie_cpu_do_interrupt,
-#endif /* !CONFIG_USER_ONLY */
-};
-
-static void moxie_cpu_class_init(ObjectClass *oc, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(oc);
- CPUClass *cc = CPU_CLASS(oc);
- MoxieCPUClass *mcc = MOXIE_CPU_CLASS(oc);
-
- device_class_set_parent_realize(dc, moxie_cpu_realizefn,
- &mcc->parent_realize);
- device_class_set_parent_reset(dc, moxie_cpu_reset, &mcc->parent_reset);
-
- cc->class_by_name = moxie_cpu_class_by_name;
-
- cc->has_work = moxie_cpu_has_work;
- cc->dump_state = moxie_cpu_dump_state;
- cc->set_pc = moxie_cpu_set_pc;
-#ifndef CONFIG_USER_ONLY
- cc->get_phys_page_debug = moxie_cpu_get_phys_page_debug;
- cc->vmsd = &vmstate_moxie_cpu;
-#endif
- cc->disas_set_info = moxie_cpu_disas_set_info;
- cc->tcg_ops = &moxie_tcg_ops;
-}
-
-static void moxielite_initfn(Object *obj)
-{
- /* Set cpu feature flags */
-}
-
-static void moxie_any_initfn(Object *obj)
-{
- /* Set cpu feature flags */
-}
-
-#define DEFINE_MOXIE_CPU_TYPE(cpu_model, initfn) \
- { \
- .parent = TYPE_MOXIE_CPU, \
- .instance_init = initfn, \
- .name = MOXIE_CPU_TYPE_NAME(cpu_model), \
- }
-
-static const TypeInfo moxie_cpus_type_infos[] = {
- { /* base class should be registered first */
- .name = TYPE_MOXIE_CPU,
- .parent = TYPE_CPU,
- .instance_size = sizeof(MoxieCPU),
- .instance_init = moxie_cpu_initfn,
- .class_size = sizeof(MoxieCPUClass),
- .class_init = moxie_cpu_class_init,
- },
- DEFINE_MOXIE_CPU_TYPE("MoxieLite", moxielite_initfn),
- DEFINE_MOXIE_CPU_TYPE("any", moxie_any_initfn),
-};
-
-DEFINE_TYPES(moxie_cpus_type_infos)
diff --git a/target/moxie/cpu.h b/target/moxie/cpu.h
deleted file mode 100644
index bd6ab66084..0000000000
--- a/target/moxie/cpu.h
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * Moxie emulation
- *
- * Copyright (c) 2008, 2010, 2013 Anthony Green
- *
- * 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.1 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 program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef MOXIE_CPU_H
-#define MOXIE_CPU_H
-
-#include "exec/cpu-defs.h"
-#include "qom/object.h"
-
-#define MOXIE_EX_DIV0 0
-#define MOXIE_EX_BAD 1
-#define MOXIE_EX_IRQ 2
-#define MOXIE_EX_SWI 3
-#define MOXIE_EX_MMU_MISS 4
-#define MOXIE_EX_BREAK 16
-
-typedef struct CPUMoxieState {
-
- uint32_t flags; /* general execution flags */
- uint32_t gregs[16]; /* general registers */
- uint32_t sregs[256]; /* special registers */
- uint32_t pc; /* program counter */
- /* Instead of saving the cc value, we save the cmp arguments
- and compute cc on demand. */
- uint32_t cc_a; /* reg a for condition code calculation */
- uint32_t cc_b; /* reg b for condition code calculation */
-
- void *irq[8];
-
- /* Fields up to this point are cleared by a CPU reset */
- struct {} end_reset_fields;
-} CPUMoxieState;
-
-#include "hw/core/cpu.h"
-
-#define TYPE_MOXIE_CPU "moxie-cpu"
-
-OBJECT_DECLARE_TYPE(MoxieCPU, MoxieCPUClass,
- MOXIE_CPU)
-
-/**
- * MoxieCPUClass:
- * @parent_reset: The parent class' reset handler.
- *
- * A Moxie CPU model.
- */
-struct MoxieCPUClass {
- /*< private >*/
- CPUClass parent_class;
- /*< public >*/
-
- DeviceRealize parent_realize;
- DeviceReset parent_reset;
-};
-
-/**
- * MoxieCPU:
- * @env: #CPUMoxieState
- *
- * A Moxie CPU.
- */
-struct MoxieCPU {
- /*< private >*/
- CPUState parent_obj;
- /*< public >*/
-
- CPUNegativeOffsetState neg;
- CPUMoxieState env;
-};
-
-
-void moxie_cpu_do_interrupt(CPUState *cs);
-void moxie_cpu_dump_state(CPUState *cpu, FILE *f, int flags);
-hwaddr moxie_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
-void moxie_translate_init(void);
-int cpu_moxie_signal_handler(int host_signum, void *pinfo,
- void *puc);
-
-#define MOXIE_CPU_TYPE_SUFFIX "-" TYPE_MOXIE_CPU
-#define MOXIE_CPU_TYPE_NAME(model) model MOXIE_CPU_TYPE_SUFFIX
-#define CPU_RESOLVING_TYPE TYPE_MOXIE_CPU
-
-#define cpu_signal_handler cpu_moxie_signal_handler
-
-static inline int cpu_mmu_index(CPUMoxieState *env, bool ifetch)
-{
- return 0;
-}
-
-typedef CPUMoxieState CPUArchState;
-typedef MoxieCPU ArchCPU;
-
-#include "exec/cpu-all.h"
-
-static inline void cpu_get_tb_cpu_state(CPUMoxieState *env, target_ulong *pc,
- target_ulong *cs_base, uint32_t *flags)
-{
- *pc = env->pc;
- *cs_base = 0;
- *flags = 0;
-}
-
-bool moxie_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
- MMUAccessType access_type, int mmu_idx,
- bool probe, uintptr_t retaddr);
-
-#endif /* MOXIE_CPU_H */
diff --git a/target/moxie/helper.c b/target/moxie/helper.c
deleted file mode 100644
index b1919f62b3..0000000000
--- a/target/moxie/helper.c
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * Moxie helper routines.
- *
- * Copyright (c) 2008, 2009, 2010, 2013 Anthony Green
- *
- * 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.1 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 program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "qemu/osdep.h"
-
-#include "cpu.h"
-#include "mmu.h"
-#include "exec/exec-all.h"
-#include "exec/cpu_ldst.h"
-#include "qemu/host-utils.h"
-#include "exec/helper-proto.h"
-
-void helper_raise_exception(CPUMoxieState *env, int ex)
-{
- CPUState *cs = env_cpu(env);
-
- cs->exception_index = ex;
- /* Stash the exception type. */
- env->sregs[2] = ex;
- /* Stash the address where the exception occurred. */
- cpu_restore_state(cs, GETPC(), true);
- env->sregs[5] = env->pc;
- /* Jump to the exception handline routine. */
- env->pc = env->sregs[1];
- cpu_loop_exit(cs);
-}
-
-uint32_t helper_div(CPUMoxieState *env, uint32_t a, uint32_t b)
-{
- if (unlikely(b == 0)) {
- helper_raise_exception(env, MOXIE_EX_DIV0);
- return 0;
- }
- if (unlikely(a == INT_MIN && b == -1)) {
- return INT_MIN;
- }
-
- return (int32_t)a / (int32_t)b;
-}
-
-uint32_t helper_udiv(CPUMoxieState *env, uint32_t a, uint32_t b)
-{
- if (unlikely(b == 0)) {
- helper_raise_exception(env, MOXIE_EX_DIV0);
- return 0;
- }
- return a / b;
-}
-
-void helper_debug(CPUMoxieState *env)
-{
- CPUState *cs = env_cpu(env);
-
- cs->exception_index = EXCP_DEBUG;
- cpu_loop_exit(cs);
-}
-
-bool moxie_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
- MMUAccessType access_type, int mmu_idx,
- bool probe, uintptr_t retaddr)
-{
- MoxieCPU *cpu = MOXIE_CPU(cs);
- CPUMoxieState *env = &cpu->env;
- MoxieMMUResult res;
- int prot, miss;
-
- address &= TARGET_PAGE_MASK;
- prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
- miss = moxie_mmu_translate(&res, env, address, access_type, mmu_idx);
- if (likely(!miss)) {
- tlb_set_page(cs, address, res.phy, prot, mmu_idx, TARGET_PAGE_SIZE);
- return true;
- }
- if (probe) {
- return false;
- }
-
- cs->exception_index = MOXIE_EX_MMU_MISS;
- cpu_loop_exit_restore(cs, retaddr);
-}
-
-void moxie_cpu_do_interrupt(CPUState *cs)
-{
- switch (cs->exception_index) {
- case MOXIE_EX_BREAK:
- break;
- default:
- break;
- }
-}
-
-hwaddr moxie_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
-{
- MoxieCPU *cpu = MOXIE_CPU(cs);
- uint32_t phy = addr;
- MoxieMMUResult res;
- int miss;
-
- miss = moxie_mmu_translate(&res, &cpu->env, addr, 0, 0);
- if (!miss) {
- phy = res.phy;
- }
- return phy;
-}
diff --git a/target/moxie/helper.h b/target/moxie/helper.h
deleted file mode 100644
index d94ef7a17e..0000000000
--- a/target/moxie/helper.h
+++ /dev/null
@@ -1,5 +0,0 @@
-DEF_HELPER_2(raise_exception, void, env, int)
-DEF_HELPER_1(debug, void, env)
-
-DEF_HELPER_FLAGS_3(div, TCG_CALL_NO_WG, i32, env, i32, i32)
-DEF_HELPER_FLAGS_3(udiv, TCG_CALL_NO_WG, i32, env, i32, i32)
diff --git a/target/moxie/machine.c b/target/moxie/machine.c
deleted file mode 100644
index d0f177048c..0000000000
--- a/target/moxie/machine.c
+++ /dev/null
@@ -1,19 +0,0 @@
-#include "qemu/osdep.h"
-#include "cpu.h"
-#include "machine.h"
-#include "migration/cpu.h"
-
-const VMStateDescription vmstate_moxie_cpu = {
- .name = "cpu",
- .version_id = 1,
- .minimum_version_id = 1,
- .fields = (VMStateField[]) {
- VMSTATE_UINT32(flags, CPUMoxieState),
- VMSTATE_UINT32_ARRAY(gregs, CPUMoxieState, 16),
- VMSTATE_UINT32_ARRAY(sregs, CPUMoxieState, 256),
- VMSTATE_UINT32(pc, CPUMoxieState),
- VMSTATE_UINT32(cc_a, CPUMoxieState),
- VMSTATE_UINT32(cc_b, CPUMoxieState),
- VMSTATE_END_OF_LIST()
- }
-};
diff --git a/target/moxie/machine.h b/target/moxie/machine.h
deleted file mode 100644
index a1b72907ae..0000000000
--- a/target/moxie/machine.h
+++ /dev/null
@@ -1 +0,0 @@
-extern const VMStateDescription vmstate_moxie_cpu;
diff --git a/target/moxie/meson.build b/target/moxie/meson.build
deleted file mode 100644
index b4beb528cc..0000000000
--- a/target/moxie/meson.build
+++ /dev/null
@@ -1,14 +0,0 @@
-moxie_ss = ss.source_set()
-moxie_ss.add(files(
- 'cpu.c',
- 'helper.c',
- 'machine.c',
- 'machine.c',
- 'translate.c',
-))
-
-moxie_softmmu_ss = ss.source_set()
-moxie_softmmu_ss.add(files('mmu.c'))
-
-target_arch += {'moxie': moxie_ss}
-target_softmmu_arch += {'moxie': moxie_softmmu_ss}
diff --git a/target/moxie/mmu.c b/target/moxie/mmu.c
deleted file mode 100644
index 87783a36f8..0000000000
--- a/target/moxie/mmu.c
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Moxie mmu emulation.
- *
- * Copyright (c) 2008, 2013 Anthony Green
- *
- * 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.1 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 program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "qemu/osdep.h"
-
-#include "cpu.h"
-#include "mmu.h"
-
-int moxie_mmu_translate(MoxieMMUResult *res,
- CPUMoxieState *env, uint32_t vaddr,
- int rw, int mmu_idx)
-{
- /* Perform no translation yet. */
- res->phy = vaddr;
- return 0;
-}
diff --git a/target/moxie/mmu.h b/target/moxie/mmu.h
deleted file mode 100644
index d80690f4d2..0000000000
--- a/target/moxie/mmu.h
+++ /dev/null
@@ -1,19 +0,0 @@
-#ifndef TARGET_MOXIE_MMU_H
-#define TARGET_MOXIE_MMU_H
-
-#define MOXIE_MMU_ERR_EXEC 0
-#define MOXIE_MMU_ERR_READ 1
-#define MOXIE_MMU_ERR_WRITE 2
-#define MOXIE_MMU_ERR_FLUSH 3
-
-typedef struct {
- uint32_t phy;
- uint32_t pfn;
- int cause_op;
-} MoxieMMUResult;
-
-int moxie_mmu_translate(MoxieMMUResult *res,
- CPUMoxieState *env, uint32_t vaddr,
- int rw, int mmu_idx);
-
-#endif
diff --git a/target/moxie/translate.c b/target/moxie/translate.c
deleted file mode 100644
index 24a742b25e..0000000000
--- a/target/moxie/translate.c
+++ /dev/null
@@ -1,892 +0,0 @@
-/*
- * Moxie emulation for qemu: main translation routines.
- *
- * Copyright (c) 2009, 2013 Anthony Green
- *
- * 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.1 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 program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-/* For information on the Moxie architecture, see
- * http://moxielogic.org/wiki
- */
-
-#include "qemu/osdep.h"
-
-#include "cpu.h"
-#include "exec/exec-all.h"
-#include "disas/disas.h"
-#include "tcg/tcg-op.h"
-#include "exec/cpu_ldst.h"
-#include "qemu/qemu-print.h"
-
-#include "exec/helper-proto.h"
-#include "exec/helper-gen.h"
-#include "exec/log.h"
-
-/* This is the state at translation time. */
-typedef struct DisasContext {
- TranslationBlock *tb;
- target_ulong pc, saved_pc;
- uint32_t opcode;
- uint32_t fp_status;
- /* Routine used to access memory */
- int memidx;
- int bstate;
- target_ulong btarget;
- int singlestep_enabled;
-} DisasContext;
-
-enum {
- BS_NONE = 0, /* We go out of the TB without reaching a branch or an
- * exception condition */
- BS_STOP = 1, /* We want to stop translation for any reason */
- BS_BRANCH = 2, /* We reached a branch condition */
- BS_EXCP = 3, /* We reached an exception condition */
-};
-
-static TCGv cpu_pc;
-static TCGv cpu_gregs[16];
-static TCGv cc_a, cc_b;
-
-#include "exec/gen-icount.h"
-
-#define REG(x) (cpu_gregs[x])
-
-/* Extract the signed 10-bit offset from a 16-bit branch
- instruction. */
-static int extract_branch_offset(int opcode)
-{
- return (((signed short)((opcode & ((1 << 10) - 1)) << 6)) >> 6) << 1;
-}
-
-void moxie_cpu_dump_state(CPUState *cs, FILE *f, int flags)
-{
- MoxieCPU *cpu = MOXIE_CPU(cs);
- CPUMoxieState *env = &cpu->env;
- int i;
- qemu_fprintf(f, "pc=0x%08x\n", env->pc);
- qemu_fprintf(f, "$fp=0x%08x $sp=0x%08x $r0=0x%08x $r1=0x%08x\n",
- env->gregs[0], env->gregs[1], env->gregs[2], env->gregs[3]);
- for (i = 4; i < 16; i += 4) {
- qemu_fprintf(f, "$r%d=0x%08x $r%d=0x%08x $r%d=0x%08x $r%d=0x%08x\n",
- i - 2, env->gregs[i], i - 1, env->gregs[i + 1],
- i, env->gregs[i + 2], i + 1, env->gregs[i + 3]);
- }
- for (i = 4; i < 16; i += 4) {
- qemu_fprintf(f, "sr%d=0x%08x sr%d=0x%08x sr%d=0x%08x sr%d=0x%08x\n",
- i - 2, env->sregs[i], i - 1, env->sregs[i + 1],
- i, env->sregs[i + 2], i + 1, env->sregs[i + 3]);
- }
-}
-
-void moxie_translate_init(void)
-{
- int i;
- static const char * const gregnames[16] = {
- "$fp", "$sp", "$r0", "$r1",
- "$r2", "$r3", "$r4", "$r5",
- "$r6", "$r7", "$r8", "$r9",
- "$r10", "$r11", "$r12", "$r13"
- };
-
- cpu_pc = tcg_global_mem_new_i32(cpu_env,
- offsetof(CPUMoxieState, pc), "$pc");
- for (i = 0; i < 16; i++)
- cpu_gregs[i] = tcg_global_mem_new_i32(cpu_env,
- offsetof(CPUMoxieState, gregs[i]),
- gregnames[i]);
-
- cc_a = tcg_global_mem_new_i32(cpu_env,
- offsetof(CPUMoxieState, cc_a), "cc_a");
- cc_b = tcg_global_mem_new_i32(cpu_env,
- offsetof(CPUMoxieState, cc_b), "cc_b");
-}
-
-static inline bool use_goto_tb(DisasContext *ctx, target_ulong dest)
-{
- if (unlikely(ctx->singlestep_enabled)) {
- return false;
- }
-
-#ifndef CONFIG_USER_ONLY
- return (ctx->tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK);
-#else
- return true;
-#endif
-}
-
-static inline void gen_goto_tb(CPUMoxieState *env, DisasContext *ctx,
- int n, target_ulong dest)
-{
- if (use_goto_tb(ctx, dest)) {
- tcg_gen_goto_tb(n);
- tcg_gen_movi_i32(cpu_pc, dest);
- tcg_gen_exit_tb(ctx->tb, n);
- } else {
- tcg_gen_movi_i32(cpu_pc, dest);
- if (ctx->singlestep_enabled) {
- gen_helper_debug(cpu_env);
- }
- tcg_gen_exit_tb(NULL, 0);
- }
-}
-
-static int decode_opc(MoxieCPU *cpu, DisasContext *ctx)
-{
- CPUMoxieState *env = &cpu->env;
-
- /* Local cache for the instruction opcode. */
- int opcode;
- /* Set the default instruction length. */
- int length = 2;
-
- /* Examine the 16-bit opcode. */
- opcode = ctx->opcode;
-
- /* Decode instruction. */
- if (opcode & (1 << 15)) {
- if (opcode & (1 << 14)) {
- /* This is a Form 3 instruction. */
- int inst = (opcode >> 10 & 0xf);
-
-#define BRANCH(cond) \
- do { \
- TCGLabel *l1 = gen_new_label(); \
- tcg_gen_brcond_i32(cond, cc_a, cc_b, l1); \
- gen_goto_tb(env, ctx, 1, ctx->pc+2); \
- gen_set_label(l1); \
- gen_goto_tb(env, ctx, 0, extract_branch_offset(opcode) + ctx->pc+2); \
- ctx->bstate = BS_BRANCH; \
- } while (0)
-
- switch (inst) {
- case 0x00: /* beq */
- BRANCH(TCG_COND_EQ);
- break;
- case 0x01: /* bne */
- BRANCH(TCG_COND_NE);
- break;
- case 0x02: /* blt */
- BRANCH(TCG_COND_LT);
- break;
- case 0x03: /* bgt */
- BRANCH(TCG_COND_GT);
- break;
- case 0x04: /* bltu */
- BRANCH(TCG_COND_LTU);
- break;
- case 0x05: /* bgtu */
- BRANCH(TCG_COND_GTU);
- break;
- case 0x06: /* bge */
- BRANCH(TCG_COND_GE);
- break;
- case 0x07: /* ble */
- BRANCH(TCG_COND_LE);
- break;
- case 0x08: /* bgeu */
- BRANCH(TCG_COND_GEU);
- break;
- case 0x09: /* bleu */
- BRANCH(TCG_COND_LEU);
- break;
- default:
- {
- TCGv temp = tcg_temp_new_i32();
- tcg_gen_movi_i32(cpu_pc, ctx->pc);
- tcg_gen_movi_i32(temp, MOXIE_EX_BAD);
- gen_helper_raise_exception(cpu_env, temp);
- tcg_temp_free_i32(temp);
- }
- break;
- }
- } else {
- /* This is a Form 2 instruction. */
- int inst = (opcode >> 12 & 0x3);
- switch (inst) {
- case 0x00: /* inc */
- {
- int a = (opcode >> 8) & 0xf;
- unsigned int v = (opcode & 0xff);
- tcg_gen_addi_i32(REG(a), REG(a), v);
- }
- break;
- case 0x01: /* dec */
- {
- int a = (opcode >> 8) & 0xf;
- unsigned int v = (opcode & 0xff);
- tcg_gen_subi_i32(REG(a), REG(a), v);
- }
- break;
- case 0x02: /* gsr */
- {
- int a = (opcode >> 8) & 0xf;
- unsigned v = (opcode & 0xff);
- tcg_gen_ld_i32(REG(a), cpu_env,
- offsetof(CPUMoxieState, sregs[v]));
- }
- break;
- case 0x03: /* ssr */
- {
- int a = (opcode >> 8) & 0xf;
- unsigned v = (opcode & 0xff);
- tcg_gen_st_i32(REG(a), cpu_env,
- offsetof(CPUMoxieState, sregs[v]));
- }
- break;
- default:
- {
- TCGv temp = tcg_temp_new_i32();
- tcg_gen_movi_i32(cpu_pc, ctx->pc);
- tcg_gen_movi_i32(temp, MOXIE_EX_BAD);
- gen_helper_raise_exception(cpu_env, temp);
- tcg_temp_free_i32(temp);
- }
- break;
- }
- }
- } else {
- /* This is a Form 1 instruction. */
- int inst = opcode >> 8;
- switch (inst) {
- case 0x00: /* nop */
- break;
- case 0x01: /* ldi.l (immediate) */
- {
- int reg = (opcode >> 4) & 0xf;
- int val = cpu_ldl_code(env, ctx->pc+2);
- tcg_gen_movi_i32(REG(reg), val);
- length = 6;
- }
- break;
- case 0x02: /* mov (register-to-register) */
- {
- int dest = (opcode >> 4) & 0xf;
- int src = opcode & 0xf;
- tcg_gen_mov_i32(REG(dest), REG(src));
- }
- break;
- case 0x03: /* jsra */
- {
- TCGv t1 = tcg_temp_new_i32();
- TCGv t2 = tcg_temp_new_i32();
-
- tcg_gen_movi_i32(t1, ctx->pc + 6);
-
- /* Make space for the static chain and return address. */
- tcg_gen_subi_i32(t2, REG(1), 8);
- tcg_gen_mov_i32(REG(1), t2);
- tcg_gen_qemu_st32(t1, REG(1), ctx->memidx);
-
- /* Push the current frame pointer. */
- tcg_gen_subi_i32(t2, REG(1), 4);
- tcg_gen_mov_i32(REG(1), t2);
- tcg_gen_qemu_st32(REG(0), REG(1), ctx->memidx);
-
- /* Set the pc and $fp. */
- tcg_gen_mov_i32(REG(0), REG(1));
-
- gen_goto_tb(env, ctx, 0, cpu_ldl_code(env, ctx->pc+2));
-
- tcg_temp_free_i32(t1);
- tcg_temp_free_i32(t2);
-
- ctx->bstate = BS_BRANCH;
- length = 6;
- }
- break;
- case 0x04: /* ret */
- {
- TCGv t1 = tcg_temp_new_i32();
-
- /* The new $sp is the old $fp. */
- tcg_gen_mov_i32(REG(1), REG(0));
-
- /* Pop the frame pointer. */
- tcg_gen_qemu_ld32u(REG(0), REG(1), ctx->memidx);
- tcg_gen_addi_i32(t1, REG(1), 4);
- tcg_gen_mov_i32(REG(1), t1);
-
-
- /* Pop the return address and skip over the static chain
- slot. */
- tcg_gen_qemu_ld32u(cpu_pc, REG(1), ctx->memidx);
- tcg_gen_addi_i32(t1, REG(1), 8);
- tcg_gen_mov_i32(REG(1), t1);
-
- tcg_temp_free_i32(t1);
-
- /* Jump... */
- tcg_gen_exit_tb(NULL, 0);
-
- ctx->bstate = BS_BRANCH;
- }
- break;
- case 0x05: /* add.l */
- {
- int a = (opcode >> 4) & 0xf;
- int b = opcode & 0xf;
-
- tcg_gen_add_i32(REG(a), REG(a), REG(b));
- }
- break;
- case 0x06: /* push */
- {
- int a = (opcode >> 4) & 0xf;
- int b = opcode & 0xf;
-
- TCGv t1 = tcg_temp_new_i32();
- tcg_gen_subi_i32(t1, REG(a), 4);
- tcg_gen_mov_i32(REG(a), t1);
- tcg_gen_qemu_st32(REG(b), REG(a), ctx->memidx);
- tcg_temp_free_i32(t1);
- }
- break;
- case 0x07: /* pop */
- {
- int a = (opcode >> 4) & 0xf;
- int b = opcode & 0xf;
- TCGv t1 = tcg_temp_new_i32();
-
- tcg_gen_qemu_ld32u(REG(b), REG(a), ctx->memidx);
- tcg_gen_addi_i32(t1, REG(a), 4);
- tcg_gen_mov_i32(REG(a), t1);
- tcg_temp_free_i32(t1);
- }
- break;
- case 0x08: /* lda.l */
- {
- int reg = (opcode >> 4) & 0xf;
-
- TCGv ptr = tcg_temp_new_i32();
- tcg_gen_movi_i32(ptr, cpu_ldl_code(env, ctx->pc+2));
- tcg_gen_qemu_ld32u(REG(reg), ptr, ctx->memidx);
- tcg_temp_free_i32(ptr);
-
- length = 6;
- }
- break;
- case 0x09: /* sta.l */
- {
- int val = (opcode >> 4) & 0xf;
-
- TCGv ptr = tcg_temp_new_i32();
- tcg_gen_movi_i32(ptr, cpu_ldl_code(env, ctx->pc+2));
- tcg_gen_qemu_st32(REG(val), ptr, ctx->memidx);
- tcg_temp_free_i32(ptr);
-
- length = 6;
- }
- break;
- case 0x0a: /* ld.l (register indirect) */
- {
- int src = opcode & 0xf;
- int dest = (opcode >> 4) & 0xf;
-
- tcg_gen_qemu_ld32u(REG(dest), REG(src), ctx->memidx);
- }
- break;
- case 0x0b: /* st.l */
- {
- int dest = (opcode >> 4) & 0xf;
- int val = opcode & 0xf;
-
- tcg_gen_qemu_st32(REG(val), REG(dest), ctx->memidx);
- }
- break;
- case 0x0c: /* ldo.l */
- {
- int a = (opcode >> 4) & 0xf;
- int b = opcode & 0xf;
-
- TCGv t1 = tcg_temp_new_i32();
- TCGv t2 = tcg_temp_new_i32();
- tcg_gen_addi_i32(t1, REG(b), cpu_ldl_code(env, ctx->pc+2));
- tcg_gen_qemu_ld32u(t2, t1, ctx->memidx);
- tcg_gen_mov_i32(REG(a), t2);
-
- tcg_temp_free_i32(t1);
- tcg_temp_free_i32(t2);
-
- length = 6;
- }
- break;
- case 0x0d: /* sto.l */
- {
- int a = (opcode >> 4) & 0xf;
- int b = opcode & 0xf;
-
- TCGv t1 = tcg_temp_new_i32();
- TCGv t2 = tcg_temp_new_i32();
- tcg_gen_addi_i32(t1, REG(a), cpu_ldl_code(env, ctx->pc+2));
- tcg_gen_qemu_st32(REG(b), t1, ctx->memidx);
-
- tcg_temp_free_i32(t1);
- tcg_temp_free_i32(t2);
-
- length = 6;
- }
- break;
- case 0x0e: /* cmp */
- {
- int a = (opcode >> 4) & 0xf;
- int b = opcode & 0xf;
-
- tcg_gen_mov_i32(cc_a, REG(a));
- tcg_gen_mov_i32(cc_b, REG(b));
- }
- break;
- case 0x19: /* jsr */
- {
- int fnreg = (opcode >> 4) & 0xf;
-
- /* Load the stack pointer into T0. */
- TCGv t1 = tcg_temp_new_i32();
- TCGv t2 = tcg_temp_new_i32();
-
- tcg_gen_movi_i32(t1, ctx->pc+2);
-
- /* Make space for the static chain and return address. */
- tcg_gen_subi_i32(t2, REG(1), 8);
- tcg_gen_mov_i32(REG(1), t2);
- tcg_gen_qemu_st32(t1, REG(1), ctx->memidx);
-
- /* Push the current frame pointer. */
- tcg_gen_subi_i32(t2, REG(1), 4);
- tcg_gen_mov_i32(REG(1), t2);
- tcg_gen_qemu_st32(REG(0), REG(1), ctx->memidx);
-
- /* Set the pc and $fp. */
- tcg_gen_mov_i32(REG(0), REG(1));
- tcg_gen_mov_i32(cpu_pc, REG(fnreg));
- tcg_temp_free_i32(t1);
- tcg_temp_free_i32(t2);
- tcg_gen_exit_tb(NULL, 0);
- ctx->bstate = BS_BRANCH;
- }
- break;
- case 0x1a: /* jmpa */
- {
- tcg_gen_movi_i32(cpu_pc, cpu_ldl_code(env, ctx->pc+2));
- tcg_gen_exit_tb(NULL, 0);
- ctx->bstate = BS_BRANCH;
- length = 6;
- }
- break;
- case 0x1b: /* ldi.b (immediate) */
- {
- int reg = (opcode >> 4) & 0xf;
- int val = cpu_ldl_code(env, ctx->pc+2);
- tcg_gen_movi_i32(REG(reg), val);
- length = 6;
- }
- break;
- case 0x1c: /* ld.b (register indirect) */
- {
- int src = opcode & 0xf;
- int dest = (opcode >> 4) & 0xf;
-
- tcg_gen_qemu_ld8u(REG(dest), REG(src), ctx->memidx);
- }
- break;
- case 0x1d: /* lda.b */
- {
- int reg = (opcode >> 4) & 0xf;
-
- TCGv ptr = tcg_temp_new_i32();
- tcg_gen_movi_i32(ptr, cpu_ldl_code(env, ctx->pc+2));
- tcg_gen_qemu_ld8u(REG(reg), ptr, ctx->memidx);
- tcg_temp_free_i32(ptr);
-
- length = 6;
- }
- break;
- case 0x1e: /* st.b */
- {
- int dest = (opcode >> 4) & 0xf;
- int val = opcode & 0xf;
-
- tcg_gen_qemu_st8(REG(val), REG(dest), ctx->memidx);
- }
- break;
- case 0x1f: /* sta.b */
- {
- int val = (opcode >> 4) & 0xf;
-
- TCGv ptr = tcg_temp_new_i32();
- tcg_gen_movi_i32(ptr, cpu_ldl_code(env, ctx->pc+2));
- tcg_gen_qemu_st8(REG(val), ptr, ctx->memidx);
- tcg_temp_free_i32(ptr);
-
- length = 6;
- }
- break;
- case 0x20: /* ldi.s (immediate) */
- {
- int reg = (opcode >> 4) & 0xf;
- int val = cpu_ldl_code(env, ctx->pc+2);
- tcg_gen_movi_i32(REG(reg), val);
- length = 6;
- }
- break;
- case 0x21: /* ld.s (register indirect) */
- {
- int src = opcode & 0xf;
- int dest = (opcode >> 4) & 0xf;
-
- tcg_gen_qemu_ld16u(REG(dest), REG(src), ctx->memidx);
- }
- break;
- case 0x22: /* lda.s */
- {
- int reg = (opcode >> 4) & 0xf;
-
- TCGv ptr = tcg_temp_new_i32();
- tcg_gen_movi_i32(ptr, cpu_ldl_code(env, ctx->pc+2));
- tcg_gen_qemu_ld16u(REG(reg), ptr, ctx->memidx);
- tcg_temp_free_i32(ptr);
-
- length = 6;
- }
- break;
- case 0x23: /* st.s */
- {
- int dest = (opcode >> 4) & 0xf;
- int val = opcode & 0xf;
-
- tcg_gen_qemu_st16(REG(val), REG(dest), ctx->memidx);
- }
- break;
- case 0x24: /* sta.s */
- {
- int val = (opcode >> 4) & 0xf;
-
- TCGv ptr = tcg_temp_new_i32();
- tcg_gen_movi_i32(ptr, cpu_ldl_code(env, ctx->pc+2));
- tcg_gen_qemu_st16(REG(val), ptr, ctx->memidx);
- tcg_temp_free_i32(ptr);
-
- length = 6;
- }
- break;
- case 0x25: /* jmp */
- {
- int reg = (opcode >> 4) & 0xf;
- tcg_gen_mov_i32(cpu_pc, REG(reg));
- tcg_gen_exit_tb(NULL, 0);
- ctx->bstate = BS_BRANCH;
- }
- break;
- case 0x26: /* and */
- {
- int a = (opcode >> 4) & 0xf;
- int b = opcode & 0xf;
-
- tcg_gen_and_i32(REG(a), REG(a), REG(b));
- }
- break;
- case 0x27: /* lshr */
- {
- int a = (opcode >> 4) & 0xf;
- int b = opcode & 0xf;
-
- TCGv sv = tcg_temp_new_i32();
- tcg_gen_andi_i32(sv, REG(b), 0x1f);
- tcg_gen_shr_i32(REG(a), REG(a), sv);
- tcg_temp_free_i32(sv);
- }
- break;
- case 0x28: /* ashl */
- {
- int a = (opcode >> 4) & 0xf;
- int b = opcode & 0xf;
-
- TCGv sv = tcg_temp_new_i32();
- tcg_gen_andi_i32(sv, REG(b), 0x1f);
- tcg_gen_shl_i32(REG(a), REG(a), sv);
- tcg_temp_free_i32(sv);
- }
- break;
- case 0x29: /* sub.l */
- {
- int a = (opcode >> 4) & 0xf;
- int b = opcode & 0xf;
-
- tcg_gen_sub_i32(REG(a), REG(a), REG(b));
- }
- break;
- case 0x2a: /* neg */
- {
- int a = (opcode >> 4) & 0xf;
- int b = opcode & 0xf;
-
- tcg_gen_neg_i32(REG(a), REG(b));
- }
- break;
- case 0x2b: /* or */
- {
- int a = (opcode >> 4) & 0xf;
- int b = opcode & 0xf;
-
- tcg_gen_or_i32(REG(a), REG(a), REG(b));
- }
- break;
- case 0x2c: /* not */
- {
- int a = (opcode >> 4) & 0xf;
- int b = opcode & 0xf;
-
- tcg_gen_not_i32(REG(a), REG(b));
- }
- break;
- case 0x2d: /* ashr */
- {
- int a = (opcode >> 4) & 0xf;
- int b = opcode & 0xf;
-
- TCGv sv = tcg_temp_new_i32();
- tcg_gen_andi_i32(sv, REG(b), 0x1f);
- tcg_gen_sar_i32(REG(a), REG(a), sv);
- tcg_temp_free_i32(sv);
- }
- break;
- case 0x2e: /* xor */
- {
- int a = (opcode >> 4) & 0xf;
- int b = opcode & 0xf;
-
- tcg_gen_xor_i32(REG(a), REG(a), REG(b));
- }
- break;
- case 0x2f: /* mul.l */
- {
- int a = (opcode >> 4) & 0xf;
- int b = opcode & 0xf;
-
- tcg_gen_mul_i32(REG(a), REG(a), REG(b));
- }
- break;
- case 0x30: /* swi */
- {
- int val = cpu_ldl_code(env, ctx->pc+2);
-
- TCGv temp = tcg_temp_new_i32();
- tcg_gen_movi_i32(temp, val);
- tcg_gen_st_i32(temp, cpu_env,
- offsetof(CPUMoxieState, sregs[3]));
- tcg_gen_movi_i32(cpu_pc, ctx->pc);
- tcg_gen_movi_i32(temp, MOXIE_EX_SWI);
- gen_helper_raise_exception(cpu_env, temp);
- tcg_temp_free_i32(temp);
-
- length = 6;
- }
- break;
- case 0x31: /* div.l */
- {
- int a = (opcode >> 4) & 0xf;
- int b = opcode & 0xf;
- tcg_gen_movi_i32(cpu_pc, ctx->pc);
- gen_helper_div(REG(a), cpu_env, REG(a), REG(b));
- }
- break;
- case 0x32: /* udiv.l */
- {
- int a = (opcode >> 4) & 0xf;
- int b = opcode & 0xf;
- tcg_gen_movi_i32(cpu_pc, ctx->pc);
- gen_helper_udiv(REG(a), cpu_env, REG(a), REG(b));
- }
- break;
- case 0x33: /* mod.l */
- {
- int a = (opcode >> 4) & 0xf;
- int b = opcode & 0xf;
- tcg_gen_rem_i32(REG(a), REG(a), REG(b));
- }
- break;
- case 0x34: /* umod.l */
- {
- int a = (opcode >> 4) & 0xf;
- int b = opcode & 0xf;
- tcg_gen_remu_i32(REG(a), REG(a), REG(b));
- }
- break;
- case 0x35: /* brk */
- {
- TCGv temp = tcg_temp_new_i32();
- tcg_gen_movi_i32(cpu_pc, ctx->pc);
- tcg_gen_movi_i32(temp, MOXIE_EX_BREAK);
- gen_helper_raise_exception(cpu_env, temp);
- tcg_temp_free_i32(temp);
- }
- break;
- case 0x36: /* ldo.b */
- {
- int a = (opcode >> 4) & 0xf;
- int b = opcode & 0xf;
-
- TCGv t1 = tcg_temp_new_i32();
- TCGv t2 = tcg_temp_new_i32();
- tcg_gen_addi_i32(t1, REG(b), cpu_ldl_code(env, ctx->pc+2));
- tcg_gen_qemu_ld8u(t2, t1, ctx->memidx);
- tcg_gen_mov_i32(REG(a), t2);
-
- tcg_temp_free_i32(t1);
- tcg_temp_free_i32(t2);
-
- length = 6;
- }
- break;
- case 0x37: /* sto.b */
- {
- int a = (opcode >> 4) & 0xf;
- int b = opcode & 0xf;
-
- TCGv t1 = tcg_temp_new_i32();
- TCGv t2 = tcg_temp_new_i32();
- tcg_gen_addi_i32(t1, REG(a), cpu_ldl_code(env, ctx->pc+2));
- tcg_gen_qemu_st8(REG(b), t1, ctx->memidx);
-
- tcg_temp_free_i32(t1);
- tcg_temp_free_i32(t2);
-
- length = 6;
- }
- break;
- case 0x38: /* ldo.s */
- {
- int a = (opcode >> 4) & 0xf;
- int b = opcode & 0xf;
-
- TCGv t1 = tcg_temp_new_i32();
- TCGv t2 = tcg_temp_new_i32();
- tcg_gen_addi_i32(t1, REG(b), cpu_ldl_code(env, ctx->pc+2));
- tcg_gen_qemu_ld16u(t2, t1, ctx->memidx);
- tcg_gen_mov_i32(REG(a), t2);
-
- tcg_temp_free_i32(t1);
- tcg_temp_free_i32(t2);
-
- length = 6;
- }
- break;
- case 0x39: /* sto.s */
- {
- int a = (opcode >> 4) & 0xf;
- int b = opcode & 0xf;
-
- TCGv t1 = tcg_temp_new_i32();
- TCGv t2 = tcg_temp_new_i32();
- tcg_gen_addi_i32(t1, REG(a), cpu_ldl_code(env, ctx->pc+2));
- tcg_gen_qemu_st16(REG(b), t1, ctx->memidx);
- tcg_temp_free_i32(t1);
- tcg_temp_free_i32(t2);
-
- length = 6;
- }
- break;
- default:
- {
- TCGv temp = tcg_temp_new_i32();
- tcg_gen_movi_i32(cpu_pc, ctx->pc);
- tcg_gen_movi_i32(temp, MOXIE_EX_BAD);
- gen_helper_raise_exception(cpu_env, temp);
- tcg_temp_free_i32(temp);
- }
- break;
- }
- }
-
- return length;
-}
-
-/* generate intermediate code for basic block 'tb'. */
-void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
-{
- CPUMoxieState *env = cs->env_ptr;
- MoxieCPU *cpu = env_archcpu(env);
- DisasContext ctx;
- target_ulong pc_start;
- int num_insns;
-
- pc_start = tb->pc;
- ctx.pc = pc_start;
- ctx.saved_pc = -1;
- ctx.tb = tb;
- ctx.memidx = 0;
- ctx.singlestep_enabled = 0;
- ctx.bstate = BS_NONE;
- num_insns = 0;
-
- gen_tb_start(tb);
- do {
- tcg_gen_insn_start(ctx.pc);
- num_insns++;
-
- if (unlikely(cpu_breakpoint_test(cs, ctx.pc, BP_ANY))) {
- tcg_gen_movi_i32(cpu_pc, ctx.pc);
- gen_helper_debug(cpu_env);
- ctx.bstate = BS_EXCP;
- /* The address covered by the breakpoint must be included in
- [tb->pc, tb->pc + tb->size) in order to for it to be
- properly cleared -- thus we increment the PC here so that
- the logic setting tb->size below does the right thing. */
- ctx.pc += 2;
- goto done_generating;
- }
-
- ctx.opcode = cpu_lduw_code(env, ctx.pc);
- ctx.pc += decode_opc(cpu, &ctx);
-
- if (num_insns >= max_insns) {
- break;
- }
- if (cs->singlestep_enabled) {
- break;
- }
- if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0) {
- break;
- }
- } while (ctx.bstate == BS_NONE && !tcg_op_buf_full());
-
- if (cs->singlestep_enabled) {
- tcg_gen_movi_tl(cpu_pc, ctx.pc);
- gen_helper_debug(cpu_env);
- } else {
- switch (ctx.bstate) {
- case BS_STOP:
- case BS_NONE:
- gen_goto_tb(env, &ctx, 0, ctx.pc);
- break;
- case BS_EXCP:
- tcg_gen_exit_tb(NULL, 0);
- break;
- case BS_BRANCH:
- default:
- break;
- }
- }
- done_generating:
- gen_tb_end(tb, num_insns);
-
- tb->size = ctx.pc - pc_start;
- tb->icount = num_insns;
-}
-
-void restore_state_to_opc(CPUMoxieState *env, TranslationBlock *tb,
- target_ulong *data)
-{
- env->pc = data[0];
-}
diff --git a/target/unicore32/cpu-param.h b/target/unicore32/cpu-param.h
deleted file mode 100644
index 94d8a5daa1..0000000000
--- a/target/unicore32/cpu-param.h
+++ /dev/null
@@ -1,17 +0,0 @@
-/*
- * UniCore32 cpu parameters for qemu.
- *
- * Copyright (C) 2010-2012 Guan Xuetao
- * SPDX-License-Identifier: GPL-2.0+
- */
-
-#ifndef UNICORE32_CPU_PARAM_H
-#define UNICORE32_CPU_PARAM_H 1
-
-#define TARGET_LONG_BITS 32
-#define TARGET_PAGE_BITS 12
-#define TARGET_PHYS_ADDR_SPACE_BITS 32
-#define TARGET_VIRT_ADDR_SPACE_BITS 32
-#define NB_MMU_MODES 2
-
-#endif
diff --git a/target/unicore32/cpu-qom.h b/target/unicore32/cpu-qom.h
deleted file mode 100644
index 43621e7479..0000000000
--- a/target/unicore32/cpu-qom.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * QEMU UniCore32 CPU
- *
- * Copyright (c) 2012 SUSE LINUX Products GmbH
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation, or (at your option) any
- * later version. See the COPYING file in the top-level directory.
- */
-#ifndef QEMU_UC32_CPU_QOM_H
-#define QEMU_UC32_CPU_QOM_H
-
-#include "hw/core/cpu.h"
-#include "qom/object.h"
-
-#define TYPE_UNICORE32_CPU "unicore32-cpu"
-
-OBJECT_DECLARE_TYPE(UniCore32CPU, UniCore32CPUClass,
- UNICORE32_CPU)
-
-/**
- * UniCore32CPUClass:
- * @parent_realize: The parent class' realize handler.
- *
- * A UniCore32 CPU model.
- */
-struct UniCore32CPUClass {
- /*< private >*/
- CPUClass parent_class;
- /*< public >*/
-
- DeviceRealize parent_realize;
-};
-
-
-#endif
diff --git a/target/unicore32/cpu.c b/target/unicore32/cpu.c
deleted file mode 100644
index 0258884f84..0000000000
--- a/target/unicore32/cpu.c
+++ /dev/null
@@ -1,174 +0,0 @@
-/*
- * QEMU UniCore32 CPU
- *
- * Copyright (c) 2010-2012 Guan Xuetao
- * Copyright (c) 2012 SUSE LINUX Products GmbH
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * Contributions from 2012-04-01 on are considered under GPL version 2,
- * or (at your option) any later version.
- */
-
-#include "qemu/osdep.h"
-#include "qapi/error.h"
-#include "cpu.h"
-#include "migration/vmstate.h"
-#include "exec/exec-all.h"
-
-static void uc32_cpu_set_pc(CPUState *cs, vaddr value)
-{
- UniCore32CPU *cpu = UNICORE32_CPU(cs);
-
- cpu->env.regs[31] = value;
-}
-
-static bool uc32_cpu_has_work(CPUState *cs)
-{
- return cs->interrupt_request &
- (CPU_INTERRUPT_HARD | CPU_INTERRUPT_EXITTB);
-}
-
-static inline void set_feature(CPUUniCore32State *env, int feature)
-{
- env->features |= feature;
-}
-
-/* CPU models */
-
-static ObjectClass *uc32_cpu_class_by_name(const char *cpu_model)
-{
- ObjectClass *oc;
- char *typename;
-
- typename = g_strdup_printf(UNICORE32_CPU_TYPE_NAME("%s"), cpu_model);
- oc = object_class_by_name(typename);
- g_free(typename);
- if (oc != NULL && (!object_class_dynamic_cast(oc, TYPE_UNICORE32_CPU) ||
- object_class_is_abstract(oc))) {
- oc = NULL;
- }
- return oc;
-}
-
-static void unicore_ii_cpu_initfn(Object *obj)
-{
- UniCore32CPU *cpu = UNICORE32_CPU(obj);
- CPUUniCore32State *env = &cpu->env;
-
- env->cp0.c0_cpuid = 0x4d000863;
- env->cp0.c0_cachetype = 0x0d152152;
- env->cp0.c1_sys = 0x2000;
- env->cp0.c2_base = 0x0;
- env->cp0.c3_faultstatus = 0x0;
- env->cp0.c4_faultaddr = 0x0;
- env->ucf64.xregs[UC32_UCF64_FPSCR] = 0;
-
- set_feature(env, UC32_HWCAP_CMOV);
- set_feature(env, UC32_HWCAP_UCF64);
-}
-
-static void uc32_any_cpu_initfn(Object *obj)
-{
- UniCore32CPU *cpu = UNICORE32_CPU(obj);
- CPUUniCore32State *env = &cpu->env;
-
- env->cp0.c0_cpuid = 0xffffffff;
- env->ucf64.xregs[UC32_UCF64_FPSCR] = 0;
-
- set_feature(env, UC32_HWCAP_CMOV);
- set_feature(env, UC32_HWCAP_UCF64);
-}
-
-static void uc32_cpu_realizefn(DeviceState *dev, Error **errp)
-{
- CPUState *cs = CPU(dev);
- UniCore32CPUClass *ucc = UNICORE32_CPU_GET_CLASS(dev);
- Error *local_err = NULL;
-
- cpu_exec_realizefn(cs, &local_err);
- if (local_err != NULL) {
- error_propagate(errp, local_err);
- return;
- }
-
- qemu_init_vcpu(cs);
-
- ucc->parent_realize(dev, errp);
-}
-
-static void uc32_cpu_initfn(Object *obj)
-{
- UniCore32CPU *cpu = UNICORE32_CPU(obj);
- CPUUniCore32State *env = &cpu->env;
-
- cpu_set_cpustate_pointers(cpu);
-
-#ifdef CONFIG_USER_ONLY
- env->uncached_asr = ASR_MODE_USER;
- env->regs[31] = 0;
-#else
- env->uncached_asr = ASR_MODE_PRIV;
- env->regs[31] = 0x03000000;
-#endif
-}
-
-static const VMStateDescription vmstate_uc32_cpu = {
- .name = "cpu",
- .unmigratable = 1,
-};
-
-#include "hw/core/tcg-cpu-ops.h"
-
-static struct TCGCPUOps uc32_tcg_ops = {
- .initialize = uc32_translate_init,
- .cpu_exec_interrupt = uc32_cpu_exec_interrupt,
- .tlb_fill = uc32_cpu_tlb_fill,
-
-#ifndef CONFIG_USER_ONLY
- .do_interrupt = uc32_cpu_do_interrupt,
-#endif /* !CONFIG_USER_ONLY */
-};
-
-static void uc32_cpu_class_init(ObjectClass *oc, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(oc);
- CPUClass *cc = CPU_CLASS(oc);
- UniCore32CPUClass *ucc = UNICORE32_CPU_CLASS(oc);
-
- device_class_set_parent_realize(dc, uc32_cpu_realizefn,
- &ucc->parent_realize);
-
- cc->class_by_name = uc32_cpu_class_by_name;
- cc->has_work = uc32_cpu_has_work;
- cc->dump_state = uc32_cpu_dump_state;
- cc->set_pc = uc32_cpu_set_pc;
- cc->get_phys_page_debug = uc32_cpu_get_phys_page_debug;
- dc->vmsd = &vmstate_uc32_cpu;
- cc->tcg_ops = &uc32_tcg_ops;
-}
-
-#define DEFINE_UNICORE32_CPU_TYPE(cpu_model, initfn) \
- { \
- .parent = TYPE_UNICORE32_CPU, \
- .instance_init = initfn, \
- .name = UNICORE32_CPU_TYPE_NAME(cpu_model), \
- }
-
-static const TypeInfo uc32_cpu_type_infos[] = {
- {
- .name = TYPE_UNICORE32_CPU,
- .parent = TYPE_CPU,
- .instance_size = sizeof(UniCore32CPU),
- .instance_init = uc32_cpu_initfn,
- .abstract = true,
- .class_size = sizeof(UniCore32CPUClass),
- .class_init = uc32_cpu_class_init,
- },
- DEFINE_UNICORE32_CPU_TYPE("UniCore-II", unicore_ii_cpu_initfn),
- DEFINE_UNICORE32_CPU_TYPE("any", uc32_any_cpu_initfn),
-};
-
-DEFINE_TYPES(uc32_cpu_type_infos)
diff --git a/target/unicore32/cpu.h b/target/unicore32/cpu.h
deleted file mode 100644
index 7a32e086ed..0000000000
--- a/target/unicore32/cpu.h
+++ /dev/null
@@ -1,168 +0,0 @@
-/*
- * UniCore32 virtual CPU header
- *
- * Copyright (C) 2010-2012 Guan Xuetao
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation, or (at your option) any
- * later version. See the COPYING file in the top-level directory.
- */
-
-#ifndef UNICORE32_CPU_H
-#define UNICORE32_CPU_H
-
-#include "cpu-qom.h"
-#include "exec/cpu-defs.h"
-
-typedef struct CPUUniCore32State {
- /* Regs for current mode. */
- uint32_t regs[32];
- /* Frequently accessed ASR bits are stored separately for efficiently.
- This contains all the other bits. Use asr_{read,write} to access
- the whole ASR. */
- uint32_t uncached_asr;
- uint32_t bsr;
-
- /* Banked registers. */
- uint32_t banked_bsr[6];
- uint32_t banked_r29[6];
- uint32_t banked_r30[6];
-
- /* asr flag cache for faster execution */
- uint32_t CF; /* 0 or 1 */
- uint32_t VF; /* V is the bit 31. All other bits are undefined */
- uint32_t NF; /* N is bit 31. All other bits are undefined. */
- uint32_t ZF; /* Z set if zero. */
-
- /* System control coprocessor (cp0) */
- struct {
- uint32_t c0_cpuid;
- uint32_t c0_cachetype;
- uint32_t c1_sys; /* System control register. */
- uint32_t c2_base; /* MMU translation table base. */
- uint32_t c3_faultstatus; /* Fault status registers. */
- uint32_t c4_faultaddr; /* Fault address registers. */
- uint32_t c5_cacheop; /* Cache operation registers. */
- uint32_t c6_tlbop; /* TLB operation registers. */
- } cp0;
-
- /* UniCore-F64 coprocessor state. */
- struct {
- float64 regs[16];
- uint32_t xregs[32];
- float_status fp_status;
- } ucf64;
-
- /* Internal CPU feature flags. */
- uint32_t features;
-
-} CPUUniCore32State;
-
-/**
- * UniCore32CPU:
- * @env: #CPUUniCore32State
- *
- * A UniCore32 CPU.
- */
-struct UniCore32CPU {
- /*< private >*/
- CPUState parent_obj;
- /*< public >*/
-
- CPUNegativeOffsetState neg;
- CPUUniCore32State env;
-};
-
-
-void uc32_cpu_do_interrupt(CPUState *cpu);
-bool uc32_cpu_exec_interrupt(CPUState *cpu, int int_req);
-void uc32_cpu_dump_state(CPUState *cpu, FILE *f, int flags);
-hwaddr uc32_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
-
-#define ASR_M (0x1f)
-#define ASR_MODE_USER (0x10)
-#define ASR_MODE_INTR (0x12)
-#define ASR_MODE_PRIV (0x13)
-#define ASR_MODE_TRAP (0x17)
-#define ASR_MODE_EXTN (0x1b)
-#define ASR_MODE_SUSR (0x1f)
-#define ASR_I (1 << 7)
-#define ASR_V (1 << 28)
-#define ASR_C (1 << 29)
-#define ASR_Z (1 << 30)
-#define ASR_N (1 << 31)
-#define ASR_NZCV (ASR_N | ASR_Z | ASR_C | ASR_V)
-#define ASR_RESERVED (~(ASR_M | ASR_I | ASR_NZCV))
-
-#define UC32_EXCP_PRIV (1)
-#define UC32_EXCP_ITRAP (2)
-#define UC32_EXCP_DTRAP (3)
-#define UC32_EXCP_INTR (4)
-
-/* Return the current ASR value. */
-target_ulong cpu_asr_read(CPUUniCore32State *env1);
-/* Set the ASR. Note that some bits of mask must be all-set or all-clear. */
-void cpu_asr_write(CPUUniCore32State *env1, target_ulong val, target_ulong mask);
-
-/* UniCore-F64 system registers. */
-#define UC32_UCF64_FPSCR (31)
-#define UCF64_FPSCR_MASK (0x27ffffff)
-#define UCF64_FPSCR_RND_MASK (0x7)
-#define UCF64_FPSCR_RND(r) (((r) >> 0) & UCF64_FPSCR_RND_MASK)
-#define UCF64_FPSCR_TRAPEN_MASK (0x7f)
-#define UCF64_FPSCR_TRAPEN(r) (((r) >> 10) & UCF64_FPSCR_TRAPEN_MASK)
-#define UCF64_FPSCR_FLAG_MASK (0x3ff)
-#define UCF64_FPSCR_FLAG(r) (((r) >> 17) & UCF64_FPSCR_FLAG_MASK)
-#define UCF64_FPSCR_FLAG_ZERO (1 << 17)
-#define UCF64_FPSCR_FLAG_INFINITY (1 << 18)
-#define UCF64_FPSCR_FLAG_INVALID (1 << 19)
-#define UCF64_FPSCR_FLAG_UNDERFLOW (1 << 20)
-#define UCF64_FPSCR_FLAG_OVERFLOW (1 << 21)
-#define UCF64_FPSCR_FLAG_INEXACT (1 << 22)
-#define UCF64_FPSCR_FLAG_HUGEINT (1 << 23)
-#define UCF64_FPSCR_FLAG_DENORMAL (1 << 24)
-#define UCF64_FPSCR_FLAG_UNIMP (1 << 25)
-#define UCF64_FPSCR_FLAG_DIVZERO (1 << 26)
-
-#define UC32_HWCAP_CMOV 4 /* 1 << 2 */
-#define UC32_HWCAP_UCF64 8 /* 1 << 3 */
-
-#define cpu_signal_handler uc32_cpu_signal_handler
-
-int uc32_cpu_signal_handler(int host_signum, void *pinfo, void *puc);
-
-/* MMU modes definitions */
-#define MMU_USER_IDX 1
-static inline int cpu_mmu_index(CPUUniCore32State *env, bool ifetch)
-{
- return (env->uncached_asr & ASR_M) == ASR_MODE_USER ? 1 : 0;
-}
-
-typedef CPUUniCore32State CPUArchState;
-typedef UniCore32CPU ArchCPU;
-
-#include "exec/cpu-all.h"
-
-#define UNICORE32_CPU_TYPE_SUFFIX "-" TYPE_UNICORE32_CPU
-#define UNICORE32_CPU_TYPE_NAME(model) model UNICORE32_CPU_TYPE_SUFFIX
-#define CPU_RESOLVING_TYPE TYPE_UNICORE32_CPU
-
-static inline void cpu_get_tb_cpu_state(CPUUniCore32State *env, target_ulong *pc,
- target_ulong *cs_base, uint32_t *flags)
-{
- *pc = env->regs[31];
- *cs_base = 0;
- *flags = 0;
- if ((env->uncached_asr & ASR_M) != ASR_MODE_USER) {
- *flags |= (1 << 6);
- }
-}
-
-bool uc32_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
- MMUAccessType access_type, int mmu_idx,
- bool probe, uintptr_t retaddr);
-void uc32_translate_init(void);
-void switch_mode(CPUUniCore32State *, int);
-
-#endif /* UNICORE32_CPU_H */
diff --git a/target/unicore32/helper.c b/target/unicore32/helper.c
deleted file mode 100644
index 704393c27f..0000000000
--- a/target/unicore32/helper.c
+++ /dev/null
@@ -1,183 +0,0 @@
-/*
- * Copyright (C) 2010-2012 Guan Xuetao
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * Contributions from 2012-04-01 on are considered under GPL version 2,
- * or (at your option) any later version.
- */
-
-#include "qemu/osdep.h"
-#include "qemu/log.h"
-#include "cpu.h"
-#include "exec/exec-all.h"
-#include "exec/helper-proto.h"
-#include "semihosting/console.h"
-
-#undef DEBUG_UC32
-
-#ifdef DEBUG_UC32
-#define DPRINTF(fmt, ...) printf("%s: " fmt , __func__, ## __VA_ARGS__)
-#else
-#define DPRINTF(fmt, ...) do {} while (0)
-#endif
-
-#ifndef CONFIG_USER_ONLY
-void helper_cp0_set(CPUUniCore32State *env, uint32_t val, uint32_t creg,
- uint32_t cop)
-{
- /*
- * movc pp.nn, rn, #imm9
- * rn: UCOP_REG_D
- * nn: UCOP_REG_N
- * 1: sys control reg.
- * 2: page table base reg.
- * 3: data fault status reg.
- * 4: insn fault status reg.
- * 5: cache op. reg.
- * 6: tlb op. reg.
- * imm9: split UCOP_IMM10 with bit5 is 0
- */
- switch (creg) {
- case 1:
- if (cop != 0) {
- goto unrecognized;
- }
- env->cp0.c1_sys = val;
- break;
- case 2:
- if (cop != 0) {
- goto unrecognized;
- }
- env->cp0.c2_base = val;
- break;
- case 3:
- if (cop != 0) {
- goto unrecognized;
- }
- env->cp0.c3_faultstatus = val;
- break;
- case 4:
- if (cop != 0) {
- goto unrecognized;
- }
- env->cp0.c4_faultaddr = val;
- break;
- case 5:
- switch (cop) {
- case 28:
- DPRINTF("Invalidate Entire I&D cache\n");
- return;
- case 20:
- DPRINTF("Invalidate Entire Icache\n");
- return;
- case 12:
- DPRINTF("Invalidate Entire Dcache\n");
- return;
- case 10:
- DPRINTF("Clean Entire Dcache\n");
- return;
- case 14:
- DPRINTF("Flush Entire Dcache\n");
- return;
- case 13:
- DPRINTF("Invalidate Dcache line\n");
- return;
- case 11:
- DPRINTF("Clean Dcache line\n");
- return;
- case 15:
- DPRINTF("Flush Dcache line\n");
- return;
- }
- break;
- case 6:
- if ((cop <= 6) && (cop >= 2)) {
- /* invalid all tlb */
- tlb_flush(env_cpu(env));
- return;
- }
- break;
- default:
- goto unrecognized;
- }
- return;
-unrecognized:
- qemu_log_mask(LOG_GUEST_ERROR,
- "Wrong register (%d) or wrong operation (%d) in cp0_set!\n",
- creg, cop);
-}
-
-uint32_t helper_cp0_get(CPUUniCore32State *env, uint32_t creg, uint32_t cop)
-{
- /*
- * movc rd, pp.nn, #imm9
- * rd: UCOP_REG_D
- * nn: UCOP_REG_N
- * 0: cpuid and cachetype
- * 1: sys control reg.
- * 2: page table base reg.
- * 3: data fault status reg.
- * 4: insn fault status reg.
- * imm9: split UCOP_IMM10 with bit5 is 0
- */
- switch (creg) {
- case 0:
- switch (cop) {
- case 0:
- return env->cp0.c0_cpuid;
- case 1:
- return env->cp0.c0_cachetype;
- }
- break;
- case 1:
- if (cop == 0) {
- return env->cp0.c1_sys;
- }
- break;
- case 2:
- if (cop == 0) {
- return env->cp0.c2_base;
- }
- break;
- case 3:
- if (cop == 0) {
- return env->cp0.c3_faultstatus;
- }
- break;
- case 4:
- if (cop == 0) {
- return env->cp0.c4_faultaddr;
- }
- break;
- }
- qemu_log_mask(LOG_GUEST_ERROR,
- "Wrong register (%d) or wrong operation (%d) in cp0_set!\n",
- creg, cop);
- return 0;
-}
-
-void helper_cp1_putc(target_ulong regval)
-{
- const char c = regval;
-
- qemu_semihosting_log_out(&c, sizeof(c));
-}
-#endif /* !CONFIG_USER_ONLY */
-
-bool uc32_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
-{
- if (interrupt_request & CPU_INTERRUPT_HARD) {
- UniCore32CPU *cpu = UNICORE32_CPU(cs);
- CPUUniCore32State *env = &cpu->env;
-
- if (!(env->uncached_asr & ASR_I)) {
- cs->exception_index = UC32_EXCP_INTR;
- uc32_cpu_do_interrupt(cs);
- return true;
- }
- }
- return false;
-}
diff --git a/target/unicore32/helper.h b/target/unicore32/helper.h
deleted file mode 100644
index a4a5d45d1d..0000000000
--- a/target/unicore32/helper.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (C) 2010-2012 Guan Xuetao
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation, or (at your option) any
- * later version. See the COPYING file in the top-level directory.
- */
-
-#ifndef CONFIG_USER_ONLY
-DEF_HELPER_4(cp0_set, void, env, i32, i32, i32)
-DEF_HELPER_3(cp0_get, i32, env, i32, i32)
-DEF_HELPER_1(cp1_putc, void, i32)
-#endif
-
-DEF_HELPER_2(exception, void, env, i32)
-
-DEF_HELPER_3(asr_write, void, env, i32, i32)
-DEF_HELPER_1(asr_read, i32, env)
-
-DEF_HELPER_2(get_user_reg, i32, env, i32)
-DEF_HELPER_3(set_user_reg, void, env, i32, i32)
-
-DEF_HELPER_3(add_cc, i32, env, i32, i32)
-DEF_HELPER_3(adc_cc, i32, env, i32, i32)
-DEF_HELPER_3(sub_cc, i32, env, i32, i32)
-DEF_HELPER_3(sbc_cc, i32, env, i32, i32)
-
-DEF_HELPER_2(shl, i32, i32, i32)
-DEF_HELPER_2(shr, i32, i32, i32)
-DEF_HELPER_2(sar, i32, i32, 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(ror_cc, i32, env, i32, i32)
-
-DEF_HELPER_1(ucf64_get_fpscr, i32, env)
-DEF_HELPER_2(ucf64_set_fpscr, void, env, i32)
-
-DEF_HELPER_3(ucf64_adds, f32, f32, f32, env)
-DEF_HELPER_3(ucf64_addd, f64, f64, f64, env)
-DEF_HELPER_3(ucf64_subs, f32, f32, f32, env)
-DEF_HELPER_3(ucf64_subd, f64, f64, f64, env)
-DEF_HELPER_3(ucf64_muls, f32, f32, f32, env)
-DEF_HELPER_3(ucf64_muld, f64, f64, f64, env)
-DEF_HELPER_3(ucf64_divs, f32, f32, f32, env)
-DEF_HELPER_3(ucf64_divd, f64, f64, f64, env)
-DEF_HELPER_1(ucf64_negs, f32, f32)
-DEF_HELPER_1(ucf64_negd, f64, f64)
-DEF_HELPER_1(ucf64_abss, f32, f32)
-DEF_HELPER_1(ucf64_absd, f64, f64)
-DEF_HELPER_4(ucf64_cmps, void, f32, f32, i32, env)
-DEF_HELPER_4(ucf64_cmpd, void, f64, f64, i32, env)
-
-DEF_HELPER_2(ucf64_sf2df, f64, f32, env)
-DEF_HELPER_2(ucf64_df2sf, f32, f64, env)
-
-DEF_HELPER_2(ucf64_si2sf, f32, f32, env)
-DEF_HELPER_2(ucf64_si2df, f64, f32, env)
-
-DEF_HELPER_2(ucf64_sf2si, f32, f32, env)
-DEF_HELPER_2(ucf64_df2si, f32, f64, env)
diff --git a/target/unicore32/meson.build b/target/unicore32/meson.build
deleted file mode 100644
index 0fa78772eb..0000000000
--- a/target/unicore32/meson.build
+++ /dev/null
@@ -1,14 +0,0 @@
-unicore32_ss = ss.source_set()
-unicore32_ss.add(files(
- 'cpu.c',
- 'helper.c',
- 'op_helper.c',
- 'translate.c',
- 'ucf64_helper.c',
-), curses)
-
-unicore32_softmmu_ss = ss.source_set()
-unicore32_softmmu_ss.add(files('softmmu.c'))
-
-target_arch += {'unicore32': unicore32_ss}
-target_softmmu_arch += {'unicore32': unicore32_softmmu_ss}
diff --git a/target/unicore32/op_helper.c b/target/unicore32/op_helper.c
deleted file mode 100644
index eeaa78601a..0000000000
--- a/target/unicore32/op_helper.c
+++ /dev/null
@@ -1,244 +0,0 @@
-/*
- * UniCore32 helper routines
- *
- * Copyright (C) 2010-2012 Guan Xuetao
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation, or (at your option) any
- * later version. See the COPYING file in the top-level directory.
- */
-#include "qemu/osdep.h"
-#include "cpu.h"
-#include "exec/helper-proto.h"
-#include "exec/exec-all.h"
-#include "exec/cpu_ldst.h"
-
-#define SIGNBIT (uint32_t)0x80000000
-#define SIGNBIT64 ((uint64_t)1 << 63)
-
-void HELPER(exception)(CPUUniCore32State *env, uint32_t excp)
-{
- CPUState *cs = env_cpu(env);
-
- cs->exception_index = excp;
- cpu_loop_exit(cs);
-}
-
-static target_ulong asr_read(CPUUniCore32State *env)
-{
- int ZF;
- ZF = (env->ZF == 0);
- return env->uncached_asr | (env->NF & 0x80000000) | (ZF << 30) |
- (env->CF << 29) | ((env->VF & 0x80000000) >> 3);
-}
-
-target_ulong cpu_asr_read(CPUUniCore32State *env)
-{
- return asr_read(env);
-}
-
-target_ulong HELPER(asr_read)(CPUUniCore32State *env)
-{
- return asr_read(env);
-}
-
-static void asr_write(CPUUniCore32State *env, target_ulong val,
- target_ulong mask)
-{
- if (mask & ASR_NZCV) {
- env->ZF = (~val) & ASR_Z;
- env->NF = val;
- env->CF = (val >> 29) & 1;
- env->VF = (val << 3) & 0x80000000;
- }
-
- if ((env->uncached_asr ^ val) & mask & ASR_M) {
- switch_mode(env, val & ASR_M);
- }
- mask &= ~ASR_NZCV;
- env->uncached_asr = (env->uncached_asr & ~mask) | (val & mask);
-}
-
-void cpu_asr_write(CPUUniCore32State *env, target_ulong val, target_ulong mask)
-{
- asr_write(env, val, mask);
-}
-
-void HELPER(asr_write)(CPUUniCore32State *env, target_ulong val,
- target_ulong mask)
-{
- asr_write(env, val, mask);
-}
-
-/* Access to user mode registers from privileged modes. */
-uint32_t HELPER(get_user_reg)(CPUUniCore32State *env, uint32_t regno)
-{
- uint32_t val;
-
- if (regno == 29) {
- val = env->banked_r29[0];
- } else if (regno == 30) {
- val = env->banked_r30[0];
- } else {
- val = env->regs[regno];
- }
- return val;
-}
-
-void HELPER(set_user_reg)(CPUUniCore32State *env, uint32_t regno, uint32_t val)
-{
- if (regno == 29) {
- env->banked_r29[0] = val;
- } else if (regno == 30) {
- env->banked_r30[0] = val;
- } else {
- env->regs[regno] = val;
- }
-}
-
-/* ??? Flag setting arithmetic is awkward because we need to do comparisons.
- The only way to do that in TCG is a conditional branch, which clobbers
- all our temporaries. For now implement these as helper functions. */
-
-uint32_t HELPER(add_cc)(CPUUniCore32State *env, uint32_t a, uint32_t b)
-{
- uint32_t result;
- result = a + b;
- env->NF = env->ZF = result;
- env->CF = result < a;
- env->VF = (a ^ b ^ -1) & (a ^ result);
- return result;
-}
-
-uint32_t HELPER(adc_cc)(CPUUniCore32State *env, uint32_t a, uint32_t b)
-{
- uint32_t result;
- if (!env->CF) {
- result = a + b;
- env->CF = result < a;
- } else {
- result = a + b + 1;
- env->CF = result <= a;
- }
- env->VF = (a ^ b ^ -1) & (a ^ result);
- env->NF = env->ZF = result;
- return result;
-}
-
-uint32_t HELPER(sub_cc)(CPUUniCore32State *env, uint32_t a, uint32_t b)
-{
- uint32_t result;
- result = a - b;
- env->NF = env->ZF = result;
- env->CF = a >= b;
- env->VF = (a ^ b) & (a ^ result);
- return result;
-}
-
-uint32_t HELPER(sbc_cc)(CPUUniCore32State *env, uint32_t a, uint32_t b)
-{
- uint32_t result;
- if (!env->CF) {
- result = a - b - 1;
- env->CF = a > b;
- } else {
- result = a - b;
- env->CF = a >= b;
- }
- env->VF = (a ^ b) & (a ^ result);
- env->NF = env->ZF = result;
- return result;
-}
-
-/* Similarly for variable shift instructions. */
-
-uint32_t HELPER(shl)(uint32_t x, uint32_t i)
-{
- int shift = i & 0xff;
- if (shift >= 32) {
- return 0;
- }
- return x << shift;
-}
-
-uint32_t HELPER(shr)(uint32_t x, uint32_t i)
-{
- int shift = i & 0xff;
- if (shift >= 32) {
- return 0;
- }
- return (uint32_t)x >> shift;
-}
-
-uint32_t HELPER(sar)(uint32_t x, uint32_t i)
-{
- int shift = i & 0xff;
- if (shift >= 32) {
- shift = 31;
- }
- return (int32_t)x >> shift;
-}
-
-uint32_t HELPER(shl_cc)(CPUUniCore32State *env, uint32_t x, uint32_t i)
-{
- int shift = i & 0xff;
- if (shift >= 32) {
- if (shift == 32) {
- env->CF = x & 1;
- } else {
- env->CF = 0;
- }
- return 0;
- } else if (shift != 0) {
- env->CF = (x >> (32 - shift)) & 1;
- return x << shift;
- }
- return x;
-}
-
-uint32_t HELPER(shr_cc)(CPUUniCore32State *env, uint32_t x, uint32_t i)
-{
- int shift = i & 0xff;
- if (shift >= 32) {
- if (shift == 32) {
- env->CF = (x >> 31) & 1;
- } else {
- env->CF = 0;
- }
- return 0;
- } else if (shift != 0) {
- env->CF = (x >> (shift - 1)) & 1;
- return x >> shift;
- }
- return x;
-}
-
-uint32_t HELPER(sar_cc)(CPUUniCore32State *env, uint32_t x, uint32_t i)
-{
- int shift = i & 0xff;
- if (shift >= 32) {
- env->CF = (x >> 31) & 1;
- return (int32_t)x >> 31;
- } else if (shift != 0) {
- env->CF = (x >> (shift - 1)) & 1;
- return (int32_t)x >> shift;
- }
- return x;
-}
-
-uint32_t HELPER(ror_cc)(CPUUniCore32State *env, uint32_t x, uint32_t i)
-{
- int shift1, shift;
- shift1 = i & 0xff;
- shift = shift1 & 0x1f;
- if (shift == 0) {
- if (shift1 != 0) {
- env->CF = (x >> 31) & 1;
- }
- return x;
- } else {
- env->CF = (x >> (shift - 1)) & 1;
- return ((uint32_t)x >> shift) | (x << (32 - shift));
- }
-}
diff --git a/target/unicore32/softmmu.c b/target/unicore32/softmmu.c
deleted file mode 100644
index cbdaa500b7..0000000000
--- a/target/unicore32/softmmu.c
+++ /dev/null
@@ -1,280 +0,0 @@
-/*
- * Softmmu related functions
- *
- * Copyright (C) 2010-2012 Guan Xuetao
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation, or any later version.
- * See the COPYING file in the top-level directory.
- */
-#ifdef CONFIG_USER_ONLY
-#error This file only exist under softmmu circumstance
-#endif
-
-#include "qemu/osdep.h"
-#include "cpu.h"
-#include "exec/exec-all.h"
-#include "qemu/error-report.h"
-
-#undef DEBUG_UC32
-
-#ifdef DEBUG_UC32
-#define DPRINTF(fmt, ...) printf("%s: " fmt , __func__, ## __VA_ARGS__)
-#else
-#define DPRINTF(fmt, ...) do {} while (0)
-#endif
-
-#define SUPERPAGE_SIZE (1 << 22)
-#define UC32_PAGETABLE_READ (1 << 8)
-#define UC32_PAGETABLE_WRITE (1 << 7)
-#define UC32_PAGETABLE_EXEC (1 << 6)
-#define UC32_PAGETABLE_EXIST (1 << 2)
-#define PAGETABLE_TYPE(x) ((x) & 3)
-
-
-/* Map CPU modes onto saved register banks. */
-static inline int bank_number(CPUUniCore32State *env, int mode)
-{
- switch (mode) {
- case ASR_MODE_USER:
- case ASR_MODE_SUSR:
- return 0;
- case ASR_MODE_PRIV:
- return 1;
- case ASR_MODE_TRAP:
- return 2;
- case ASR_MODE_EXTN:
- return 3;
- case ASR_MODE_INTR:
- return 4;
- }
- cpu_abort(env_cpu(env), "Bad mode %x\n", mode);
- return -1;
-}
-
-void switch_mode(CPUUniCore32State *env, int mode)
-{
- int old_mode;
- int i;
-
- old_mode = env->uncached_asr & ASR_M;
- if (mode == old_mode) {
- return;
- }
-
- i = bank_number(env, old_mode);
- env->banked_r29[i] = env->regs[29];
- env->banked_r30[i] = env->regs[30];
- env->banked_bsr[i] = env->bsr;
-
- i = bank_number(env, mode);
- env->regs[29] = env->banked_r29[i];
- env->regs[30] = env->banked_r30[i];
- env->bsr = env->banked_bsr[i];
-}
-
-/* Handle a CPU exception. */
-void uc32_cpu_do_interrupt(CPUState *cs)
-{
- UniCore32CPU *cpu = UNICORE32_CPU(cs);
- CPUUniCore32State *env = &cpu->env;
- uint32_t addr;
- int new_mode;
-
- switch (cs->exception_index) {
- case UC32_EXCP_PRIV:
- new_mode = ASR_MODE_PRIV;
- addr = 0x08;
- break;
- case UC32_EXCP_ITRAP:
- DPRINTF("itrap happened at %x\n", env->regs[31]);
- new_mode = ASR_MODE_TRAP;
- addr = 0x0c;
- break;
- case UC32_EXCP_DTRAP:
- DPRINTF("dtrap happened at %x\n", env->regs[31]);
- new_mode = ASR_MODE_TRAP;
- addr = 0x10;
- break;
- case UC32_EXCP_INTR:
- new_mode = ASR_MODE_INTR;
- addr = 0x18;
- break;
- default:
- cpu_abort(cs, "Unhandled exception 0x%x\n", cs->exception_index);
- return;
- }
- /* High vectors. */
- if (env->cp0.c1_sys & (1 << 13)) {
- addr += 0xffff0000;
- }
-
- switch_mode(env, new_mode);
- env->bsr = cpu_asr_read(env);
- env->uncached_asr = (env->uncached_asr & ~ASR_M) | new_mode;
- env->uncached_asr |= ASR_I;
- /* The PC already points to the proper instruction. */
- env->regs[30] = env->regs[31];
- env->regs[31] = addr;
- cs->interrupt_request |= CPU_INTERRUPT_EXITTB;
-}
-
-static int get_phys_addr_ucv2(CPUUniCore32State *env, uint32_t address,
- int access_type, int is_user, uint32_t *phys_ptr, int *prot,
- target_ulong *page_size)
-{
- CPUState *cs = env_cpu(env);
- int code;
- uint32_t table;
- uint32_t desc;
- uint32_t phys_addr;
-
- /* Pagetable walk. */
- /* Lookup l1 descriptor. */
- table = env->cp0.c2_base & 0xfffff000;
- table |= (address >> 20) & 0xffc;
- desc = ldl_phys(cs->as, table);
- code = 0;
- switch (PAGETABLE_TYPE(desc)) {
- case 3:
- /* Superpage */
- if (!(desc & UC32_PAGETABLE_EXIST)) {
- code = 0x0b; /* superpage miss */
- goto do_fault;
- }
- phys_addr = (desc & 0xffc00000) | (address & 0x003fffff);
- *page_size = SUPERPAGE_SIZE;
- break;
- case 0:
- /* Lookup l2 entry. */
- if (is_user) {
- DPRINTF("PGD address %x, desc %x\n", table, desc);
- }
- if (!(desc & UC32_PAGETABLE_EXIST)) {
- code = 0x05; /* second pagetable miss */
- goto do_fault;
- }
- table = (desc & 0xfffff000) | ((address >> 10) & 0xffc);
- desc = ldl_phys(cs->as, table);
- /* 4k page. */
- if (is_user) {
- DPRINTF("PTE address %x, desc %x\n", table, desc);
- }
- if (!(desc & UC32_PAGETABLE_EXIST)) {
- code = 0x08; /* page miss */
- goto do_fault;
- }
- switch (PAGETABLE_TYPE(desc)) {
- case 0:
- phys_addr = (desc & 0xfffff000) | (address & 0xfff);
- *page_size = TARGET_PAGE_SIZE;
- break;
- default:
- cpu_abort(cs, "wrong page type!");
- }
- break;
- default:
- cpu_abort(cs, "wrong page type!");
- }
-
- *phys_ptr = phys_addr;
- *prot = 0;
- /* Check access permissions. */
- if (desc & UC32_PAGETABLE_READ) {
- *prot |= PAGE_READ;
- } else {
- if (is_user && (access_type == 0)) {
- code = 0x11; /* access unreadable area */
- goto do_fault;
- }
- }
-
- if (desc & UC32_PAGETABLE_WRITE) {
- *prot |= PAGE_WRITE;
- } else {
- if (is_user && (access_type == 1)) {
- code = 0x12; /* access unwritable area */
- goto do_fault;
- }
- }
-
- if (desc & UC32_PAGETABLE_EXEC) {
- *prot |= PAGE_EXEC;
- } else {
- if (is_user && (access_type == 2)) {
- code = 0x13; /* access unexecutable area */
- goto do_fault;
- }
- }
-
-do_fault:
- return code;
-}
-
-bool uc32_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
- MMUAccessType access_type, int mmu_idx,
- bool probe, uintptr_t retaddr)
-{
- UniCore32CPU *cpu = UNICORE32_CPU(cs);
- CPUUniCore32State *env = &cpu->env;
- uint32_t phys_addr;
- target_ulong page_size;
- int prot;
- int ret, is_user;
-
- ret = 1;
- is_user = mmu_idx == MMU_USER_IDX;
-
- if ((env->cp0.c1_sys & 1) == 0) {
- /* MMU disabled. */
- phys_addr = address;
- prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
- page_size = TARGET_PAGE_SIZE;
- ret = 0;
- } else {
- if ((address & (1 << 31)) || (is_user)) {
- ret = get_phys_addr_ucv2(env, address, access_type, is_user,
- &phys_addr, &prot, &page_size);
- if (is_user) {
- DPRINTF("user space access: ret %x, address %" VADDR_PRIx ", "
- "access_type %x, phys_addr %x, prot %x\n",
- ret, address, access_type, phys_addr, prot);
- }
- } else {
- /*IO memory */
- phys_addr = address | (1 << 31);
- prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
- page_size = TARGET_PAGE_SIZE;
- ret = 0;
- }
- }
-
- if (ret == 0) {
- /* Map a single page. */
- phys_addr &= TARGET_PAGE_MASK;
- address &= TARGET_PAGE_MASK;
- tlb_set_page(cs, address, phys_addr, prot, mmu_idx, page_size);
- return true;
- }
-
- if (probe) {
- return false;
- }
-
- env->cp0.c3_faultstatus = ret;
- env->cp0.c4_faultaddr = address;
- if (access_type == 2) {
- cs->exception_index = UC32_EXCP_ITRAP;
- } else {
- cs->exception_index = UC32_EXCP_DTRAP;
- }
- cpu_loop_exit_restore(cs, retaddr);
-}
-
-hwaddr uc32_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
-{
- error_report("function uc32_cpu_get_phys_page_debug not "
- "implemented, aborting");
- return -1;
-}
diff --git a/target/unicore32/translate.c b/target/unicore32/translate.c
deleted file mode 100644
index 370709c9ea..0000000000
--- a/target/unicore32/translate.c
+++ /dev/null
@@ -1,2083 +0,0 @@
-/*
- * UniCore32 translation
- *
- * Copyright (C) 2010-2012 Guan Xuetao
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation, or (at your option) any
- * later version. See the COPYING file in the top-level directory.
- */
-#include "qemu/osdep.h"
-
-#include "cpu.h"
-#include "disas/disas.h"
-#include "exec/exec-all.h"
-#include "tcg/tcg-op.h"
-#include "qemu/log.h"
-#include "exec/cpu_ldst.h"
-#include "exec/translator.h"
-#include "qemu/qemu-print.h"
-
-#include "exec/helper-proto.h"
-#include "exec/helper-gen.h"
-
-#include "trace-tcg.h"
-#include "exec/log.h"
-
-
-/* internal defines */
-typedef struct DisasContext {
- target_ulong pc;
- int is_jmp;
- /* Nonzero if this instruction has been conditionally skipped. */
- int condjmp;
- /* The label that will be jumped to when the instruction is skipped. */
- TCGLabel *condlabel;
- TranslationBlock *tb;
- int singlestep_enabled;
-#ifndef CONFIG_USER_ONLY
- int user;
-#endif
-} DisasContext;
-
-#ifndef CONFIG_USER_ONLY
-#define IS_USER(s) (s->user)
-#else
-#define IS_USER(s) 1
-#endif
-
-/* is_jmp field values */
-#define DISAS_JUMP DISAS_TARGET_0 /* only pc was modified dynamically */
-#define DISAS_UPDATE DISAS_TARGET_1 /* cpu state was modified dynamically */
-#define DISAS_TB_JUMP DISAS_TARGET_2 /* only pc was modified statically */
-/* These instructions trap after executing, so defer them until after the
- conditional executions state has been updated. */
-#define DISAS_SYSCALL DISAS_TARGET_3
-
-static TCGv_i32 cpu_R[32];
-
-/* FIXME: These should be removed. */
-static TCGv cpu_F0s, cpu_F1s;
-static TCGv_i64 cpu_F0d, cpu_F1d;
-
-#include "exec/gen-icount.h"
-
-static const char *regnames[] = {
- "r00", "r01", "r02", "r03", "r04", "r05", "r06", "r07",
- "r08", "r09", "r10", "r11", "r12", "r13", "r14", "r15",
- "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
- "r24", "r25", "r26", "r27", "r28", "r29", "r30", "pc" };
-
-/* initialize TCG globals. */
-void uc32_translate_init(void)
-{
- int i;
-
- for (i = 0; i < 32; i++) {
- cpu_R[i] = tcg_global_mem_new_i32(cpu_env,
- offsetof(CPUUniCore32State, regs[i]), regnames[i]);
- }
-}
-
-static int num_temps;
-
-/* Allocate a temporary variable. */
-static TCGv_i32 new_tmp(void)
-{
- num_temps++;
- return tcg_temp_new_i32();
-}
-
-/* Release a temporary variable. */
-static void dead_tmp(TCGv tmp)
-{
- tcg_temp_free(tmp);
- num_temps--;
-}
-
-static inline TCGv load_cpu_offset(int offset)
-{
- TCGv tmp = new_tmp();
- tcg_gen_ld_i32(tmp, cpu_env, offset);
- return tmp;
-}
-
-#define load_cpu_field(name) load_cpu_offset(offsetof(CPUUniCore32State, name))
-
-static inline void store_cpu_offset(TCGv var, int offset)
-{
- tcg_gen_st_i32(var, cpu_env, offset);
- dead_tmp(var);
-}
-
-#define store_cpu_field(var, name) \
- store_cpu_offset(var, offsetof(CPUUniCore32State, name))
-
-/* Set a variable to the value of a CPU register. */
-static void load_reg_var(DisasContext *s, TCGv var, int reg)
-{
- if (reg == 31) {
- uint32_t addr;
- /* normaly, since we updated PC */
- addr = (long)s->pc;
- tcg_gen_movi_i32(var, addr);
- } else {
- tcg_gen_mov_i32(var, cpu_R[reg]);
- }
-}
-
-/* Create a new temporary and set it to the value of a CPU register. */
-static inline TCGv load_reg(DisasContext *s, int reg)
-{
- TCGv tmp = new_tmp();
- load_reg_var(s, tmp, reg);
- return tmp;
-}
-
-/* Set a CPU register. The source must be a temporary and will be
- marked as dead. */
-static void store_reg(DisasContext *s, int reg, TCGv var)
-{
- if (reg == 31) {
- tcg_gen_andi_i32(var, var, ~3);
- s->is_jmp = DISAS_JUMP;
- }
- tcg_gen_mov_i32(cpu_R[reg], var);
- dead_tmp(var);
-}
-
-/* Value extensions. */
-#define gen_uxtb(var) tcg_gen_ext8u_i32(var, var)
-#define gen_uxth(var) tcg_gen_ext16u_i32(var, var)
-#define gen_sxtb(var) tcg_gen_ext8s_i32(var, var)
-#define gen_sxth(var) tcg_gen_ext16s_i32(var, var)
-
-#define UCOP_REG_M (((insn) >> 0) & 0x1f)
-#define UCOP_REG_N (((insn) >> 19) & 0x1f)
-#define UCOP_REG_D (((insn) >> 14) & 0x1f)
-#define UCOP_REG_S (((insn) >> 9) & 0x1f)
-#define UCOP_REG_LO (((insn) >> 14) & 0x1f)
-#define UCOP_REG_HI (((insn) >> 9) & 0x1f)
-#define UCOP_SH_OP (((insn) >> 6) & 0x03)
-#define UCOP_SH_IM (((insn) >> 9) & 0x1f)
-#define UCOP_OPCODES (((insn) >> 25) & 0x0f)
-#define UCOP_IMM_9 (((insn) >> 0) & 0x1ff)
-#define UCOP_IMM10 (((insn) >> 0) & 0x3ff)
-#define UCOP_IMM14 (((insn) >> 0) & 0x3fff)
-#define UCOP_COND (((insn) >> 25) & 0x0f)
-#define UCOP_CMOV_COND (((insn) >> 19) & 0x0f)
-#define UCOP_CPNUM (((insn) >> 10) & 0x0f)
-#define UCOP_UCF64_FMT (((insn) >> 24) & 0x03)
-#define UCOP_UCF64_FUNC (((insn) >> 6) & 0x0f)
-#define UCOP_UCF64_COND (((insn) >> 6) & 0x0f)
-
-#define UCOP_SET(i) ((insn) & (1 << (i)))
-#define UCOP_SET_P UCOP_SET(28)
-#define UCOP_SET_U UCOP_SET(27)
-#define UCOP_SET_B UCOP_SET(26)
-#define UCOP_SET_W UCOP_SET(25)
-#define UCOP_SET_L UCOP_SET(24)
-#define UCOP_SET_S UCOP_SET(24)
-
-#define ILLEGAL cpu_abort(env_cpu(env), \
- "Illegal UniCore32 instruction %x at line %d!", \
- insn, __LINE__)
-
-#ifndef CONFIG_USER_ONLY
-static void disas_cp0_insn(CPUUniCore32State *env, DisasContext *s,
- uint32_t insn)
-{
- TCGv tmp, tmp2, tmp3;
- if ((insn & 0xfe000000) == 0xe0000000) {
- tmp2 = new_tmp();
- tmp3 = new_tmp();
- tcg_gen_movi_i32(tmp2, UCOP_REG_N);
- tcg_gen_movi_i32(tmp3, UCOP_IMM10);
- if (UCOP_SET_L) {
- tmp = new_tmp();
- gen_helper_cp0_get(tmp, cpu_env, tmp2, tmp3);
- store_reg(s, UCOP_REG_D, tmp);
- } else {
- tmp = load_reg(s, UCOP_REG_D);
- gen_helper_cp0_set(cpu_env, tmp, tmp2, tmp3);
- dead_tmp(tmp);
- }
- dead_tmp(tmp2);
- dead_tmp(tmp3);
- return;
- }
- ILLEGAL;
-}
-
-static void disas_ocd_insn(CPUUniCore32State *env, DisasContext *s,
- uint32_t insn)
-{
- TCGv tmp;
-
- if ((insn & 0xff003fff) == 0xe1000400) {
- /*
- * movc rd, pp.nn, #imm9
- * rd: UCOP_REG_D
- * nn: UCOP_REG_N (must be 0)
- * imm9: 0
- */
- if (UCOP_REG_N == 0) {
- tmp = new_tmp();
- tcg_gen_movi_i32(tmp, 0);
- store_reg(s, UCOP_REG_D, tmp);
- return;
- } else {
- ILLEGAL;
- }
- }
- if ((insn & 0xff003fff) == 0xe0000401) {
- /*
- * movc pp.nn, rn, #imm9
- * rn: UCOP_REG_D
- * nn: UCOP_REG_N (must be 1)
- * imm9: 1
- */
- if (UCOP_REG_N == 1) {
- tmp = load_reg(s, UCOP_REG_D);
- gen_helper_cp1_putc(tmp);
- dead_tmp(tmp);
- return;
- } else {
- ILLEGAL;
- }
- }
- ILLEGAL;
-}
-#endif
-
-static inline void gen_set_asr(TCGv var, uint32_t mask)
-{
- TCGv tmp_mask = tcg_const_i32(mask);
- gen_helper_asr_write(cpu_env, var, tmp_mask);
- tcg_temp_free_i32(tmp_mask);
-}
-/* Set NZCV flags from the high 4 bits of var. */
-#define gen_set_nzcv(var) gen_set_asr(var, ASR_NZCV)
-
-static void gen_exception(int excp)
-{
- TCGv tmp = new_tmp();
- tcg_gen_movi_i32(tmp, excp);
- gen_helper_exception(cpu_env, tmp);
- dead_tmp(tmp);
-}
-
-#define gen_set_CF(var) tcg_gen_st_i32(var, cpu_env, offsetof(CPUUniCore32State, CF))
-
-/* Set CF to the top bit of var. */
-static void gen_set_CF_bit31(TCGv var)
-{
- TCGv tmp = new_tmp();
- tcg_gen_shri_i32(tmp, var, 31);
- gen_set_CF(tmp);
- dead_tmp(tmp);
-}
-
-/* Set N and Z flags from var. */
-static inline void gen_logic_CC(TCGv var)
-{
- tcg_gen_st_i32(var, cpu_env, offsetof(CPUUniCore32State, NF));
- tcg_gen_st_i32(var, cpu_env, offsetof(CPUUniCore32State, ZF));
-}
-
-/* dest = T0 + T1 + CF. */
-static void gen_add_carry(TCGv dest, TCGv t0, TCGv t1)
-{
- TCGv tmp;
- tcg_gen_add_i32(dest, t0, t1);
- tmp = load_cpu_field(CF);
- tcg_gen_add_i32(dest, dest, tmp);
- dead_tmp(tmp);
-}
-
-/* dest = T0 - T1 + CF - 1. */
-static void gen_sub_carry(TCGv dest, TCGv t0, TCGv t1)
-{
- TCGv tmp;
- tcg_gen_sub_i32(dest, t0, t1);
- tmp = load_cpu_field(CF);
- tcg_gen_add_i32(dest, dest, tmp);
- tcg_gen_subi_i32(dest, dest, 1);
- dead_tmp(tmp);
-}
-
-static void shifter_out_im(TCGv var, int shift)
-{
- TCGv tmp = new_tmp();
- if (shift == 0) {
- tcg_gen_andi_i32(tmp, var, 1);
- } else {
- tcg_gen_shri_i32(tmp, var, shift);
- if (shift != 31) {
- tcg_gen_andi_i32(tmp, tmp, 1);
- }
- }
- gen_set_CF(tmp);
- dead_tmp(tmp);
-}
-
-/* Shift by immediate. Includes special handling for shift == 0. */
-static inline void gen_uc32_shift_im(TCGv var, int shiftop, int shift,
- int flags)
-{
- switch (shiftop) {
- case 0: /* LSL */
- if (shift != 0) {
- if (flags) {
- shifter_out_im(var, 32 - shift);
- }
- tcg_gen_shli_i32(var, var, shift);
- }
- break;
- case 1: /* LSR */
- if (shift == 0) {
- if (flags) {
- tcg_gen_shri_i32(var, var, 31);
- gen_set_CF(var);
- }
- tcg_gen_movi_i32(var, 0);
- } else {
- if (flags) {
- shifter_out_im(var, shift - 1);
- }
- tcg_gen_shri_i32(var, var, shift);
- }
- break;
- case 2: /* ASR */
- if (shift == 0) {
- shift = 32;
- }
- if (flags) {
- shifter_out_im(var, shift - 1);
- }
- if (shift == 32) {
- shift = 31;
- }
- tcg_gen_sari_i32(var, var, shift);
- break;
- case 3: /* ROR/RRX */
- if (shift != 0) {
- if (flags) {
- shifter_out_im(var, shift - 1);
- }
- tcg_gen_rotri_i32(var, var, shift); break;
- } else {
- TCGv tmp = load_cpu_field(CF);
- if (flags) {
- shifter_out_im(var, 0);
- }
- tcg_gen_shri_i32(var, var, 1);
- tcg_gen_shli_i32(tmp, tmp, 31);
- tcg_gen_or_i32(var, var, tmp);
- dead_tmp(tmp);
- }
- }
-};
-
-static inline void gen_uc32_shift_reg(TCGv var, int shiftop,
- TCGv shift, int flags)
-{
- if (flags) {
- switch (shiftop) {
- case 0:
- gen_helper_shl_cc(var, cpu_env, var, shift);
- break;
- case 1:
- gen_helper_shr_cc(var, cpu_env, var, shift);
- break;
- case 2:
- gen_helper_sar_cc(var, cpu_env, var, shift);
- break;
- case 3:
- gen_helper_ror_cc(var, cpu_env, var, shift);
- break;
- }
- } else {
- switch (shiftop) {
- case 0:
- gen_helper_shl(var, var, shift);
- break;
- case 1:
- gen_helper_shr(var, var, shift);
- break;
- case 2:
- gen_helper_sar(var, var, shift);
- break;
- case 3:
- tcg_gen_andi_i32(shift, shift, 0x1f);
- tcg_gen_rotr_i32(var, var, shift);
- break;
- }
- }
- dead_tmp(shift);
-}
-
-static void gen_test_cc(int cc, TCGLabel *label)
-{
- TCGv tmp;
- TCGv tmp2;
- TCGLabel *inv;
-
- switch (cc) {
- case 0: /* eq: Z */
- tmp = load_cpu_field(ZF);
- tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, label);
- break;
- case 1: /* ne: !Z */
- tmp = load_cpu_field(ZF);
- tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, label);
- break;
- case 2: /* cs: C */
- tmp = load_cpu_field(CF);
- tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, label);
- break;
- case 3: /* cc: !C */
- tmp = load_cpu_field(CF);
- tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, label);
- break;
- case 4: /* mi: N */
- tmp = load_cpu_field(NF);
- tcg_gen_brcondi_i32(TCG_COND_LT, tmp, 0, label);
- break;
- case 5: /* pl: !N */
- tmp = load_cpu_field(NF);
- tcg_gen_brcondi_i32(TCG_COND_GE, tmp, 0, label);
- break;
- case 6: /* vs: V */
- tmp = load_cpu_field(VF);
- tcg_gen_brcondi_i32(TCG_COND_LT, tmp, 0, label);
- break;
- case 7: /* vc: !V */
- tmp = load_cpu_field(VF);
- tcg_gen_brcondi_i32(TCG_COND_GE, tmp, 0, label);
- break;
- case 8: /* hi: C && !Z */
- inv = gen_new_label();
- tmp = load_cpu_field(CF);
- tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, inv);
- dead_tmp(tmp);
- tmp = load_cpu_field(ZF);
- tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, label);
- gen_set_label(inv);
- break;
- case 9: /* ls: !C || Z */
- tmp = load_cpu_field(CF);
- tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, label);
- dead_tmp(tmp);
- tmp = load_cpu_field(ZF);
- tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, label);
- break;
- case 10: /* ge: N == V -> N ^ V == 0 */
- tmp = load_cpu_field(VF);
- tmp2 = load_cpu_field(NF);
- tcg_gen_xor_i32(tmp, tmp, tmp2);
- dead_tmp(tmp2);
- tcg_gen_brcondi_i32(TCG_COND_GE, tmp, 0, label);
- break;
- case 11: /* lt: N != V -> N ^ V != 0 */
- tmp = load_cpu_field(VF);
- tmp2 = load_cpu_field(NF);
- tcg_gen_xor_i32(tmp, tmp, tmp2);
- dead_tmp(tmp2);
- tcg_gen_brcondi_i32(TCG_COND_LT, tmp, 0, label);
- break;
- case 12: /* gt: !Z && N == V */
- inv = gen_new_label();
- tmp = load_cpu_field(ZF);
- tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, inv);
- dead_tmp(tmp);
- tmp = load_cpu_field(VF);
- tmp2 = load_cpu_field(NF);
- tcg_gen_xor_i32(tmp, tmp, tmp2);
- dead_tmp(tmp2);
- tcg_gen_brcondi_i32(TCG_COND_GE, tmp, 0, label);
- gen_set_label(inv);
- break;
- case 13: /* le: Z || N != V */
- tmp = load_cpu_field(ZF);
- tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, label);
- dead_tmp(tmp);
- tmp = load_cpu_field(VF);
- tmp2 = load_cpu_field(NF);
- tcg_gen_xor_i32(tmp, tmp, tmp2);
- dead_tmp(tmp2);
- tcg_gen_brcondi_i32(TCG_COND_LT, tmp, 0, label);
- break;
- default:
- fprintf(stderr, "Bad condition code 0x%x\n", cc);
- abort();
- }
- dead_tmp(tmp);
-}
-
-static const uint8_t table_logic_cc[16] = {
- 1, /* and */ 1, /* xor */ 0, /* sub */ 0, /* rsb */
- 0, /* add */ 0, /* adc */ 0, /* sbc */ 0, /* rsc */
- 1, /* andl */ 1, /* xorl */ 0, /* cmp */ 0, /* cmn */
- 1, /* orr */ 1, /* mov */ 1, /* bic */ 1, /* mvn */
-};
-
-/* Set PC state from an immediate address. */
-static inline void gen_bx_im(DisasContext *s, uint32_t addr)
-{
- s->is_jmp = DISAS_UPDATE;
- tcg_gen_movi_i32(cpu_R[31], addr & ~3);
-}
-
-/* Set PC state from var. var is marked as dead. */
-static inline void gen_bx(DisasContext *s, TCGv var)
-{
- s->is_jmp = DISAS_UPDATE;
- tcg_gen_andi_i32(cpu_R[31], var, ~3);
- dead_tmp(var);
-}
-
-static inline void store_reg_bx(DisasContext *s, int reg, TCGv var)
-{
- store_reg(s, reg, var);
-}
-
-static inline TCGv gen_ld8s(TCGv addr, int index)
-{
- TCGv tmp = new_tmp();
- tcg_gen_qemu_ld8s(tmp, addr, index);
- return tmp;
-}
-
-static inline TCGv gen_ld8u(TCGv addr, int index)
-{
- TCGv tmp = new_tmp();
- tcg_gen_qemu_ld8u(tmp, addr, index);
- return tmp;
-}
-
-static inline TCGv gen_ld16s(TCGv addr, int index)
-{
- TCGv tmp = new_tmp();
- tcg_gen_qemu_ld16s(tmp, addr, index);
- return tmp;
-}
-
-static inline TCGv gen_ld16u(TCGv addr, int index)
-{
- TCGv tmp = new_tmp();
- tcg_gen_qemu_ld16u(tmp, addr, index);
- return tmp;
-}
-
-static inline TCGv gen_ld32(TCGv addr, int index)
-{
- TCGv tmp = new_tmp();
- tcg_gen_qemu_ld32u(tmp, addr, index);
- return tmp;
-}
-
-static inline void gen_st8(TCGv val, TCGv addr, int index)
-{
- tcg_gen_qemu_st8(val, addr, index);
- dead_tmp(val);
-}
-
-static inline void gen_st16(TCGv val, TCGv addr, int index)
-{
- tcg_gen_qemu_st16(val, addr, index);
- dead_tmp(val);
-}
-
-static inline void gen_st32(TCGv val, TCGv addr, int index)
-{
- tcg_gen_qemu_st32(val, addr, index);
- dead_tmp(val);
-}
-
-static inline void gen_set_pc_im(uint32_t val)
-{
- tcg_gen_movi_i32(cpu_R[31], val);
-}
-
-/* Force a TB lookup after an instruction that changes the CPU state. */
-static inline void gen_lookup_tb(DisasContext *s)
-{
- tcg_gen_movi_i32(cpu_R[31], s->pc & ~1);
- s->is_jmp = DISAS_UPDATE;
-}
-
-static inline void gen_add_data_offset(DisasContext *s, unsigned int insn,
- TCGv var)
-{
- int val;
- TCGv offset;
-
- if (UCOP_SET(29)) {
- /* immediate */
- val = UCOP_IMM14;
- if (!UCOP_SET_U) {
- val = -val;
- }
- if (val != 0) {
- tcg_gen_addi_i32(var, var, val);
- }
- } else {
- /* shift/register */
- offset = load_reg(s, UCOP_REG_M);
- gen_uc32_shift_im(offset, UCOP_SH_OP, UCOP_SH_IM, 0);
- if (!UCOP_SET_U) {
- tcg_gen_sub_i32(var, var, offset);
- } else {
- tcg_gen_add_i32(var, var, offset);
- }
- dead_tmp(offset);
- }
-}
-
-static inline void gen_add_datah_offset(DisasContext *s, unsigned int insn,
- TCGv var)
-{
- int val;
- TCGv offset;
-
- if (UCOP_SET(26)) {
- /* immediate */
- val = (insn & 0x1f) | ((insn >> 4) & 0x3e0);
- if (!UCOP_SET_U) {
- val = -val;
- }
- if (val != 0) {
- tcg_gen_addi_i32(var, var, val);
- }
- } else {
- /* register */
- offset = load_reg(s, UCOP_REG_M);
- if (!UCOP_SET_U) {
- tcg_gen_sub_i32(var, var, offset);
- } else {
- tcg_gen_add_i32(var, var, offset);
- }
- dead_tmp(offset);
- }
-}
-
-static inline long ucf64_reg_offset(int reg)
-{
- if (reg & 1) {
- return offsetof(CPUUniCore32State, ucf64.regs[reg >> 1])
- + offsetof(CPU_DoubleU, l.upper);
- } else {
- return offsetof(CPUUniCore32State, ucf64.regs[reg >> 1])
- + offsetof(CPU_DoubleU, l.lower);
- }
-}
-
-#define ucf64_gen_ld32(reg) load_cpu_offset(ucf64_reg_offset(reg))
-#define ucf64_gen_st32(var, reg) store_cpu_offset(var, ucf64_reg_offset(reg))
-
-/* UniCore-F64 single load/store I_offset */
-static void do_ucf64_ldst_i(CPUUniCore32State *env, DisasContext *s, uint32_t insn)
-{
- int offset;
- TCGv tmp;
- TCGv addr;
-
- addr = load_reg(s, UCOP_REG_N);
- if (!UCOP_SET_P && !UCOP_SET_W) {
- ILLEGAL;
- }
-
- if (UCOP_SET_P) {
- offset = UCOP_IMM10 << 2;
- if (!UCOP_SET_U) {
- offset = -offset;
- }
- if (offset != 0) {
- tcg_gen_addi_i32(addr, addr, offset);
- }
- }
-
- if (UCOP_SET_L) { /* load */
- tmp = gen_ld32(addr, IS_USER(s));
- ucf64_gen_st32(tmp, UCOP_REG_D);
- } else { /* store */
- tmp = ucf64_gen_ld32(UCOP_REG_D);
- gen_st32(tmp, addr, IS_USER(s));
- }
-
- if (!UCOP_SET_P) {
- offset = UCOP_IMM10 << 2;
- if (!UCOP_SET_U) {
- offset = -offset;
- }
- if (offset != 0) {
- tcg_gen_addi_i32(addr, addr, offset);
- }
- }
- if (UCOP_SET_W) {
- store_reg(s, UCOP_REG_N, addr);
- } else {
- dead_tmp(addr);
- }
-}
-
-/* UniCore-F64 load/store multiple words */
-static void do_ucf64_ldst_m(CPUUniCore32State *env, DisasContext *s, uint32_t insn)
-{
- unsigned int i;
- int j, n, freg;
- TCGv tmp;
- TCGv addr;
-
- if (UCOP_REG_D != 0) {
- ILLEGAL;
- }
- if (UCOP_REG_N == 31) {
- ILLEGAL;
- }
- if ((insn << 24) == 0) {
- ILLEGAL;
- }
-
- addr = load_reg(s, UCOP_REG_N);
-
- n = 0;
- for (i = 0; i < 8; i++) {
- if (UCOP_SET(i)) {
- n++;
- }
- }
-
- if (UCOP_SET_U) {
- if (UCOP_SET_P) { /* pre increment */
- tcg_gen_addi_i32(addr, addr, 4);
- } /* unnecessary to do anything when post increment */
- } else {
- if (UCOP_SET_P) { /* pre decrement */
- tcg_gen_addi_i32(addr, addr, -(n * 4));
- } else { /* post decrement */
- if (n != 1) {
- tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
- }
- }
- }
-
- freg = ((insn >> 8) & 3) << 3; /* freg should be 0, 8, 16, 24 */
-
- for (i = 0, j = 0; i < 8; i++, freg++) {
- if (!UCOP_SET(i)) {
- continue;
- }
-
- if (UCOP_SET_L) { /* load */
- tmp = gen_ld32(addr, IS_USER(s));
- ucf64_gen_st32(tmp, freg);
- } else { /* store */
- tmp = ucf64_gen_ld32(freg);
- gen_st32(tmp, addr, IS_USER(s));
- }
-
- j++;
- /* unnecessary to add after the last transfer */
- if (j != n) {
- tcg_gen_addi_i32(addr, addr, 4);
- }
- }
-
- if (UCOP_SET_W) { /* write back */
- if (UCOP_SET_U) {
- if (!UCOP_SET_P) { /* post increment */
- tcg_gen_addi_i32(addr, addr, 4);
- } /* unnecessary to do anything when pre increment */
- } else {
- if (UCOP_SET_P) {
- /* pre decrement */
- if (n != 1) {
- tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
- }
- } else {
- /* post decrement */
- tcg_gen_addi_i32(addr, addr, -(n * 4));
- }
- }
- store_reg(s, UCOP_REG_N, addr);
- } else {
- dead_tmp(addr);
- }
-}
-
-/* UniCore-F64 mrc/mcr */
-static void do_ucf64_trans(CPUUniCore32State *env, DisasContext *s, uint32_t insn)
-{
- TCGv tmp;
-
- if ((insn & 0xfe0003ff) == 0xe2000000) {
- /* control register */
- if ((UCOP_REG_N != UC32_UCF64_FPSCR) || (UCOP_REG_D == 31)) {
- ILLEGAL;
- }
- if (UCOP_SET(24)) {
- /* CFF */
- tmp = new_tmp();
- gen_helper_ucf64_get_fpscr(tmp, cpu_env);
- store_reg(s, UCOP_REG_D, tmp);
- } else {
- /* CTF */
- tmp = load_reg(s, UCOP_REG_D);
- gen_helper_ucf64_set_fpscr(cpu_env, tmp);
- dead_tmp(tmp);
- gen_lookup_tb(s);
- }
- return;
- }
- if ((insn & 0xfe0003ff) == 0xe0000000) {
- /* general register */
- if (UCOP_REG_D == 31) {
- ILLEGAL;
- }
- if (UCOP_SET(24)) { /* MFF */
- tmp = ucf64_gen_ld32(UCOP_REG_N);
- store_reg(s, UCOP_REG_D, tmp);
- } else { /* MTF */
- tmp = load_reg(s, UCOP_REG_D);
- ucf64_gen_st32(tmp, UCOP_REG_N);
- }
- return;
- }
- if ((insn & 0xfb000000) == 0xe9000000) {
- /* MFFC */
- if (UCOP_REG_D != 31) {
- ILLEGAL;
- }
- if (UCOP_UCF64_COND & 0x8) {
- ILLEGAL;
- }
-
- tmp = new_tmp();
- tcg_gen_movi_i32(tmp, UCOP_UCF64_COND);
- if (UCOP_SET(26)) {
- tcg_gen_ld_i64(cpu_F0d, cpu_env, ucf64_reg_offset(UCOP_REG_N));
- tcg_gen_ld_i64(cpu_F1d, cpu_env, ucf64_reg_offset(UCOP_REG_M));
- gen_helper_ucf64_cmpd(cpu_F0d, cpu_F1d, tmp, cpu_env);
- } else {
- tcg_gen_ld_i32(cpu_F0s, cpu_env, ucf64_reg_offset(UCOP_REG_N));
- tcg_gen_ld_i32(cpu_F1s, cpu_env, ucf64_reg_offset(UCOP_REG_M));
- gen_helper_ucf64_cmps(cpu_F0s, cpu_F1s, tmp, cpu_env);
- }
- dead_tmp(tmp);
- return;
- }
- ILLEGAL;
-}
-
-/* UniCore-F64 convert instructions */
-static void do_ucf64_fcvt(CPUUniCore32State *env, DisasContext *s, uint32_t insn)
-{
- if (UCOP_UCF64_FMT == 3) {
- ILLEGAL;
- }
- if (UCOP_REG_N != 0) {
- ILLEGAL;
- }
- switch (UCOP_UCF64_FUNC) {
- case 0: /* cvt.s */
- switch (UCOP_UCF64_FMT) {
- case 1 /* d */:
- tcg_gen_ld_i64(cpu_F0d, cpu_env, ucf64_reg_offset(UCOP_REG_M));
- gen_helper_ucf64_df2sf(cpu_F0s, cpu_F0d, cpu_env);
- tcg_gen_st_i32(cpu_F0s, cpu_env, ucf64_reg_offset(UCOP_REG_D));
- break;
- case 2 /* w */:
- tcg_gen_ld_i32(cpu_F0s, cpu_env, ucf64_reg_offset(UCOP_REG_M));
- gen_helper_ucf64_si2sf(cpu_F0s, cpu_F0s, cpu_env);
- tcg_gen_st_i32(cpu_F0s, cpu_env, ucf64_reg_offset(UCOP_REG_D));
- break;
- default /* s */:
- ILLEGAL;
- break;
- }
- break;
- case 1: /* cvt.d */
- switch (UCOP_UCF64_FMT) {
- case 0 /* s */:
- tcg_gen_ld_i32(cpu_F0s, cpu_env, ucf64_reg_offset(UCOP_REG_M));
- gen_helper_ucf64_sf2df(cpu_F0d, cpu_F0s, cpu_env);
- tcg_gen_st_i64(cpu_F0d, cpu_env, ucf64_reg_offset(UCOP_REG_D));
- break;
- case 2 /* w */:
- tcg_gen_ld_i32(cpu_F0s, cpu_env, ucf64_reg_offset(UCOP_REG_M));
- gen_helper_ucf64_si2df(cpu_F0d, cpu_F0s, cpu_env);
- tcg_gen_st_i64(cpu_F0d, cpu_env, ucf64_reg_offset(UCOP_REG_D));
- break;
- default /* d */:
- ILLEGAL;
- break;
- }
- break;
- case 4: /* cvt.w */
- switch (UCOP_UCF64_FMT) {
- case 0 /* s */:
- tcg_gen_ld_i32(cpu_F0s, cpu_env, ucf64_reg_offset(UCOP_REG_M));
- gen_helper_ucf64_sf2si(cpu_F0s, cpu_F0s, cpu_env);
- tcg_gen_st_i32(cpu_F0s, cpu_env, ucf64_reg_offset(UCOP_REG_D));
- break;
- case 1 /* d */:
- tcg_gen_ld_i64(cpu_F0d, cpu_env, ucf64_reg_offset(UCOP_REG_M));
- gen_helper_ucf64_df2si(cpu_F0s, cpu_F0d, cpu_env);
- tcg_gen_st_i32(cpu_F0s, cpu_env, ucf64_reg_offset(UCOP_REG_D));
- break;
- default /* w */:
- ILLEGAL;
- break;
- }
- break;
- default:
- ILLEGAL;
- }
-}
-
-/* UniCore-F64 compare instructions */
-static void do_ucf64_fcmp(CPUUniCore32State *env, DisasContext *s, uint32_t insn)
-{
- if (UCOP_SET(25)) {
- ILLEGAL;
- }
- if (UCOP_REG_D != 0) {
- ILLEGAL;
- }
-
- ILLEGAL; /* TODO */
- if (UCOP_SET(24)) {
- tcg_gen_ld_i64(cpu_F0d, cpu_env, ucf64_reg_offset(UCOP_REG_N));
- tcg_gen_ld_i64(cpu_F1d, cpu_env, ucf64_reg_offset(UCOP_REG_M));
- /* gen_helper_ucf64_cmpd(cpu_F0d, cpu_F1d, cpu_env); */
- } else {
- tcg_gen_ld_i32(cpu_F0s, cpu_env, ucf64_reg_offset(UCOP_REG_N));
- tcg_gen_ld_i32(cpu_F1s, cpu_env, ucf64_reg_offset(UCOP_REG_M));
- /* gen_helper_ucf64_cmps(cpu_F0s, cpu_F1s, cpu_env); */
- }
-}
-
-#define gen_helper_ucf64_movs(x, y) do { } while (0)
-#define gen_helper_ucf64_movd(x, y) do { } while (0)
-
-#define UCF64_OP1(name) do { \
- if (UCOP_REG_N != 0) { \
- ILLEGAL; \
- } \
- switch (UCOP_UCF64_FMT) { \
- case 0 /* s */: \
- tcg_gen_ld_i32(cpu_F0s, cpu_env, \
- ucf64_reg_offset(UCOP_REG_M)); \
- gen_helper_ucf64_##name##s(cpu_F0s, cpu_F0s); \
- tcg_gen_st_i32(cpu_F0s, cpu_env, \
- ucf64_reg_offset(UCOP_REG_D)); \
- break; \
- case 1 /* d */: \
- tcg_gen_ld_i64(cpu_F0d, cpu_env, \
- ucf64_reg_offset(UCOP_REG_M)); \
- gen_helper_ucf64_##name##d(cpu_F0d, cpu_F0d); \
- tcg_gen_st_i64(cpu_F0d, cpu_env, \
- ucf64_reg_offset(UCOP_REG_D)); \
- break; \
- case 2 /* w */: \
- ILLEGAL; \
- break; \
- } \
- } while (0)
-
-#define UCF64_OP2(name) do { \
- switch (UCOP_UCF64_FMT) { \
- case 0 /* s */: \
- tcg_gen_ld_i32(cpu_F0s, cpu_env, \
- ucf64_reg_offset(UCOP_REG_N)); \
- tcg_gen_ld_i32(cpu_F1s, cpu_env, \
- ucf64_reg_offset(UCOP_REG_M)); \
- gen_helper_ucf64_##name##s(cpu_F0s, \
- cpu_F0s, cpu_F1s, cpu_env); \
- tcg_gen_st_i32(cpu_F0s, cpu_env, \
- ucf64_reg_offset(UCOP_REG_D)); \
- break; \
- case 1 /* d */: \
- tcg_gen_ld_i64(cpu_F0d, cpu_env, \
- ucf64_reg_offset(UCOP_REG_N)); \
- tcg_gen_ld_i64(cpu_F1d, cpu_env, \
- ucf64_reg_offset(UCOP_REG_M)); \
- gen_helper_ucf64_##name##d(cpu_F0d, \
- cpu_F0d, cpu_F1d, cpu_env); \
- tcg_gen_st_i64(cpu_F0d, cpu_env, \
- ucf64_reg_offset(UCOP_REG_D)); \
- break; \
- case 2 /* w */: \
- ILLEGAL; \
- break; \
- } \
- } while (0)
-
-/* UniCore-F64 data processing */
-static void do_ucf64_datap(CPUUniCore32State *env, DisasContext *s, uint32_t insn)
-{
- if (UCOP_UCF64_FMT == 3) {
- ILLEGAL;
- }
- switch (UCOP_UCF64_FUNC) {
- case 0: /* add */
- UCF64_OP2(add);
- break;
- case 1: /* sub */
- UCF64_OP2(sub);
- break;
- case 2: /* mul */
- UCF64_OP2(mul);
- break;
- case 4: /* div */
- UCF64_OP2(div);
- break;
- case 5: /* abs */
- UCF64_OP1(abs);
- break;
- case 6: /* mov */
- UCF64_OP1(mov);
- break;
- case 7: /* neg */
- UCF64_OP1(neg);
- break;
- default:
- ILLEGAL;
- }
-}
-
-/* Disassemble an F64 instruction */
-static void disas_ucf64_insn(CPUUniCore32State *env, DisasContext *s, uint32_t insn)
-{
- if (!UCOP_SET(29)) {
- if (UCOP_SET(26)) {
- do_ucf64_ldst_m(env, s, insn);
- } else {
- do_ucf64_ldst_i(env, s, insn);
- }
- } else {
- if (UCOP_SET(5)) {
- switch ((insn >> 26) & 0x3) {
- case 0:
- do_ucf64_datap(env, s, insn);
- break;
- case 1:
- ILLEGAL;
- break;
- case 2:
- do_ucf64_fcvt(env, s, insn);
- break;
- case 3:
- do_ucf64_fcmp(env, s, insn);
- break;
- }
- } else {
- do_ucf64_trans(env, s, insn);
- }
- }
-}
-
-static inline bool use_goto_tb(DisasContext *s, uint32_t dest)
-{
-#ifndef CONFIG_USER_ONLY
- return (s->tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK);
-#else
- return true;
-#endif
-}
-
-static inline void gen_goto_tb(DisasContext *s, int n, uint32_t dest)
-{
- if (use_goto_tb(s, dest)) {
- tcg_gen_goto_tb(n);
- gen_set_pc_im(dest);
- tcg_gen_exit_tb(s->tb, n);
- } else {
- gen_set_pc_im(dest);
- tcg_gen_exit_tb(NULL, 0);
- }
-}
-
-static inline void gen_jmp(DisasContext *s, uint32_t dest)
-{
- if (unlikely(s->singlestep_enabled)) {
- /* An indirect jump so that we still trigger the debug exception. */
- gen_bx_im(s, dest);
- } else {
- gen_goto_tb(s, 0, dest);
- s->is_jmp = DISAS_TB_JUMP;
- }
-}
-
-/* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */
-static int gen_set_psr(DisasContext *s, uint32_t mask, int bsr, TCGv t0)
-{
- TCGv tmp;
- if (bsr) {
- /* ??? This is also undefined in system mode. */
- if (IS_USER(s)) {
- return 1;
- }
-
- tmp = load_cpu_field(bsr);
- tcg_gen_andi_i32(tmp, tmp, ~mask);
- tcg_gen_andi_i32(t0, t0, mask);
- tcg_gen_or_i32(tmp, tmp, t0);
- store_cpu_field(tmp, bsr);
- } else {
- gen_set_asr(t0, mask);
- }
- dead_tmp(t0);
- gen_lookup_tb(s);
- return 0;
-}
-
-/* Generate an old-style exception return. Marks pc as dead. */
-static void gen_exception_return(DisasContext *s, TCGv pc)
-{
- TCGv tmp;
- store_reg(s, 31, pc);
- tmp = load_cpu_field(bsr);
- gen_set_asr(tmp, 0xffffffff);
- dead_tmp(tmp);
- s->is_jmp = DISAS_UPDATE;
-}
-
-static void disas_coproc_insn(CPUUniCore32State *env, DisasContext *s,
- uint32_t insn)
-{
- switch (UCOP_CPNUM) {
-#ifndef CONFIG_USER_ONLY
- case 0:
- disas_cp0_insn(env, s, insn);
- break;
- case 1:
- disas_ocd_insn(env, s, insn);
- break;
-#endif
- case 2:
- disas_ucf64_insn(env, s, insn);
- break;
- default:
- /* Unknown coprocessor. */
- cpu_abort(env_cpu(env), "Unknown coprocessor!");
- }
-}
-
-/* data processing instructions */
-static void do_datap(CPUUniCore32State *env, DisasContext *s, uint32_t insn)
-{
- TCGv tmp;
- TCGv tmp2;
- int logic_cc;
-
- if (UCOP_OPCODES == 0x0f || UCOP_OPCODES == 0x0d) {
- if (UCOP_SET(23)) { /* CMOV instructions */
- if ((UCOP_CMOV_COND == 0xe) || (UCOP_CMOV_COND == 0xf)) {
- ILLEGAL;
- }
- /* if not always execute, we generate a conditional jump to
- next instruction */
- s->condlabel = gen_new_label();
- gen_test_cc(UCOP_CMOV_COND ^ 1, s->condlabel);
- s->condjmp = 1;
- }
- }
-
- logic_cc = table_logic_cc[UCOP_OPCODES] & (UCOP_SET_S >> 24);
-
- if (UCOP_SET(29)) {
- unsigned int val;
- /* immediate operand */
- val = UCOP_IMM_9;
- if (UCOP_SH_IM) {
- val = (val >> UCOP_SH_IM) | (val << (32 - UCOP_SH_IM));
- }
- tmp2 = new_tmp();
- tcg_gen_movi_i32(tmp2, val);
- if (logic_cc && UCOP_SH_IM) {
- gen_set_CF_bit31(tmp2);
- }
- } else {
- /* register */
- tmp2 = load_reg(s, UCOP_REG_M);
- if (UCOP_SET(5)) {
- tmp = load_reg(s, UCOP_REG_S);
- gen_uc32_shift_reg(tmp2, UCOP_SH_OP, tmp, logic_cc);
- } else {
- gen_uc32_shift_im(tmp2, UCOP_SH_OP, UCOP_SH_IM, logic_cc);
- }
- }
-
- if (UCOP_OPCODES != 0x0f && UCOP_OPCODES != 0x0d) {
- tmp = load_reg(s, UCOP_REG_N);
- } else {
- tmp = NULL;
- }
-
- switch (UCOP_OPCODES) {
- case 0x00:
- tcg_gen_and_i32(tmp, tmp, tmp2);
- if (logic_cc) {
- gen_logic_CC(tmp);
- }
- store_reg_bx(s, UCOP_REG_D, tmp);
- break;
- case 0x01:
- tcg_gen_xor_i32(tmp, tmp, tmp2);
- if (logic_cc) {
- gen_logic_CC(tmp);
- }
- store_reg_bx(s, UCOP_REG_D, tmp);
- break;
- case 0x02:
- if (UCOP_SET_S && UCOP_REG_D == 31) {
- /* SUBS r31, ... is used for exception return. */
- if (IS_USER(s)) {
- ILLEGAL;
- }
- gen_helper_sub_cc(tmp, cpu_env, tmp, tmp2);
- gen_exception_return(s, tmp);
- } else {
- if (UCOP_SET_S) {
- gen_helper_sub_cc(tmp, cpu_env, tmp, tmp2);
- } else {
- tcg_gen_sub_i32(tmp, tmp, tmp2);
- }
- store_reg_bx(s, UCOP_REG_D, tmp);
- }
- break;
- case 0x03:
- if (UCOP_SET_S) {
- gen_helper_sub_cc(tmp, cpu_env, tmp2, tmp);
- } else {
- tcg_gen_sub_i32(tmp, tmp2, tmp);
- }
- store_reg_bx(s, UCOP_REG_D, tmp);
- break;
- case 0x04:
- if (UCOP_SET_S) {
- gen_helper_add_cc(tmp, cpu_env, tmp, tmp2);
- } else {
- tcg_gen_add_i32(tmp, tmp, tmp2);
- }
- store_reg_bx(s, UCOP_REG_D, tmp);
- break;
- case 0x05:
- if (UCOP_SET_S) {
- gen_helper_adc_cc(tmp, cpu_env, tmp, tmp2);
- } else {
- gen_add_carry(tmp, tmp, tmp2);
- }
- store_reg_bx(s, UCOP_REG_D, tmp);
- break;
- case 0x06:
- if (UCOP_SET_S) {
- gen_helper_sbc_cc(tmp, cpu_env, tmp, tmp2);
- } else {
- gen_sub_carry(tmp, tmp, tmp2);
- }
- store_reg_bx(s, UCOP_REG_D, tmp);
- break;
- case 0x07:
- if (UCOP_SET_S) {
- gen_helper_sbc_cc(tmp, cpu_env, tmp2, tmp);
- } else {
- gen_sub_carry(tmp, tmp2, tmp);
- }
- store_reg_bx(s, UCOP_REG_D, tmp);
- break;
- case 0x08:
- if (UCOP_SET_S) {
- tcg_gen_and_i32(tmp, tmp, tmp2);
- gen_logic_CC(tmp);
- }
- dead_tmp(tmp);
- break;
- case 0x09:
- if (UCOP_SET_S) {
- tcg_gen_xor_i32(tmp, tmp, tmp2);
- gen_logic_CC(tmp);
- }
- dead_tmp(tmp);
- break;
- case 0x0a:
- if (UCOP_SET_S) {
- gen_helper_sub_cc(tmp, cpu_env, tmp, tmp2);
- }
- dead_tmp(tmp);
- break;
- case 0x0b:
- if (UCOP_SET_S) {
- gen_helper_add_cc(tmp, cpu_env, tmp, tmp2);
- }
- dead_tmp(tmp);
- break;
- case 0x0c:
- tcg_gen_or_i32(tmp, tmp, tmp2);
- if (logic_cc) {
- gen_logic_CC(tmp);
- }
- store_reg_bx(s, UCOP_REG_D, tmp);
- break;
- case 0x0d:
- if (logic_cc && UCOP_REG_D == 31) {
- /* MOVS r31, ... is used for exception return. */
- if (IS_USER(s)) {
- ILLEGAL;
- }
- gen_exception_return(s, tmp2);
- } else {
- if (logic_cc) {
- gen_logic_CC(tmp2);
- }
- store_reg_bx(s, UCOP_REG_D, tmp2);
- }
- break;
- case 0x0e:
- tcg_gen_andc_i32(tmp, tmp, tmp2);
- if (logic_cc) {
- gen_logic_CC(tmp);
- }
- store_reg_bx(s, UCOP_REG_D, tmp);
- break;
- default:
- case 0x0f:
- tcg_gen_not_i32(tmp2, tmp2);
- if (logic_cc) {
- gen_logic_CC(tmp2);
- }
- store_reg_bx(s, UCOP_REG_D, tmp2);
- break;
- }
- if (UCOP_OPCODES != 0x0f && UCOP_OPCODES != 0x0d) {
- dead_tmp(tmp2);
- }
-}
-
-/* multiply */
-static void do_mult(CPUUniCore32State *env, DisasContext *s, uint32_t insn)
-{
- TCGv tmp, tmp2, tmp3, tmp4;
-
- if (UCOP_SET(27)) {
- /* 64 bit mul */
- tmp = load_reg(s, UCOP_REG_M);
- tmp2 = load_reg(s, UCOP_REG_N);
- if (UCOP_SET(26)) {
- tcg_gen_muls2_i32(tmp, tmp2, tmp, tmp2);
- } else {
- tcg_gen_mulu2_i32(tmp, tmp2, tmp, tmp2);
- }
- if (UCOP_SET(25)) { /* mult accumulate */
- tmp3 = load_reg(s, UCOP_REG_LO);
- tmp4 = load_reg(s, UCOP_REG_HI);
- tcg_gen_add2_i32(tmp, tmp2, tmp, tmp2, tmp3, tmp4);
- dead_tmp(tmp3);
- dead_tmp(tmp4);
- }
- store_reg(s, UCOP_REG_LO, tmp);
- store_reg(s, UCOP_REG_HI, tmp2);
- } else {
- /* 32 bit mul */
- tmp = load_reg(s, UCOP_REG_M);
- tmp2 = load_reg(s, UCOP_REG_N);
- tcg_gen_mul_i32(tmp, tmp, tmp2);
- dead_tmp(tmp2);
- if (UCOP_SET(25)) {
- /* Add */
- tmp2 = load_reg(s, UCOP_REG_S);
- tcg_gen_add_i32(tmp, tmp, tmp2);
- dead_tmp(tmp2);
- }
- if (UCOP_SET_S) {
- gen_logic_CC(tmp);
- }
- store_reg(s, UCOP_REG_D, tmp);
- }
-}
-
-/* miscellaneous instructions */
-static void do_misc(CPUUniCore32State *env, DisasContext *s, uint32_t insn)
-{
- unsigned int val;
- TCGv tmp;
-
- if ((insn & 0xffffffe0) == 0x10ffc120) {
- /* Trivial implementation equivalent to bx. */
- tmp = load_reg(s, UCOP_REG_M);
- gen_bx(s, tmp);
- return;
- }
-
- if ((insn & 0xfbffc000) == 0x30ffc000) {
- /* PSR = immediate */
- val = UCOP_IMM_9;
- if (UCOP_SH_IM) {
- val = (val >> UCOP_SH_IM) | (val << (32 - UCOP_SH_IM));
- }
- tmp = new_tmp();
- tcg_gen_movi_i32(tmp, val);
- if (gen_set_psr(s, ~ASR_RESERVED, UCOP_SET_B, tmp)) {
- ILLEGAL;
- }
- return;
- }
-
- if ((insn & 0xfbffffe0) == 0x12ffc020) {
- /* PSR.flag = reg */
- tmp = load_reg(s, UCOP_REG_M);
- if (gen_set_psr(s, ASR_NZCV, UCOP_SET_B, tmp)) {
- ILLEGAL;
- }
- return;
- }
-
- if ((insn & 0xfbffffe0) == 0x10ffc020) {
- /* PSR = reg */
- tmp = load_reg(s, UCOP_REG_M);
- if (gen_set_psr(s, ~ASR_RESERVED, UCOP_SET_B, tmp)) {
- ILLEGAL;
- }
- return;
- }
-
- if ((insn & 0xfbf83fff) == 0x10f80000) {
- /* reg = PSR */
- if (UCOP_SET_B) {
- if (IS_USER(s)) {
- ILLEGAL;
- }
- tmp = load_cpu_field(bsr);
- } else {
- tmp = new_tmp();
- gen_helper_asr_read(tmp, cpu_env);
- }
- store_reg(s, UCOP_REG_D, tmp);
- return;
- }
-
- if ((insn & 0xfbf83fe0) == 0x12f80120) {
- /* clz */
- tmp = load_reg(s, UCOP_REG_M);
- if (UCOP_SET(26)) {
- /* clo */
- tcg_gen_not_i32(tmp, tmp);
- }
- tcg_gen_clzi_i32(tmp, tmp, 32);
- store_reg(s, UCOP_REG_D, tmp);
- return;
- }
-
- /* otherwise */
- ILLEGAL;
-}
-
-/* load/store I_offset and R_offset */
-static void do_ldst_ir(CPUUniCore32State *env, DisasContext *s, uint32_t insn)
-{
- unsigned int mmu_idx;
- TCGv tmp;
- TCGv tmp2;
-
- tmp2 = load_reg(s, UCOP_REG_N);
- mmu_idx = (IS_USER(s) || (!UCOP_SET_P && UCOP_SET_W));
-
- /* immediate */
- if (UCOP_SET_P) {
- gen_add_data_offset(s, insn, tmp2);
- }
-
- if (UCOP_SET_L) {
- /* load */
- if (UCOP_SET_B) {
- tmp = gen_ld8u(tmp2, mmu_idx);
- } else {
- tmp = gen_ld32(tmp2, mmu_idx);
- }
- } else {
- /* store */
- tmp = load_reg(s, UCOP_REG_D);
- if (UCOP_SET_B) {
- gen_st8(tmp, tmp2, mmu_idx);
- } else {
- gen_st32(tmp, tmp2, mmu_idx);
- }
- }
- if (!UCOP_SET_P) {
- gen_add_data_offset(s, insn, tmp2);
- store_reg(s, UCOP_REG_N, tmp2);
- } else if (UCOP_SET_W) {
- store_reg(s, UCOP_REG_N, tmp2);
- } else {
- dead_tmp(tmp2);
- }
- if (UCOP_SET_L) {
- /* Complete the load. */
- if (UCOP_REG_D == 31) {
- gen_bx(s, tmp);
- } else {
- store_reg(s, UCOP_REG_D, tmp);
- }
- }
-}
-
-/* SWP instruction */
-static void do_swap(CPUUniCore32State *env, DisasContext *s, uint32_t insn)
-{
- TCGv addr;
- TCGv tmp;
- TCGv tmp2;
-
- if ((insn & 0xff003fe0) != 0x40000120) {
- ILLEGAL;
- }
-
- /* ??? This is not really atomic. However we know
- we never have multiple CPUs running in parallel,
- so it is good enough. */
- addr = load_reg(s, UCOP_REG_N);
- tmp = load_reg(s, UCOP_REG_M);
- if (UCOP_SET_B) {
- tmp2 = gen_ld8u(addr, IS_USER(s));
- gen_st8(tmp, addr, IS_USER(s));
- } else {
- tmp2 = gen_ld32(addr, IS_USER(s));
- gen_st32(tmp, addr, IS_USER(s));
- }
- dead_tmp(addr);
- store_reg(s, UCOP_REG_D, tmp2);
-}
-
-/* load/store hw/sb */
-static void do_ldst_hwsb(CPUUniCore32State *env, DisasContext *s, uint32_t insn)
-{
- TCGv addr;
- TCGv tmp;
-
- if (UCOP_SH_OP == 0) {
- do_swap(env, s, insn);
- return;
- }
-
- addr = load_reg(s, UCOP_REG_N);
- if (UCOP_SET_P) {
- gen_add_datah_offset(s, insn, addr);
- }
-
- if (UCOP_SET_L) { /* load */
- switch (UCOP_SH_OP) {
- case 1:
- tmp = gen_ld16u(addr, IS_USER(s));
- break;
- case 2:
- tmp = gen_ld8s(addr, IS_USER(s));
- break;
- default: /* see do_swap */
- case 3:
- tmp = gen_ld16s(addr, IS_USER(s));
- break;
- }
- } else { /* store */
- if (UCOP_SH_OP != 1) {
- ILLEGAL;
- }
- tmp = load_reg(s, UCOP_REG_D);
- gen_st16(tmp, addr, IS_USER(s));
- }
- /* Perform base writeback before the loaded value to
- ensure correct behavior with overlapping index registers. */
- if (!UCOP_SET_P) {
- gen_add_datah_offset(s, insn, addr);
- store_reg(s, UCOP_REG_N, addr);
- } else if (UCOP_SET_W) {
- store_reg(s, UCOP_REG_N, addr);
- } else {
- dead_tmp(addr);
- }
- if (UCOP_SET_L) {
- /* Complete the load. */
- store_reg(s, UCOP_REG_D, tmp);
- }
-}
-
-/* load/store multiple words */
-static void do_ldst_m(CPUUniCore32State *env, DisasContext *s, uint32_t insn)
-{
- unsigned int val, i, mmu_idx;
- int j, n, reg, user, loaded_base;
- TCGv tmp;
- TCGv tmp2;
- TCGv addr;
- TCGv loaded_var;
-
- if (UCOP_SET(7)) {
- ILLEGAL;
- }
- /* XXX: store correct base if write back */
- user = 0;
- if (UCOP_SET_B) { /* S bit in instruction table */
- if (IS_USER(s)) {
- ILLEGAL; /* only usable in supervisor mode */
- }
- if (UCOP_SET(18) == 0) { /* pc reg */
- user = 1;
- }
- }
-
- mmu_idx = (IS_USER(s) || (!UCOP_SET_P && UCOP_SET_W));
- addr = load_reg(s, UCOP_REG_N);
-
- /* compute total size */
- loaded_base = 0;
- loaded_var = NULL;
- n = 0;
- for (i = 0; i < 6; i++) {
- if (UCOP_SET(i)) {
- n++;
- }
- }
- for (i = 9; i < 19; i++) {
- if (UCOP_SET(i)) {
- n++;
- }
- }
- /* XXX: test invalid n == 0 case ? */
- if (UCOP_SET_U) {
- if (UCOP_SET_P) {
- /* pre increment */
- tcg_gen_addi_i32(addr, addr, 4);
- } else {
- /* post increment */
- }
- } else {
- if (UCOP_SET_P) {
- /* pre decrement */
- tcg_gen_addi_i32(addr, addr, -(n * 4));
- } else {
- /* post decrement */
- if (n != 1) {
- tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
- }
- }
- }
-
- j = 0;
- reg = UCOP_SET(6) ? 16 : 0;
- for (i = 0; i < 19; i++, reg++) {
- if (i == 6) {
- i = i + 3;
- }
- if (UCOP_SET(i)) {
- if (UCOP_SET_L) { /* load */
- tmp = gen_ld32(addr, mmu_idx);
- if (reg == 31) {
- gen_bx(s, tmp);
- } else if (user) {
- tmp2 = tcg_const_i32(reg);
- gen_helper_set_user_reg(cpu_env, tmp2, tmp);
- tcg_temp_free_i32(tmp2);
- dead_tmp(tmp);
- } else if (reg == UCOP_REG_N) {
- loaded_var = tmp;
- loaded_base = 1;
- } else {
- store_reg(s, reg, tmp);
- }
- } else { /* store */
- if (reg == 31) {
- /* special case: r31 = PC + 4 */
- val = (long)s->pc;
- tmp = new_tmp();
- tcg_gen_movi_i32(tmp, val);
- } else if (user) {
- tmp = new_tmp();
- tmp2 = tcg_const_i32(reg);
- gen_helper_get_user_reg(tmp, cpu_env, tmp2);
- tcg_temp_free_i32(tmp2);
- } else {
- tmp = load_reg(s, reg);
- }
- gen_st32(tmp, addr, mmu_idx);
- }
- j++;
- /* no need to add after the last transfer */
- if (j != n) {
- tcg_gen_addi_i32(addr, addr, 4);
- }
- }
- }
- if (UCOP_SET_W) { /* write back */
- if (UCOP_SET_U) {
- if (UCOP_SET_P) {
- /* pre increment */
- } else {
- /* post increment */
- tcg_gen_addi_i32(addr, addr, 4);
- }
- } else {
- if (UCOP_SET_P) {
- /* pre decrement */
- if (n != 1) {
- tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
- }
- } else {
- /* post decrement */
- tcg_gen_addi_i32(addr, addr, -(n * 4));
- }
- }
- store_reg(s, UCOP_REG_N, addr);
- } else {
- dead_tmp(addr);
- }
- if (loaded_base) {
- store_reg(s, UCOP_REG_N, loaded_var);
- }
- if (UCOP_SET_B && !user) {
- /* Restore ASR from BSR. */
- tmp = load_cpu_field(bsr);
- gen_set_asr(tmp, 0xffffffff);
- dead_tmp(tmp);
- s->is_jmp = DISAS_UPDATE;
- }
-}
-
-/* branch (and link) */
-static void do_branch(CPUUniCore32State *env, DisasContext *s, uint32_t insn)
-{
- unsigned int val;
- int32_t offset;
- TCGv tmp;
-
- if (UCOP_COND == 0xf) {
- ILLEGAL;
- }
-
- if (UCOP_COND != 0xe) {
- /* if not always execute, we generate a conditional jump to
- next instruction */
- s->condlabel = gen_new_label();
- gen_test_cc(UCOP_COND ^ 1, s->condlabel);
- s->condjmp = 1;
- }
-
- val = (int32_t)s->pc;
- if (UCOP_SET_L) {
- tmp = new_tmp();
- tcg_gen_movi_i32(tmp, val);
- store_reg(s, 30, tmp);
- }
- offset = (((int32_t)insn << 8) >> 8);
- val += (offset << 2); /* unicore is pc+4 */
- gen_jmp(s, val);
-}
-
-static void disas_uc32_insn(CPUUniCore32State *env, DisasContext *s)
-{
- unsigned int insn;
-
- insn = cpu_ldl_code(env, s->pc);
- s->pc += 4;
-
- /* UniCore instructions class:
- * AAAB BBBC xxxx xxxx xxxx xxxD xxEx xxxx
- * AAA : see switch case
- * BBBB : opcodes or cond or PUBW
- * C : S OR L
- * D : 8
- * E : 5
- */
- switch (insn >> 29) {
- case 0x0:
- if (UCOP_SET(5) && UCOP_SET(8) && !UCOP_SET(28)) {
- do_mult(env, s, insn);
- break;
- }
-
- if (UCOP_SET(8)) {
- do_misc(env, s, insn);
- break;
- }
- /* fallthrough */
- case 0x1:
- if (((UCOP_OPCODES >> 2) == 2) && !UCOP_SET_S) {
- do_misc(env, s, insn);
- break;
- }
- do_datap(env, s, insn);
- break;
-
- case 0x2:
- if (UCOP_SET(8) && UCOP_SET(5)) {
- do_ldst_hwsb(env, s, insn);
- break;
- }
- if (UCOP_SET(8) || UCOP_SET(5)) {
- ILLEGAL;
- }
- /* fallthrough */
- case 0x3:
- do_ldst_ir(env, s, insn);
- break;
-
- case 0x4:
- if (UCOP_SET(8)) {
- ILLEGAL; /* extended instructions */
- }
- do_ldst_m(env, s, insn);
- break;
- case 0x5:
- do_branch(env, s, insn);
- break;
- case 0x6:
- /* Coprocessor. */
- disas_coproc_insn(env, s, insn);
- break;
- case 0x7:
- if (!UCOP_SET(28)) {
- disas_coproc_insn(env, s, insn);
- break;
- }
- if ((insn & 0xff000000) == 0xff000000) { /* syscall */
- gen_set_pc_im(s->pc);
- s->is_jmp = DISAS_SYSCALL;
- break;
- }
- ILLEGAL;
- }
-}
-
-/* generate intermediate code for basic block 'tb'. */
-void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
-{
- CPUUniCore32State *env = cs->env_ptr;
- DisasContext dc1, *dc = &dc1;
- target_ulong pc_start;
- uint32_t page_start;
- int num_insns;
-
- /* generate intermediate code */
- num_temps = 0;
-
- pc_start = tb->pc;
-
- dc->tb = tb;
-
- dc->is_jmp = DISAS_NEXT;
- dc->pc = pc_start;
- dc->singlestep_enabled = cs->singlestep_enabled;
- dc->condjmp = 0;
- cpu_F0s = tcg_temp_new_i32();
- cpu_F1s = tcg_temp_new_i32();
- cpu_F0d = tcg_temp_new_i64();
- cpu_F1d = tcg_temp_new_i64();
- page_start = pc_start & TARGET_PAGE_MASK;
- num_insns = 0;
-
-#ifndef CONFIG_USER_ONLY
- if ((env->uncached_asr & ASR_M) == ASR_MODE_USER) {
- dc->user = 1;
- } else {
- dc->user = 0;
- }
-#endif
-
- gen_tb_start(tb);
- do {
- tcg_gen_insn_start(dc->pc);
- num_insns++;
-
- if (unlikely(cpu_breakpoint_test(cs, dc->pc, BP_ANY))) {
- gen_set_pc_im(dc->pc);
- gen_exception(EXCP_DEBUG);
- dc->is_jmp = DISAS_JUMP;
- /* The address covered by the breakpoint must be included in
- [tb->pc, tb->pc + tb->size) in order to for it to be
- properly cleared -- thus we increment the PC here so that
- the logic setting tb->size below does the right thing. */
- dc->pc += 4;
- goto done_generating;
- }
-
- if (num_insns == max_insns && (tb_cflags(tb) & CF_LAST_IO)) {
- gen_io_start();
- }
-
- disas_uc32_insn(env, dc);
-
- if (num_temps) {
- fprintf(stderr, "Internal resource leak before %08x\n", dc->pc);
- num_temps = 0;
- }
-
- if (dc->condjmp && !dc->is_jmp) {
- gen_set_label(dc->condlabel);
- dc->condjmp = 0;
- }
- /* Translation stops when a conditional branch is encountered.
- * Otherwise the subsequent code could get translated several times.
- * Also stop translation when a page boundary is reached. This
- * ensures prefetch aborts occur at the right place. */
- } while (!dc->is_jmp && !tcg_op_buf_full() &&
- !cs->singlestep_enabled &&
- !singlestep &&
- dc->pc - page_start < TARGET_PAGE_SIZE &&
- num_insns < max_insns);
-
- if (tb_cflags(tb) & CF_LAST_IO) {
- if (dc->condjmp) {
- /* FIXME: This can theoretically happen with self-modifying
- code. */
- cpu_abort(cs, "IO on conditional branch instruction");
- }
- }
-
- /* At this stage dc->condjmp will only be set when the skipped
- instruction was a conditional branch or trap, and the PC has
- already been written. */
- if (unlikely(cs->singlestep_enabled)) {
- /* Make sure the pc is updated, and raise a debug exception. */
- if (dc->condjmp) {
- if (dc->is_jmp == DISAS_SYSCALL) {
- gen_exception(UC32_EXCP_PRIV);
- } else {
- gen_exception(EXCP_DEBUG);
- }
- gen_set_label(dc->condlabel);
- }
- if (dc->condjmp || !dc->is_jmp) {
- gen_set_pc_im(dc->pc);
- dc->condjmp = 0;
- }
- if (dc->is_jmp == DISAS_SYSCALL && !dc->condjmp) {
- gen_exception(UC32_EXCP_PRIV);
- } else {
- gen_exception(EXCP_DEBUG);
- }
- } else {
- /* While branches must always occur at the end of an IT block,
- there are a few other things that can cause us to terminate
- the TB in the middel of an IT block:
- - Exception generating instructions (bkpt, swi, undefined).
- - Page boundaries.
- - Hardware watchpoints.
- Hardware breakpoints have already been handled and skip this code.
- */
- switch (dc->is_jmp) {
- case DISAS_NEXT:
- gen_goto_tb(dc, 1, dc->pc);
- break;
- default:
- case DISAS_JUMP:
- case DISAS_UPDATE:
- /* indicate that the hash table must be used to find the next TB */
- tcg_gen_exit_tb(NULL, 0);
- break;
- case DISAS_TB_JUMP:
- /* nothing more to generate */
- break;
- case DISAS_SYSCALL:
- gen_exception(UC32_EXCP_PRIV);
- break;
- }
- if (dc->condjmp) {
- gen_set_label(dc->condlabel);
- gen_goto_tb(dc, 1, dc->pc);
- dc->condjmp = 0;
- }
- }
-
-done_generating:
- gen_tb_end(tb, num_insns);
-
-#ifdef DEBUG_DISAS
- if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)
- && qemu_log_in_addr_range(pc_start)) {
- FILE *logfile = qemu_log_lock();
- qemu_log("----------------\n");
- qemu_log("IN: %s\n", lookup_symbol(pc_start));
- log_target_disas(cs, pc_start, dc->pc - pc_start);
- qemu_log("\n");
- qemu_log_unlock(logfile);
- }
-#endif
- tb->size = dc->pc - pc_start;
- tb->icount = num_insns;
-}
-
-static const char *cpu_mode_names[16] = {
- "USER", "REAL", "INTR", "PRIV", "UM14", "UM15", "UM16", "TRAP",
- "UM18", "UM19", "UM1A", "EXTN", "UM1C", "UM1D", "UM1E", "SUSR"
-};
-
-#undef UCF64_DUMP_STATE
-#ifdef UCF64_DUMP_STATE
-static void cpu_dump_state_ucf64(CPUUniCore32State *env, int flags)
-{
- int i;
- union {
- uint32_t i;
- float s;
- } s0, s1;
- CPU_DoubleU d;
- /* ??? This assumes float64 and double have the same layout.
- Oh well, it's only debug dumps. */
- union {
- float64 f64;
- double d;
- } d0;
-
- for (i = 0; i < 16; i++) {
- d.d = env->ucf64.regs[i];
- s0.i = d.l.lower;
- s1.i = d.l.upper;
- d0.f64 = d.d;
- qemu_fprintf(f, "s%02d=%08x(%8g) s%02d=%08x(%8g)",
- i * 2, (int)s0.i, s0.s,
- i * 2 + 1, (int)s1.i, s1.s);
- qemu_fprintf(f, " d%02d=%" PRIx64 "(%8g)\n",
- i, (uint64_t)d0.f64, d0.d);
- }
- qemu_fprintf(f, "FPSCR: %08x\n", (int)env->ucf64.xregs[UC32_UCF64_FPSCR]);
-}
-#else
-#define cpu_dump_state_ucf64(env, file, pr, flags) do { } while (0)
-#endif
-
-void uc32_cpu_dump_state(CPUState *cs, FILE *f, int flags)
-{
- UniCore32CPU *cpu = UNICORE32_CPU(cs);
- CPUUniCore32State *env = &cpu->env;
- int i;
- uint32_t psr;
-
- for (i = 0; i < 32; i++) {
- qemu_fprintf(f, "R%02d=%08x", i, env->regs[i]);
- if ((i % 4) == 3) {
- qemu_fprintf(f, "\n");
- } else {
- qemu_fprintf(f, " ");
- }
- }
- psr = cpu_asr_read(env);
- qemu_fprintf(f, "PSR=%08x %c%c%c%c %s\n",
- psr,
- psr & (1 << 31) ? 'N' : '-',
- psr & (1 << 30) ? 'Z' : '-',
- psr & (1 << 29) ? 'C' : '-',
- psr & (1 << 28) ? 'V' : '-',
- cpu_mode_names[psr & 0xf]);
-
- if (flags & CPU_DUMP_FPU) {
- cpu_dump_state_ucf64(env, f, cpu_fprintf, flags);
- }
-}
-
-void restore_state_to_opc(CPUUniCore32State *env, TranslationBlock *tb,
- target_ulong *data)
-{
- env->regs[31] = data[0];
-}
diff --git a/target/unicore32/ucf64_helper.c b/target/unicore32/ucf64_helper.c
deleted file mode 100644
index 12a91900f6..0000000000
--- a/target/unicore32/ucf64_helper.c
+++ /dev/null
@@ -1,324 +0,0 @@
-/*
- * UniCore-F64 simulation helpers for QEMU.
- *
- * Copyright (C) 2010-2012 Guan Xuetao
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation, or any later version.
- * See the COPYING file in the top-level directory.
- */
-#include "qemu/osdep.h"
-#include "cpu.h"
-#include "exec/helper-proto.h"
-#include "fpu/softfloat.h"
-
-/*
- * The convention used for UniCore-F64 instructions:
- * Single precition routines have a "s" suffix
- * Double precision routines have a "d" suffix.
- */
-
-/* Convert host exception flags to f64 form. */
-static inline int ucf64_exceptbits_from_host(int host_bits)
-{
- int target_bits = 0;
-
- if (host_bits & float_flag_invalid) {
- target_bits |= UCF64_FPSCR_FLAG_INVALID;
- }
- if (host_bits & float_flag_divbyzero) {
- target_bits |= UCF64_FPSCR_FLAG_DIVZERO;
- }
- if (host_bits & float_flag_overflow) {
- target_bits |= UCF64_FPSCR_FLAG_OVERFLOW;
- }
- if (host_bits & float_flag_underflow) {
- target_bits |= UCF64_FPSCR_FLAG_UNDERFLOW;
- }
- if (host_bits & float_flag_inexact) {
- target_bits |= UCF64_FPSCR_FLAG_INEXACT;
- }
- return target_bits;
-}
-
-uint32_t HELPER(ucf64_get_fpscr)(CPUUniCore32State *env)
-{
- int i;
- uint32_t fpscr;
-
- fpscr = (env->ucf64.xregs[UC32_UCF64_FPSCR] & UCF64_FPSCR_MASK);
- i = get_float_exception_flags(&env->ucf64.fp_status);
- fpscr |= ucf64_exceptbits_from_host(i);
- return fpscr;
-}
-
-/* Convert ucf64 exception flags to target form. */
-static inline int ucf64_exceptbits_to_host(int target_bits)
-{
- int host_bits = 0;
-
- if (target_bits & UCF64_FPSCR_FLAG_INVALID) {
- host_bits |= float_flag_invalid;
- }
- if (target_bits & UCF64_FPSCR_FLAG_DIVZERO) {
- host_bits |= float_flag_divbyzero;
- }
- if (target_bits & UCF64_FPSCR_FLAG_OVERFLOW) {
- host_bits |= float_flag_overflow;
- }
- if (target_bits & UCF64_FPSCR_FLAG_UNDERFLOW) {
- host_bits |= float_flag_underflow;
- }
- if (target_bits & UCF64_FPSCR_FLAG_INEXACT) {
- host_bits |= float_flag_inexact;
- }
- return host_bits;
-}
-
-void HELPER(ucf64_set_fpscr)(CPUUniCore32State *env, uint32_t val)
-{
- UniCore32CPU *cpu = env_archcpu(env);
- int i;
- uint32_t changed;
-
- changed = env->ucf64.xregs[UC32_UCF64_FPSCR];
- env->ucf64.xregs[UC32_UCF64_FPSCR] = (val & UCF64_FPSCR_MASK);
-
- changed ^= val;
- if (changed & (UCF64_FPSCR_RND_MASK)) {
- i = UCF64_FPSCR_RND(val);
- switch (i) {
- case 0:
- i = float_round_nearest_even;
- break;
- case 1:
- i = float_round_to_zero;
- break;
- case 2:
- i = float_round_up;
- break;
- case 3:
- i = float_round_down;
- break;
- default: /* 100 and 101 not implement */
- cpu_abort(CPU(cpu), "Unsupported UniCore-F64 round mode");
- }
- set_float_rounding_mode(i, &env->ucf64.fp_status);
- }
-
- i = ucf64_exceptbits_to_host(UCF64_FPSCR_TRAPEN(val));
- set_float_exception_flags(i, &env->ucf64.fp_status);
-}
-
-float32 HELPER(ucf64_adds)(float32 a, float32 b, CPUUniCore32State *env)
-{
- return float32_add(a, b, &env->ucf64.fp_status);
-}
-
-float64 HELPER(ucf64_addd)(float64 a, float64 b, CPUUniCore32State *env)
-{
- return float64_add(a, b, &env->ucf64.fp_status);
-}
-
-float32 HELPER(ucf64_subs)(float32 a, float32 b, CPUUniCore32State *env)
-{
- return float32_sub(a, b, &env->ucf64.fp_status);
-}
-
-float64 HELPER(ucf64_subd)(float64 a, float64 b, CPUUniCore32State *env)
-{
- return float64_sub(a, b, &env->ucf64.fp_status);
-}
-
-float32 HELPER(ucf64_muls)(float32 a, float32 b, CPUUniCore32State *env)
-{
- return float32_mul(a, b, &env->ucf64.fp_status);
-}
-
-float64 HELPER(ucf64_muld)(float64 a, float64 b, CPUUniCore32State *env)
-{
- return float64_mul(a, b, &env->ucf64.fp_status);
-}
-
-float32 HELPER(ucf64_divs)(float32 a, float32 b, CPUUniCore32State *env)
-{
- return float32_div(a, b, &env->ucf64.fp_status);
-}
-
-float64 HELPER(ucf64_divd)(float64 a, float64 b, CPUUniCore32State *env)
-{
- return float64_div(a, b, &env->ucf64.fp_status);
-}
-
-float32 HELPER(ucf64_negs)(float32 a)
-{
- return float32_chs(a);
-}
-
-float64 HELPER(ucf64_negd)(float64 a)
-{
- return float64_chs(a);
-}
-
-float32 HELPER(ucf64_abss)(float32 a)
-{
- return float32_abs(a);
-}
-
-float64 HELPER(ucf64_absd)(float64 a)
-{
- return float64_abs(a);
-}
-
-void HELPER(ucf64_cmps)(float32 a, float32 b, uint32_t c,
- CPUUniCore32State *env)
-{
- FloatRelation flag = float32_compare_quiet(a, b, &env->ucf64.fp_status);
- env->CF = 0;
- switch (c & 0x7) {
- case 0: /* F */
- break;
- case 1: /* UN */
- if (flag == 2) {
- env->CF = 1;
- }
- break;
- case 2: /* EQ */
- if (flag == 0) {
- env->CF = 1;
- }
- break;
- case 3: /* UEQ */
- if ((flag == 0) || (flag == 2)) {
- env->CF = 1;
- }
- break;
- case 4: /* OLT */
- if (flag == -1) {
- env->CF = 1;
- }
- break;
- case 5: /* ULT */
- if ((flag == -1) || (flag == 2)) {
- env->CF = 1;
- }
- break;
- case 6: /* OLE */
- if ((flag == -1) || (flag == 0)) {
- env->CF = 1;
- }
- break;
- case 7: /* ULE */
- if (flag != 1) {
- env->CF = 1;
- }
- break;
- }
- env->ucf64.xregs[UC32_UCF64_FPSCR] = (env->CF << 29)
- | (env->ucf64.xregs[UC32_UCF64_FPSCR] & 0x0fffffff);
-}
-
-void HELPER(ucf64_cmpd)(float64 a, float64 b, uint32_t c,
- CPUUniCore32State *env)
-{
- FloatRelation flag = float64_compare_quiet(a, b, &env->ucf64.fp_status);
- env->CF = 0;
- switch (c & 0x7) {
- case 0: /* F */
- break;
- case 1: /* UN */
- if (flag == 2) {
- env->CF = 1;
- }
- break;
- case 2: /* EQ */
- if (flag == 0) {
- env->CF = 1;
- }
- break;
- case 3: /* UEQ */
- if ((flag == 0) || (flag == 2)) {
- env->CF = 1;
- }
- break;
- case 4: /* OLT */
- if (flag == -1) {
- env->CF = 1;
- }
- break;
- case 5: /* ULT */
- if ((flag == -1) || (flag == 2)) {
- env->CF = 1;
- }
- break;
- case 6: /* OLE */
- if ((flag == -1) || (flag == 0)) {
- env->CF = 1;
- }
- break;
- case 7: /* ULE */
- if (flag != 1) {
- env->CF = 1;
- }
- break;
- }
- env->ucf64.xregs[UC32_UCF64_FPSCR] = (env->CF << 29)
- | (env->ucf64.xregs[UC32_UCF64_FPSCR] & 0x0fffffff);
-}
-
-/* Helper routines to perform bitwise copies between float and int. */
-static inline float32 ucf64_itos(uint32_t i)
-{
- union {
- uint32_t i;
- float32 s;
- } v;
-
- v.i = i;
- return v.s;
-}
-
-static inline uint32_t ucf64_stoi(float32 s)
-{
- union {
- uint32_t i;
- float32 s;
- } v;
-
- v.s = s;
- return v.i;
-}
-
-/* Integer to float conversion. */
-float32 HELPER(ucf64_si2sf)(float32 x, CPUUniCore32State *env)
-{
- return int32_to_float32(ucf64_stoi(x), &env->ucf64.fp_status);
-}
-
-float64 HELPER(ucf64_si2df)(float32 x, CPUUniCore32State *env)
-{
- return int32_to_float64(ucf64_stoi(x), &env->ucf64.fp_status);
-}
-
-/* Float to integer conversion. */
-float32 HELPER(ucf64_sf2si)(float32 x, CPUUniCore32State *env)
-{
- return ucf64_itos(float32_to_int32(x, &env->ucf64.fp_status));
-}
-
-float32 HELPER(ucf64_df2si)(float64 x, CPUUniCore32State *env)
-{
- return ucf64_itos(float64_to_int32(x, &env->ucf64.fp_status));
-}
-
-/* floating point conversion */
-float64 HELPER(ucf64_sf2df)(float32 x, CPUUniCore32State *env)
-{
- return float32_to_float64(x, &env->ucf64.fp_status);
-}
-
-float32 HELPER(ucf64_df2sf)(float64 x, CPUUniCore32State *env)
-{
- return float64_to_float32(x, &env->ucf64.fp_status);
-}
diff --git a/tests/docker/dockerfiles/alpine.docker b/tests/docker/dockerfiles/alpine.docker
index d63a269aef..0ac46ddd91 100644
--- a/tests/docker/dockerfiles/alpine.docker
+++ b/tests/docker/dockerfiles/alpine.docker
@@ -9,6 +9,7 @@ ENV PACKAGES \
alsa-lib-dev \
bash \
binutils \
+ ccache \
coreutils \
curl-dev \
g++ \
@@ -39,6 +40,7 @@ ENV PACKAGES \
pulseaudio-dev \
python3 \
py3-sphinx \
+ py3-sphinx_rtd_theme \
shadow \
snappy-dev \
spice-dev \
diff --git a/tests/docker/dockerfiles/debian10.docker b/tests/docker/dockerfiles/debian10.docker
index d034acbd25..63cf835ec5 100644
--- a/tests/docker/dockerfiles/debian10.docker
+++ b/tests/docker/dockerfiles/debian10.docker
@@ -32,6 +32,7 @@ RUN apt update && \
psmisc \
python3 \
python3-sphinx \
+ python3-sphinx-rtd-theme \
$(apt-get -s build-dep --arch-only qemu | egrep ^Inst | fgrep '[all]' | cut -d\ -f2)
ENV FEATURES docs
diff --git a/tests/docker/dockerfiles/fedora-i386-cross.docker b/tests/docker/dockerfiles/fedora-i386-cross.docker
index 966072c08e..66cdb06c19 100644
--- a/tests/docker/dockerfiles/fedora-i386-cross.docker
+++ b/tests/docker/dockerfiles/fedora-i386-cross.docker
@@ -1,6 +1,7 @@
FROM fedora:33
ENV PACKAGES \
bzip2 \
+ ccache \
diffutils \
findutils \
gcc \
diff --git a/tests/docker/dockerfiles/fedora-win32-cross.docker b/tests/docker/dockerfiles/fedora-win32-cross.docker
index 81b5659e9c..3733df63e9 100644
--- a/tests/docker/dockerfiles/fedora-win32-cross.docker
+++ b/tests/docker/dockerfiles/fedora-win32-cross.docker
@@ -4,6 +4,7 @@ FROM fedora:33
ENV PACKAGES \
bc \
bzip2 \
+ ccache \
diffutils \
findutils \
gcc \
diff --git a/tests/docker/dockerfiles/fedora-win64-cross.docker b/tests/docker/dockerfiles/fedora-win64-cross.docker
index bcb428e724..2564ce4979 100644
--- a/tests/docker/dockerfiles/fedora-win64-cross.docker
+++ b/tests/docker/dockerfiles/fedora-win64-cross.docker
@@ -4,6 +4,7 @@ FROM fedora:33
ENV PACKAGES \
bc \
bzip2 \
+ ccache \
diffutils \
findutils \
gcc \
diff --git a/tests/docker/dockerfiles/fedora.docker b/tests/docker/dockerfiles/fedora.docker
index 915fdc1845..d8fa16372d 100644
--- a/tests/docker/dockerfiles/fedora.docker
+++ b/tests/docker/dockerfiles/fedora.docker
@@ -92,6 +92,7 @@ ENV PACKAGES \
python3-pillow \
python3-pip \
python3-sphinx \
+ python3-sphinx_rtd_theme \
python3-virtualenv \
rdma-core-devel \
SDL2-devel \
diff --git a/tests/docker/dockerfiles/opensuse-leap.docker b/tests/docker/dockerfiles/opensuse-leap.docker
index 0e64893e4a..f7e1cbfbe6 100644
--- a/tests/docker/dockerfiles/opensuse-leap.docker
+++ b/tests/docker/dockerfiles/opensuse-leap.docker
@@ -5,6 +5,7 @@ ENV PACKAGES \
bc \
brlapi-devel \
bzip2 \
+ ccache \
cyrus-sasl-devel \
gcc \
gcc-c++ \
diff --git a/tests/docker/dockerfiles/ubuntu.docker b/tests/docker/dockerfiles/ubuntu.docker
index b5ef7a8198..98a527361c 100644
--- a/tests/docker/dockerfiles/ubuntu.docker
+++ b/tests/docker/dockerfiles/ubuntu.docker
@@ -63,6 +63,7 @@ ENV PACKAGES \
ninja-build \
python3-yaml \
python3-sphinx \
+ python3-sphinx-rtd-theme \
sparse \
xfslibs-dev
RUN apt-get update && \
diff --git a/tests/docker/dockerfiles/ubuntu1804.docker b/tests/docker/dockerfiles/ubuntu1804.docker
index 9b0a19ba5e..c0d3642507 100644
--- a/tests/docker/dockerfiles/ubuntu1804.docker
+++ b/tests/docker/dockerfiles/ubuntu1804.docker
@@ -48,6 +48,7 @@ ENV PACKAGES \
make \
python3-yaml \
python3-sphinx \
+ python3-sphinx-rtd-theme \
ninja-build \
sparse \
xfslibs-dev
diff --git a/tests/docker/dockerfiles/ubuntu2004.docker b/tests/docker/dockerfiles/ubuntu2004.docker
index 9750016e51..f1e0ebad49 100644
--- a/tests/docker/dockerfiles/ubuntu2004.docker
+++ b/tests/docker/dockerfiles/ubuntu2004.docker
@@ -58,6 +58,7 @@ ENV PACKAGES flex bison \
python3-pil \
python3-pip \
python3-sphinx \
+ python3-sphinx-rtd-theme \
python3-venv \
python3-yaml \
rpm2cpio \
diff --git a/tests/migration/guestperf/comparison.py b/tests/migration/guestperf/comparison.py
index ba2edbe546..c03b3f6d7e 100644
--- a/tests/migration/guestperf/comparison.py
+++ b/tests/migration/guestperf/comparison.py
@@ -121,4 +121,18 @@ COMPARISONS = [
Scenario("compr-xbzrle-cache-50",
compression_xbzrle=True, compression_xbzrle_cache=50),
]),
+
+
+ # Looking at effect of multifd with
+ # varying numbers of channels
+ Comparison("compr-multifd", scenarios = [
+ Scenario("compr-multifd-channels-4",
+ multifd=True, multifd_channels=2),
+ Scenario("compr-multifd-channels-8",
+ multifd=True, multifd_channels=8),
+ Scenario("compr-multifd-channels-32",
+ multifd=True, multifd_channels=32),
+ Scenario("compr-multifd-channels-64",
+ multifd=True, multifd_channels=64),
+ ]),
]
diff --git a/tests/migration/guestperf/engine.py b/tests/migration/guestperf/engine.py
index 6b49aed579..208e095794 100644
--- a/tests/migration/guestperf/engine.py
+++ b/tests/migration/guestperf/engine.py
@@ -188,6 +188,22 @@ class Engine(object):
1024 * 1024 * 1024 / 100 *
scenario._compression_xbzrle_cache))
+ if scenario._multifd:
+ resp = src.command("migrate-set-capabilities",
+ capabilities = [
+ { "capability": "multifd",
+ "state": True }
+ ])
+ resp = src.command("migrate-set-parameters",
+ multifd_channels=scenario._multifd_channels)
+ resp = dst.command("migrate-set-capabilities",
+ capabilities = [
+ { "capability": "multifd",
+ "state": True }
+ ])
+ resp = dst.command("migrate-set-parameters",
+ multifd_channels=scenario._multifd_channels)
+
resp = src.command("migrate", uri=connect_uri)
post_copy = False
diff --git a/tests/migration/guestperf/scenario.py b/tests/migration/guestperf/scenario.py
index 28ef36c26d..de70d9b2f5 100644
--- a/tests/migration/guestperf/scenario.py
+++ b/tests/migration/guestperf/scenario.py
@@ -29,7 +29,8 @@ class Scenario(object):
post_copy=False, post_copy_iters=5,
auto_converge=False, auto_converge_step=10,
compression_mt=False, compression_mt_threads=1,
- compression_xbzrle=False, compression_xbzrle_cache=10):
+ compression_xbzrle=False, compression_xbzrle_cache=10,
+ multifd=False, multifd_channels=2):
self._name = name
@@ -56,6 +57,9 @@ class Scenario(object):
self._compression_xbzrle = compression_xbzrle
self._compression_xbzrle_cache = compression_xbzrle_cache # percentage of guest RAM
+ self._multifd = multifd
+ self._multifd_channels = multifd_channels
+
def serialize(self):
return {
"name": self._name,
@@ -73,6 +77,8 @@ class Scenario(object):
"compression_mt_threads": self._compression_mt_threads,
"compression_xbzrle": self._compression_xbzrle,
"compression_xbzrle_cache": self._compression_xbzrle_cache,
+ "multifd": self._multifd,
+ "multifd_channels": self._multifd_channels,
}
@classmethod
@@ -92,4 +98,6 @@ class Scenario(object):
data["compression_mt"],
data["compression_mt_threads"],
data["compression_xbzrle"],
- data["compression_xbzrle_cache"])
+ data["compression_xbzrle_cache"],
+ data["multifd"],
+ data["multifd_channels"])
diff --git a/tests/migration/guestperf/shell.py b/tests/migration/guestperf/shell.py
index f838888809..8a809e3dda 100644
--- a/tests/migration/guestperf/shell.py
+++ b/tests/migration/guestperf/shell.py
@@ -122,6 +122,11 @@ class Shell(BaseShell):
parser.add_argument("--compression-xbzrle", dest="compression_xbzrle", default=False, action="store_true")
parser.add_argument("--compression-xbzrle-cache", dest="compression_xbzrle_cache", default=10, type=int)
+ parser.add_argument("--multifd", dest="multifd", default=False,
+ action="store_true")
+ parser.add_argument("--multifd-channels", dest="multifd_channels",
+ default=2, type=int)
+
def get_scenario(self, args):
return Scenario(name="perfreport",
downtime=args.downtime,
@@ -142,7 +147,10 @@ class Shell(BaseShell):
compression_mt_threads=args.compression_mt_threads,
compression_xbzrle=args.compression_xbzrle,
- compression_xbzrle_cache=args.compression_xbzrle_cache)
+ compression_xbzrle_cache=args.compression_xbzrle_cache,
+
+ multifd=args.multifd,
+ multifd_channels=args.multifd_channels)
def run(self, argv):
args = self._parser.parse_args(argv)
diff --git a/tests/qemu-iotests/005 b/tests/qemu-iotests/005
index 40e64a9a8f..ba377543b0 100755
--- a/tests/qemu-iotests/005
+++ b/tests/qemu-iotests/005
@@ -52,11 +52,6 @@ if [ "$IMGFMT" = "vpc" ]; then
_notrun "image format $IMGFMT does not support large image sizes"
fi
-# sheepdog image is limited to 4TB, so we can't test it here
-if [ "$IMGPROTO" = "sheepdog" ]; then
- _notrun "image protocol $IMGPROTO does not support large image sizes"
-fi
-
# Sanity check: For raw, we require a file system that permits the creation
# of a HUGE (but very sparse) file. Check we can create it before continuing.
if [ "$IMGFMT" = "raw" ]; then
diff --git a/tests/qemu-iotests/025 b/tests/qemu-iotests/025
index da77ed3154..80686a30d5 100755
--- a/tests/qemu-iotests/025
+++ b/tests/qemu-iotests/025
@@ -39,7 +39,7 @@ trap "_cleanup; exit \$status" 0 1 2 3 15
. ./common.pattern
_supported_fmt raw qcow2 qed luks
-_supported_proto file sheepdog rbd nfs fuse
+_supported_proto file rbd nfs fuse
echo "=== Creating image"
echo
diff --git a/tests/qemu-iotests/231 b/tests/qemu-iotests/231
index 0f66d0ca36..8e6c6447c1 100755
--- a/tests/qemu-iotests/231
+++ b/tests/qemu-iotests/231
@@ -55,6 +55,10 @@ _filter_conf()
$QEMU_IMG info "json:{'file.driver':'rbd','file.filename':'rbd:rbd/bogus:conf=${BOGUS_CONF}'}" 2>&1 | _filter_conf
$QEMU_IMG info "json:{'file.driver':'rbd','file.pool':'rbd','file.image':'bogus','file.conf':'${BOGUS_CONF}'}" 2>&1 | _filter_conf
+# Regression test: the qemu-img invocation is expected to fail, but it should
+# not seg fault the parser.
+$QEMU_IMG create "rbd:rbd/aa\/bb:conf=${BOGUS_CONF}" 1M 2>&1 | _filter_conf
+
# success, all done
echo "*** done"
rm -f $seq.full
diff --git a/tests/qemu-iotests/231.out b/tests/qemu-iotests/231.out
index 579ba11c16..a785a6e859 100644
--- a/tests/qemu-iotests/231.out
+++ b/tests/qemu-iotests/231.out
@@ -1,9 +1,10 @@
QA output created by 231
-qemu-img: RBD options encoded in the filename as keyvalue pairs is deprecated. Future versions may cease to parse these options in the future.
+qemu-img: warning: RBD options encoded in the filename as keyvalue pairs is deprecated
unable to get monitor info from DNS SRV with service name: ceph-mon
-no monitors specified to connect to.
qemu-img: Could not open 'json:{'file.driver':'rbd','file.filename':'rbd:rbd/bogus:conf=BOGUS_CONF'}': error connecting: No such file or directory
unable to get monitor info from DNS SRV with service name: ceph-mon
-no monitors specified to connect to.
qemu-img: Could not open 'json:{'file.driver':'rbd','file.pool':'rbd','file.image':'bogus','file.conf':'BOGUS_CONF'}': error connecting: No such file or directory
+Formatting 'rbd:rbd/aa\/bb:conf=BOGUS_CONF', fmt=raw size=1048576
+unable to get monitor info from DNS SRV with service name: ceph-mon
+qemu-img: rbd:rbd/aa\/bb:conf=BOGUS_CONF: error connecting: No such file or directory
*** done
diff --git a/tests/qemu-iotests/240.out b/tests/qemu-iotests/240.out
index e0982831ae..89ed25e506 100644
--- a/tests/qemu-iotests/240.out
+++ b/tests/qemu-iotests/240.out
@@ -15,7 +15,7 @@
{"return": {}}
{"execute": "blockdev-del", "arguments": {"node-name": "hd0"}}
{"return": {}}
-==Attach two SCSI disks using the same block device and the same iothread==
+.==Attach two SCSI disks using the same block device and the same iothread==
{"execute": "blockdev-add", "arguments": {"driver": "null-co", "node-name": "hd0", "read-only": true, "read-zeroes": true}}
{"return": {}}
{"execute": "object-add", "arguments": {"id": "iothread0", "qom-type": "iothread"}}
@@ -32,7 +32,7 @@
{"return": {}}
{"execute": "blockdev-del", "arguments": {"node-name": "hd0"}}
{"return": {}}
-==Attach two SCSI disks using the same block device but different iothreads==
+.==Attach two SCSI disks using the same block device but different iothreads==
{"execute": "blockdev-add", "arguments": {"driver": "null-co", "node-name": "hd0", "read-only": true, "read-zeroes": true}}
{"return": {}}
{"execute": "object-add", "arguments": {"id": "iothread0", "qom-type": "iothread"}}
@@ -55,7 +55,7 @@
{"return": {}}
{"execute": "blockdev-del", "arguments": {"node-name": "hd0"}}
{"return": {}}
-==Attach a SCSI disks using the same block device as a NBD server==
+.==Attach a SCSI disks using the same block device as a NBD server==
{"execute": "blockdev-add", "arguments": {"driver": "null-co", "node-name": "hd0", "read-only": true, "read-zeroes": true}}
{"return": {}}
{"execute": "nbd-server-start", "arguments": {"addr": {"data": {"path": "SOCK_DIR/PID-nbd.sock"}, "type": "unix"}}}
@@ -68,7 +68,7 @@
{"return": {}}
{"execute": "device_add", "arguments": {"drive": "hd0", "driver": "scsi-hd", "id": "scsi-hd0"}}
{"return": {}}
-....
+.
----------------------------------------------------------------------
Ran 4 tests
diff --git a/tests/qemu-iotests/245.out b/tests/qemu-iotests/245.out
index 4b33dcaf5c..99c12f4f98 100644
--- a/tests/qemu-iotests/245.out
+++ b/tests/qemu-iotests/245.out
@@ -1,16 +1,16 @@
-{"execute": "job-finalize", "arguments": {"id": "commit0"}}
+..{"execute": "job-finalize", "arguments": {"id": "commit0"}}
{"return": {}}
{"data": {"id": "commit0", "type": "commit"}, "event": "BLOCK_JOB_PENDING", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
{"data": {"device": "commit0", "len": 3145728, "offset": 3145728, "speed": 0, "type": "commit"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
-{"execute": "job-finalize", "arguments": {"id": "stream0"}}
+...{"execute": "job-finalize", "arguments": {"id": "stream0"}}
{"return": {}}
{"data": {"id": "stream0", "type": "stream"}, "event": "BLOCK_JOB_PENDING", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
{"data": {"device": "stream0", "len": 3145728, "offset": 3145728, "speed": 0, "type": "stream"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
-{"execute": "job-finalize", "arguments": {"id": "stream0"}}
+.{"execute": "job-finalize", "arguments": {"id": "stream0"}}
{"return": {}}
{"data": {"id": "stream0", "type": "stream"}, "event": "BLOCK_JOB_PENDING", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
{"data": {"device": "stream0", "len": 3145728, "offset": 3145728, "speed": 0, "type": "stream"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
-.....................
+...............
----------------------------------------------------------------------
Ran 21 tests
diff --git a/tests/qemu-iotests/264 b/tests/qemu-iotests/264
index 4f96825a22..bc431d1a19 100755
--- a/tests/qemu-iotests/264
+++ b/tests/qemu-iotests/264
@@ -95,7 +95,7 @@ class TestNbdReconnect(iotests.QMPTestCase):
self.assert_qmp(result, 'return', {})
def cancel_job(self):
- result = self.vm.qmp('block-job-cancel', device='drive0')
+ result = self.vm.qmp('block-job-cancel', device='drive0', force=True)
self.assert_qmp(result, 'return', {})
start_t = time.time()
diff --git a/tests/qemu-iotests/295.out b/tests/qemu-iotests/295.out
index ad34b2ca2c..5ff91f116c 100644
--- a/tests/qemu-iotests/295.out
+++ b/tests/qemu-iotests/295.out
@@ -4,7 +4,7 @@
{"return": {}}
{"execute": "job-dismiss", "arguments": {"id": "job_erase_key"}}
{"return": {}}
-{"execute": "job-dismiss", "arguments": {"id": "job_add_key"}}
+.{"execute": "job-dismiss", "arguments": {"id": "job_add_key"}}
{"return": {}}
{"execute": "job-dismiss", "arguments": {"id": "job_erase_key"}}
{"return": {}}
@@ -13,7 +13,7 @@ Job failed: Invalid password, cannot unlock any keyslot
{"return": {}}
{"execute": "job-dismiss", "arguments": {"id": "job_add_key"}}
{"return": {}}
-{"execute": "job-dismiss", "arguments": {"id": "job_add_key"}}
+.{"execute": "job-dismiss", "arguments": {"id": "job_add_key"}}
{"return": {}}
{"execute": "job-dismiss", "arguments": {"id": "job_add_key"}}
{"return": {}}
@@ -33,7 +33,7 @@ Job failed: All the active keyslots match the (old) password that was given and
{"return": {}}
{"execute": "job-dismiss", "arguments": {"id": "job_erase_key"}}
{"return": {}}
-...
+.
----------------------------------------------------------------------
Ran 3 tests
diff --git a/tests/qemu-iotests/296.out b/tests/qemu-iotests/296.out
index cb2859a15c..6c69735604 100644
--- a/tests/qemu-iotests/296.out
+++ b/tests/qemu-iotests/296.out
@@ -13,7 +13,7 @@ Job failed: Failed to get shared "consistent read" lock
qemu-img: Failed to get shared "consistent read" lock
Is another process using the image [TEST_DIR/test.img]?
-Formatting 'TEST_DIR/test.img', fmt=luks size=1048576 key-secret=keysec0 iter-time=10
+.Formatting 'TEST_DIR/test.img', fmt=luks size=1048576 key-secret=keysec0 iter-time=10
Job failed: Block node is read-only
{"execute": "job-dismiss", "arguments": {"id": "job0"}}
@@ -26,15 +26,15 @@ Job failed: Failed to get shared "consistent read" lock
{"return": {}}
{"execute": "job-dismiss", "arguments": {"id": "job0"}}
{"return": {}}
-Formatting 'TEST_DIR/test.img', fmt=luks size=1048576 key-secret=keysec0 iter-time=10
+.Formatting 'TEST_DIR/test.img', fmt=luks size=1048576 key-secret=keysec0 iter-time=10
{"return": {}}
{"error": {"class": "GenericError", "desc": "Failed to get \"write\" lock"}}
-Formatting 'TEST_DIR/test.img', fmt=luks size=1048576 key-secret=keysec0 iter-time=10
+.Formatting 'TEST_DIR/test.img', fmt=luks size=1048576 key-secret=keysec0 iter-time=10
{"return": {}}
{"return": {}}
-....
+.
----------------------------------------------------------------------
Ran 4 tests
diff --git a/tests/qemu-iotests/check b/tests/qemu-iotests/check
index d1c87ceaf1..2dd529eb75 100755
--- a/tests/qemu-iotests/check
+++ b/tests/qemu-iotests/check
@@ -19,6 +19,9 @@
import os
import sys
import argparse
+import shutil
+from pathlib import Path
+
from findtests import TestFinder
from testenv import TestEnv
from testrunner import TestRunner
@@ -65,8 +68,7 @@ def make_argparser() -> argparse.ArgumentParser:
mg.add_argument('-' + fmt, dest='imgfmt', action='store_const',
const=fmt, help=f'test {fmt}')
- protocol_list = ['file', 'rbd', 'sheepdog', 'nbd', 'ssh', 'nfs',
- 'fuse']
+ protocol_list = ['file', 'rbd', 'nbd', 'ssh', 'nfs', 'fuse']
g_prt = p.add_argument_group(
' image protocol options',
'The following options set the IMGPROTO environment variable. '
@@ -101,7 +103,7 @@ def make_argparser() -> argparse.ArgumentParser:
'rerun failed ./check command, starting from the '
'middle of the process.')
g_sel.add_argument('tests', metavar='TEST_FILES', nargs='*',
- help='tests to run')
+ help='tests to run, or "--" followed by a command')
return p
@@ -114,6 +116,20 @@ if __name__ == '__main__':
imgopts=args.imgopts, misalign=args.misalign,
debug=args.debug, valgrind=args.valgrind)
+ if len(sys.argv) > 1 and sys.argv[-len(args.tests)-1] == '--':
+ if not args.tests:
+ sys.exit("missing command after '--'")
+ cmd = args.tests
+ env.print_env()
+ exec_pathstr = shutil.which(cmd[0])
+ if exec_pathstr is None:
+ sys.exit('command not found: ' + cmd[0])
+ exec_path = Path(exec_pathstr).resolve()
+ cmd[0] = str(exec_path)
+ full_env = env.prepare_subprocess(cmd)
+ os.chdir(exec_path.parent)
+ os.execve(cmd[0], cmd, full_env)
+
testfinder = TestFinder(test_dir=env.source_iotests)
groups = args.groups.split(',') if args.groups else None
diff --git a/tests/qemu-iotests/common.rc b/tests/qemu-iotests/common.rc
index 7f49c9716d..cbbf6d7c7f 100644
--- a/tests/qemu-iotests/common.rc
+++ b/tests/qemu-iotests/common.rc
@@ -641,10 +641,6 @@ _cleanup_test_img()
rbd --no-progress rm "$TEST_DIR/t.$IMGFMT" > /dev/null
;;
- sheepdog)
- collie vdi delete "$TEST_DIR/t.$IMGFMT"
- ;;
-
esac
}
diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py
index 5af0182895..777fa2ec0e 100644
--- a/tests/qemu-iotests/iotests.py
+++ b/tests/qemu-iotests/iotests.py
@@ -20,7 +20,6 @@ import atexit
import bz2
from collections import OrderedDict
import faulthandler
-import io
import json
import logging
import os
@@ -32,7 +31,7 @@ import subprocess
import sys
import time
from typing import (Any, Callable, Dict, Iterable,
- List, Optional, Sequence, Tuple, TypeVar)
+ List, Optional, Sequence, TextIO, Tuple, Type, TypeVar)
import unittest
from contextlib import contextmanager
@@ -113,15 +112,14 @@ def qemu_tool_pipe_and_status(tool: str, args: Sequence[str],
Run a tool and return both its output and its exit code
"""
stderr = subprocess.STDOUT if connect_stderr else None
- subp = subprocess.Popen(args,
- stdout=subprocess.PIPE,
- stderr=stderr,
- universal_newlines=True)
- output = subp.communicate()[0]
- if subp.returncode < 0:
- cmd = ' '.join(args)
- sys.stderr.write(f'{tool} received signal {-subp.returncode}: {cmd}\n')
- return (output, subp.returncode)
+ with subprocess.Popen(args, stdout=subprocess.PIPE,
+ stderr=stderr, universal_newlines=True) as subp:
+ output = subp.communicate()[0]
+ if subp.returncode < 0:
+ cmd = ' '.join(args)
+ sys.stderr.write(f'{tool} received signal \
+ {-subp.returncode}: {cmd}\n')
+ return (output, subp.returncode)
def qemu_img_pipe_and_status(*args: str) -> Tuple[str, int]:
"""
@@ -237,6 +235,9 @@ def qemu_io_silent_check(*args):
class QemuIoInteractive:
def __init__(self, *args):
self.args = qemu_io_args_no_fmt + list(args)
+ # We need to keep the Popen objext around, and not
+ # close it immediately. Therefore, disable the pylint check:
+ # pylint: disable=consider-using-with
self._p = subprocess.Popen(self.args, stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
@@ -310,22 +311,22 @@ def qemu_nbd_popen(*args):
cmd.extend(args)
log('Start NBD server')
- p = subprocess.Popen(cmd)
- try:
- while not os.path.exists(pid_file):
- if p.poll() is not None:
- raise RuntimeError(
- "qemu-nbd terminated with exit code {}: {}"
- .format(p.returncode, ' '.join(cmd)))
-
- time.sleep(0.01)
- yield
- finally:
- if os.path.exists(pid_file):
- os.remove(pid_file)
- log('Kill NBD server')
- p.kill()
- p.wait()
+ with subprocess.Popen(cmd) as p:
+ try:
+ while not os.path.exists(pid_file):
+ if p.poll() is not None:
+ raise RuntimeError(
+ "qemu-nbd terminated with exit code {}: {}"
+ .format(p.returncode, ' '.join(cmd)))
+
+ time.sleep(0.01)
+ yield
+ finally:
+ if os.path.exists(pid_file):
+ os.remove(pid_file)
+ log('Kill NBD server')
+ p.kill()
+ p.wait()
def compare_images(img1, img2, fmt1=imgfmt, fmt2=imgfmt):
'''Return True if two image files are identical'''
@@ -334,13 +335,12 @@ def compare_images(img1, img2, fmt1=imgfmt, fmt2=imgfmt):
def create_image(name, size):
'''Create a fully-allocated raw image with sector markers'''
- file = open(name, 'wb')
- i = 0
- while i < size:
- sector = struct.pack('>l504xl', i // 512, i // 512)
- file.write(sector)
- i = i + 512
- file.close()
+ with open(name, 'wb') as file:
+ i = 0
+ while i < size:
+ sector = struct.pack('>l504xl', i // 512, i // 512)
+ file.write(sector)
+ i = i + 512
def image_size(img):
'''Return image's virtual size'''
@@ -1271,37 +1271,54 @@ def skip_if_user_is_root(func):
return func(*args, **kwargs)
return func_wrapper
-def execute_unittest(debug=False):
+# We need to filter out the time taken from the output so that
+# qemu-iotest can reliably diff the results against master output,
+# and hide skipped tests from the reference output.
+
+class ReproducibleTestResult(unittest.TextTestResult):
+ def addSkip(self, test, reason):
+ # Same as TextTestResult, but print dot instead of "s"
+ unittest.TestResult.addSkip(self, test, reason)
+ if self.showAll:
+ self.stream.writeln("skipped {0!r}".format(reason))
+ elif self.dots:
+ self.stream.write(".")
+ self.stream.flush()
+
+class ReproducibleStreamWrapper:
+ def __init__(self, stream: TextIO):
+ self.stream = stream
+
+ def __getattr__(self, attr):
+ if attr in ('stream', '__getstate__'):
+ raise AttributeError(attr)
+ return getattr(self.stream, attr)
+
+ def write(self, arg=None):
+ arg = re.sub(r'Ran (\d+) tests? in [\d.]+s', r'Ran \1 tests', arg)
+ arg = re.sub(r' \(skipped=\d+\)', r'', arg)
+ self.stream.write(arg)
+
+class ReproducibleTestRunner(unittest.TextTestRunner):
+ def __init__(self, stream: Optional[TextIO] = None,
+ resultclass: Type[unittest.TestResult] = ReproducibleTestResult,
+ **kwargs: Any) -> None:
+ rstream = ReproducibleStreamWrapper(stream or sys.stdout)
+ super().__init__(stream=rstream, # type: ignore
+ descriptions=True,
+ resultclass=resultclass,
+ **kwargs)
+
+def execute_unittest(argv: List[str], debug: bool = False) -> None:
"""Executes unittests within the calling module."""
- verbosity = 2 if debug else 1
-
- if debug:
- output = sys.stdout
- else:
- # We need to filter out the time taken from the output so that
- # qemu-iotest can reliably diff the results against master output.
- output = io.StringIO()
-
- runner = unittest.TextTestRunner(stream=output, descriptions=True,
- verbosity=verbosity)
- try:
- # unittest.main() will use sys.exit(); so expect a SystemExit
- # exception
- unittest.main(testRunner=runner)
- finally:
- # We need to filter out the time taken from the output so that
- # qemu-iotest can reliably diff the results against master output.
- if not debug:
- out = output.getvalue()
- out = re.sub(r'Ran (\d+) tests? in [\d.]+s', r'Ran \1 tests', out)
-
- # Hide skipped tests from the reference output
- out = re.sub(r'OK \(skipped=\d+\)', 'OK', out)
- out_first_line, out_rest = out.split('\n', 1)
- out = out_first_line.replace('s', '.') + '\n' + out_rest
-
- sys.stderr.write(out)
+ # Some tests have warnings, especially ResourceWarnings for unclosed
+ # files and sockets. Ignore them for now to ensure reproducibility of
+ # the test output.
+ unittest.main(argv=argv,
+ testRunner=ReproducibleTestRunner,
+ verbosity=2 if debug else 1,
+ warnings=None if sys.warnoptions else 'ignore')
def execute_setup_common(supported_fmts: Sequence[str] = (),
supported_platforms: Sequence[str] = (),
@@ -1338,7 +1355,7 @@ def execute_test(*args, test_function=None, **kwargs):
debug = execute_setup_common(*args, **kwargs)
if not test_function:
- execute_unittest(debug)
+ execute_unittest(sys.argv, debug)
else:
test_function()
diff --git a/tests/qemu-iotests/pylintrc b/tests/qemu-iotests/pylintrc
index 7a6c0a9474..f2c0b522ac 100644
--- a/tests/qemu-iotests/pylintrc
+++ b/tests/qemu-iotests/pylintrc
@@ -19,6 +19,9 @@ disable=invalid-name,
too-many-public-methods,
# pylint warns about Optional[] etc. as unsubscriptable in 3.9
unsubscriptable-object,
+ # Sometimes we need to disable a newly introduced pylint warning.
+ # Doing so should not produce a warning in older versions of pylint.
+ bad-option-value,
# These are temporary, and should be removed:
missing-docstring,
too-many-return-statements,
diff --git a/tests/qemu-iotests/testenv.py b/tests/qemu-iotests/testenv.py
index 6d27712617..0c3fe75636 100644
--- a/tests/qemu-iotests/testenv.py
+++ b/tests/qemu-iotests/testenv.py
@@ -25,7 +25,7 @@ import collections
import random
import subprocess
import glob
-from typing import Dict, Any, Optional, ContextManager
+from typing import List, Dict, Any, Optional, ContextManager
def isxfile(path: str) -> bool:
@@ -74,6 +74,21 @@ class TestEnv(ContextManager['TestEnv']):
'CACHEMODE_IS_DEFAULT', 'IMGFMT_GENERIC', 'IMGOPTSSYNTAX',
'IMGKEYSECRET', 'QEMU_DEFAULT_MACHINE', 'MALLOC_PERTURB_']
+ def prepare_subprocess(self, args: List[str]) -> Dict[str, str]:
+ if self.debug:
+ args.append('-d')
+
+ with open(args[0], encoding="utf-8") as f:
+ try:
+ if f.readline().rstrip() == '#!/usr/bin/env python3':
+ args.insert(0, self.python)
+ except UnicodeDecodeError: # binary test? for future.
+ pass
+
+ os_env = os.environ.copy()
+ os_env.update(self.get_env())
+ return os_env
+
def get_env(self) -> Dict[str, str]:
env = {}
for v in self.env_variables:
@@ -105,7 +120,7 @@ class TestEnv(ContextManager['TestEnv']):
try:
self.sock_dir = os.environ['SOCK_DIR']
self.tmp_sock_dir = False
- Path(self.test_dir).mkdir(parents=True, exist_ok=True)
+ Path(self.sock_dir).mkdir(parents=True, exist_ok=True)
except KeyError:
self.sock_dir = tempfile.mkdtemp()
self.tmp_sock_dir = True
@@ -269,7 +284,8 @@ IMGPROTO -- {IMGPROTO}
PLATFORM -- {platform}
TEST_DIR -- {TEST_DIR}
SOCK_DIR -- {SOCK_DIR}
-SOCKET_SCM_HELPER -- {SOCKET_SCM_HELPER}"""
+SOCKET_SCM_HELPER -- {SOCKET_SCM_HELPER}
+"""
args = collections.defaultdict(str, self.get_env())
diff --git a/tests/qemu-iotests/testrunner.py b/tests/qemu-iotests/testrunner.py
index 1fc61fcaa3..4a6ec421ed 100644
--- a/tests/qemu-iotests/testrunner.py
+++ b/tests/qemu-iotests/testrunner.py
@@ -129,7 +129,6 @@ class TestRunner(ContextManager['TestRunner']):
def __init__(self, env: TestEnv, makecheck: bool = False,
color: str = 'auto') -> None:
self.env = env
- self.test_run_env = self.env.get_env()
self.makecheck = makecheck
self.last_elapsed = LastElapsedTime('.last-elapsed-cache', env)
@@ -243,32 +242,21 @@ class TestRunner(ContextManager['TestRunner']):
silent_unlink(p)
args = [str(f_test.resolve())]
- if self.env.debug:
- args.append('-d')
-
- with f_test.open(encoding="utf-8") as f:
- try:
- if f.readline().rstrip() == '#!/usr/bin/env python3':
- args.insert(0, self.env.python)
- except UnicodeDecodeError: # binary test? for future.
- pass
-
- env = os.environ.copy()
- env.update(self.test_run_env)
+ env = self.env.prepare_subprocess(args)
t0 = time.time()
with f_bad.open('w', encoding="utf-8") as f:
- proc = subprocess.Popen(args, cwd=str(f_test.parent), env=env,
- stdout=f, stderr=subprocess.STDOUT)
- try:
- proc.wait()
- except KeyboardInterrupt:
- proc.terminate()
- proc.wait()
- return TestResult(status='not run',
- description='Interrupted by user',
- interrupted=True)
- ret = proc.returncode
+ with subprocess.Popen(args, cwd=str(f_test.parent), env=env,
+ stdout=f, stderr=subprocess.STDOUT) as proc:
+ try:
+ proc.wait()
+ except KeyboardInterrupt:
+ proc.terminate()
+ proc.wait()
+ return TestResult(status='not run',
+ description='Interrupted by user',
+ interrupted=True)
+ ret = proc.returncode
elapsed = round(time.time() - t0, 1)
@@ -328,7 +316,6 @@ class TestRunner(ContextManager['TestRunner']):
if not self.makecheck:
self.env.print_env()
- print()
test_field_width = max(len(os.path.basename(t)) for t in tests) + 2
diff --git a/tests/qtest/ahci-test.c b/tests/qtest/ahci-test.c
index 5e1954852e..8073ccc205 100644
--- a/tests/qtest/ahci-test.c
+++ b/tests/qtest/ahci-test.c
@@ -1491,14 +1491,14 @@ static void ahci_test_cdrom(int nsectors, bool dma, uint8_t cmd,
char *iso;
int fd;
AHCIOpts opts = {
- .size = (ATAPI_SECTOR_SIZE * nsectors),
+ .size = ((uint64_t)ATAPI_SECTOR_SIZE * nsectors),
.atapi = true,
.atapi_dma = dma,
.post_cb = ahci_cb_cmp_buff,
.set_bcl = override_bcl,
.bcl = bcl,
};
- uint64_t iso_size = ATAPI_SECTOR_SIZE * (nsectors + 1);
+ uint64_t iso_size = (uint64_t)ATAPI_SECTOR_SIZE * (nsectors + 1);
/* Prepare ISO and fill 'tx' buffer */
fd = prepare_iso(iso_size, &tx, &iso);
diff --git a/tests/qtest/boot-serial-test.c b/tests/qtest/boot-serial-test.c
index d74509b1c5..d40adddafa 100644
--- a/tests/qtest/boot-serial-test.c
+++ b/tests/qtest/boot-serial-test.c
@@ -61,13 +61,6 @@ static const uint8_t kernel_plml605[] = {
0xfc, 0xff, 0x00, 0xb8 /* bri -4 loop */
};
-static const uint8_t bios_moxiesim[] = {
- 0x20, 0x10, 0x00, 0x00, 0x03, 0xf8, /* ldi.s r1,0x3f8 */
- 0x1b, 0x20, 0x00, 0x00, 0x00, 0x54, /* ldi.b r2,'T' */
- 0x1e, 0x12, /* st.b r1,r2 */
- 0x1a, 0x00, 0x00, 0x00, 0x10, 0x00 /* jmpa 0x1000 */
-};
-
static const uint8_t bios_raspi2[] = {
0x08, 0x30, 0x9f, 0xe5, /* ldr r3,[pc,#8] Get base */
0x54, 0x20, 0xa0, 0xe3, /* mov r2,#'T' */
@@ -145,7 +138,6 @@ static testdef_t tests[] = {
sizeof(kernel_pls3adsp1800), kernel_pls3adsp1800 },
{ "microblazeel", "petalogix-ml605", "", "TT",
sizeof(kernel_plml605), kernel_plml605 },
- { "moxie", "moxiesim", "", "TT", sizeof(bios_moxiesim), 0, bios_moxiesim },
{ "arm", "raspi2", "", "TT", sizeof(bios_raspi2), 0, bios_raspi2 },
/* For hppa, force bios to output to serial by disabling graphics. */
{ "hppa", "hppa", "-vga none", "SeaBIOS wants SYSTEM HALT" },
diff --git a/tests/qtest/ipmi-bt-test.c b/tests/qtest/ipmi-bt-test.c
index a42207d416..8492f02a9c 100644
--- a/tests/qtest/ipmi-bt-test.c
+++ b/tests/qtest/ipmi-bt-test.c
@@ -98,7 +98,8 @@ static void bt_wait_b_busy(void)
{
unsigned int count = 1000;
while (IPMI_BT_CTLREG_GET_B_BUSY() != 0) {
- g_assert(--count != 0);
+ --count;
+ g_assert(count != 0);
usleep(100);
}
}
@@ -107,7 +108,8 @@ static void bt_wait_b2h_atn(void)
{
unsigned int count = 1000;
while (IPMI_BT_CTLREG_GET_B2H_ATN() == 0) {
- g_assert(--count != 0);
+ --count;
+ g_assert(count != 0);
usleep(100);
}
}
diff --git a/tests/qtest/ipmi-kcs-test.c b/tests/qtest/ipmi-kcs-test.c
index fc0a918c8d..afc24dd3e4 100644
--- a/tests/qtest/ipmi-kcs-test.c
+++ b/tests/qtest/ipmi-kcs-test.c
@@ -73,7 +73,8 @@ static void kcs_wait_ibf(void)
{
unsigned int count = 1000;
while (IPMI_KCS_CMDREG_GET_IBF() != 0) {
- g_assert(--count != 0);
+ --count;
+ g_assert(count != 0);
}
}
diff --git a/tests/qtest/libqos/qgraph.c b/tests/qtest/libqos/qgraph.c
index b3b1a31f81..d1dc491930 100644
--- a/tests/qtest/libqos/qgraph.c
+++ b/tests/qtest/libqos/qgraph.c
@@ -844,7 +844,7 @@ void qos_dump_graph(void)
}
qos_printf_literal("type=%d cmd_line='%s' [%s]\n",
node->type, node->command_line,
- node->available ? "available" : "UNAVAILBLE"
+ node->available ? "available" : "UNAVAILABLE"
);
}
g_list_free(keys);
diff --git a/tests/qtest/libqtest.c b/tests/qtest/libqtest.c
index 71e359efcd..825b13a44c 100644
--- a/tests/qtest/libqtest.c
+++ b/tests/qtest/libqtest.c
@@ -907,7 +907,14 @@ const char *qtest_get_arch(void)
if (!end) {
fprintf(stderr, "Can't determine architecture from binary name.\n");
- abort();
+ exit(1);
+ }
+
+ if (!strstr(qemu, "-system-")) {
+ fprintf(stderr, "QTEST_QEMU_BINARY must end with *-system-<arch> "
+ "where 'arch' is the target\narchitecture (x86_64, aarch64, "
+ "etc).\n");
+ exit(1);
}
return end + 1;
diff --git a/tests/qtest/machine-none-test.c b/tests/qtest/machine-none-test.c
index aab06b9fc2..138101b46a 100644
--- a/tests/qtest/machine-none-test.c
+++ b/tests/qtest/machine-none-test.c
@@ -32,7 +32,6 @@ static struct arch2cpu cpus_map[] = {
{ "i386", "qemu32,apic-id=0" },
{ "alpha", "ev67" },
{ "cris", "crisv32" },
- { "lm32", "lm32-full" },
{ "m68k", "m5206" },
{ "microblaze", "any" },
{ "microblazeel", "any" },
@@ -40,7 +39,6 @@ static struct arch2cpu cpus_map[] = {
{ "mipsel", "I7200" },
{ "mips64", "20Kc" },
{ "mips64el", "I6500" },
- { "moxie", "MoxieLite" },
{ "nios2", "FIXME" },
{ "or1k", "or1200" },
{ "ppc", "604" },
@@ -51,7 +49,6 @@ static struct arch2cpu cpus_map[] = {
{ "sparc", "LEON2" },
{ "sparc64", "Fujitsu Sparc64" },
{ "tricore", "tc1796" },
- { "unicore32", "UniCore-II" },
{ "xtensa", "dc233c" },
{ "xtensaeb", "fsf" },
{ "hppa", "hppa" },
diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
index 966bc93efa..49de74ff59 100644
--- a/tests/qtest/meson.build
+++ b/tests/qtest/meson.build
@@ -126,8 +126,6 @@ qtests_mips64el = \
(config_all_devices.has_key('CONFIG_ISA_TESTDEV') ? ['endianness-test'] : []) + \
(config_all_devices.has_key('CONFIG_VGA') ? ['display-vga-test'] : [])
-qtests_moxie = [ 'boot-serial-test' ]
-
qtests_ppc = \
(config_all_devices.has_key('CONFIG_ISA_TESTDEV') ? ['endianness-test'] : []) + \
(config_all_devices.has_key('CONFIG_M48T59') ? ['m48t59-test'] : []) + \
diff --git a/tests/qtest/migration-test.c b/tests/qtest/migration-test.c
index 3a711bb492..2b028df687 100644
--- a/tests/qtest/migration-test.c
+++ b/tests/qtest/migration-test.c
@@ -110,13 +110,12 @@ static void init_bootfile(const char *bootpath, void *content, size_t len)
*/
static void wait_for_serial(const char *side)
{
- char *serialpath = g_strdup_printf("%s/%s", tmpfs, side);
+ g_autofree char *serialpath = g_strdup_printf("%s/%s", tmpfs, side);
FILE *serialfile = fopen(serialpath, "r");
const char *arch = qtest_get_arch();
int started = (strcmp(side, "src_serial") == 0 &&
strcmp(arch, "ppc64") == 0) ? 0 : 1;
- g_free(serialpath);
do {
int readvalue = fgetc(serialfile);
@@ -274,10 +273,9 @@ static void check_guests_ram(QTestState *who)
static void cleanup(const char *filename)
{
- char *path = g_strdup_printf("%s/%s", tmpfs, filename);
+ g_autofree char *path = g_strdup_printf("%s/%s", tmpfs, filename);
unlink(path);
- g_free(path);
}
static char *SocketAddress_to_str(SocketAddress *addr)
@@ -374,11 +372,8 @@ static char *migrate_get_parameter_str(QTestState *who,
static void migrate_check_parameter_str(QTestState *who, const char *parameter,
const char *value)
{
- char *result;
-
- result = migrate_get_parameter_str(who, parameter);
+ g_autofree char *result = migrate_get_parameter_str(who, parameter);
g_assert_cmpstr(result, ==, value);
- g_free(result);
}
static void migrate_set_parameter_str(QTestState *who, const char *parameter,
@@ -495,12 +490,14 @@ static void migrate_start_destroy(MigrateStart *args)
static int test_migrate_start(QTestState **from, QTestState **to,
const char *uri, MigrateStart *args)
{
- gchar *arch_source, *arch_target;
- gchar *cmd_source, *cmd_target;
+ g_autofree gchar *arch_source = NULL;
+ g_autofree gchar *arch_target = NULL;
+ g_autofree gchar *cmd_source = NULL;
+ g_autofree gchar *cmd_target = NULL;
const gchar *ignore_stderr;
- char *bootpath = NULL;
- char *shmem_opts;
- char *shmem_path;
+ g_autofree char *bootpath = NULL;
+ g_autofree char *shmem_opts = NULL;
+ g_autofree char *shmem_path = NULL;
const char *arch = qtest_get_arch();
const char *machine_opts = NULL;
const char *memory_size;
@@ -559,8 +556,6 @@ static int test_migrate_start(QTestState **from, QTestState **to,
g_assert_not_reached();
}
- g_free(bootpath);
-
if (!getenv("QTEST_LOG") && args->hide_stderr) {
ignore_stderr = "2>/dev/null";
} else {
@@ -588,11 +583,9 @@ static int test_migrate_start(QTestState **from, QTestState **to,
memory_size, tmpfs,
arch_source, shmem_opts, args->opts_source,
ignore_stderr);
- g_free(arch_source);
if (!args->only_target) {
*from = qtest_init(cmd_source);
}
- g_free(cmd_source);
cmd_target = g_strdup_printf("-accel kvm -accel tcg%s%s "
"-name target,debug-threads=on "
@@ -605,18 +598,14 @@ static int test_migrate_start(QTestState **from, QTestState **to,
memory_size, tmpfs, uri,
arch_target, shmem_opts,
args->opts_target, ignore_stderr);
- g_free(arch_target);
*to = qtest_init(cmd_target);
- g_free(cmd_target);
- g_free(shmem_opts);
/*
* Remove shmem file immediately to avoid memory leak in test failed case.
* It's valid becase QEMU has already opened this file
*/
if (args->use_shmem) {
unlink(shmem_path);
- g_free(shmem_path);
}
out:
@@ -662,7 +651,7 @@ static int migrate_postcopy_prepare(QTestState **from_ptr,
QTestState **to_ptr,
MigrateStart *args)
{
- char *uri = g_strdup_printf("unix:%s/migsocket", tmpfs);
+ g_autofree char *uri = g_strdup_printf("unix:%s/migsocket", tmpfs);
QTestState *from, *to;
if (test_migrate_start(&from, &to, uri, args)) {
@@ -684,7 +673,6 @@ static int migrate_postcopy_prepare(QTestState **from_ptr,
wait_for_serial("src_serial");
migrate_qmp(from, uri, "{}");
- g_free(uri);
wait_for_migration_pass(from);
@@ -724,7 +712,7 @@ static void test_postcopy_recovery(void)
{
MigrateStart *args = migrate_start_new();
QTestState *from, *to;
- char *uri;
+ g_autofree char *uri = NULL;
args->hide_stderr = true;
@@ -775,7 +763,6 @@ static void test_postcopy_recovery(void)
(const char * []) { "failed", "active",
"completed", NULL });
migrate_qmp(from, uri, "{'resume': true}");
- g_free(uri);
/* Restore the postcopy bandwidth to unlimited */
migrate_set_parameter_int(from, "max-postcopy-bandwidth", 0);
@@ -800,7 +787,7 @@ static void test_baddest(void)
static void test_precopy_unix(void)
{
- char *uri = g_strdup_printf("unix:%s/migsocket", tmpfs);
+ g_autofree char *uri = g_strdup_printf("unix:%s/migsocket", tmpfs);
MigrateStart *args = migrate_start_new();
QTestState *from, *to;
@@ -836,14 +823,13 @@ static void test_precopy_unix(void)
wait_for_migration_complete(from);
test_migrate_end(from, to, true);
- g_free(uri);
}
#if 0
/* Currently upset on aarch64 TCG */
static void test_ignore_shared(void)
{
- char *uri = g_strdup_printf("unix:%s/migsocket", tmpfs);
+ g_autofree char *uri = g_strdup_printf("unix:%s/migsocket", tmpfs);
QTestState *from, *to;
if (test_migrate_start(&from, &to, uri, false, true, NULL, NULL)) {
@@ -873,7 +859,6 @@ static void test_ignore_shared(void)
g_assert_cmpint(read_ram_property_int(from, "transferred"), <, 1024 * 1024);
test_migrate_end(from, to, true);
- g_free(uri);
}
#endif
@@ -898,8 +883,8 @@ static void test_xbzrle(const char *uri)
migrate_set_parameter_int(from, "xbzrle-cache-size", 33554432);
- migrate_set_capability(from, "xbzrle", "true");
- migrate_set_capability(to, "xbzrle", "true");
+ migrate_set_capability(from, "xbzrle", true);
+ migrate_set_capability(to, "xbzrle", true);
/* Wait for the first serial output from the source */
wait_for_serial("src_serial");
@@ -925,16 +910,15 @@ static void test_xbzrle(const char *uri)
static void test_xbzrle_unix(void)
{
- char *uri = g_strdup_printf("unix:%s/migsocket", tmpfs);
+ g_autofree char *uri = g_strdup_printf("unix:%s/migsocket", tmpfs);
test_xbzrle(uri);
- g_free(uri);
}
static void test_precopy_tcp(void)
{
MigrateStart *args = migrate_start_new();
- char *uri;
+ g_autofree char *uri = NULL;
QTestState *from, *to;
if (test_migrate_start(&from, &to, "tcp:127.0.0.1:0", args)) {
@@ -971,7 +955,6 @@ static void test_precopy_tcp(void)
wait_for_migration_complete(from);
test_migrate_end(from, to, true);
- g_free(uri);
}
static void test_migrate_fd_proto(void)
@@ -1060,7 +1043,7 @@ static void test_migrate_fd_proto(void)
static void do_test_validate_uuid(MigrateStart *args, bool should_fail)
{
- char *uri = g_strdup_printf("unix:%s/migsocket", tmpfs);
+ g_autofree char *uri = g_strdup_printf("unix:%s/migsocket", tmpfs);
QTestState *from, *to;
if (test_migrate_start(&from, &to, uri, args)) {
@@ -1088,7 +1071,6 @@ static void do_test_validate_uuid(MigrateStart *args, bool should_fail)
}
test_migrate_end(from, to, false);
- g_free(uri);
}
static void test_validate_uuid(void)
@@ -1136,7 +1118,7 @@ static void test_validate_uuid_dst_not_set(void)
static void test_migrate_auto_converge(void)
{
- char *uri = g_strdup_printf("unix:%s/migsocket", tmpfs);
+ g_autofree char *uri = g_strdup_printf("unix:%s/migsocket", tmpfs);
MigrateStart *args = migrate_start_new();
QTestState *from, *to;
int64_t remaining, percentage;
@@ -1214,7 +1196,6 @@ static void test_migrate_auto_converge(void)
wait_for_serial("dest_serial");
wait_for_migration_complete(from);
- g_free(uri);
test_migrate_end(from, to, true);
}
@@ -1224,7 +1205,7 @@ static void test_multifd_tcp(const char *method)
MigrateStart *args = migrate_start_new();
QTestState *from, *to;
QDict *rsp;
- char *uri;
+ g_autofree char *uri = NULL;
if (test_migrate_start(&from, &to, "defer", args)) {
return;
@@ -1246,8 +1227,8 @@ static void test_multifd_tcp(const char *method)
migrate_set_parameter_str(from, "multifd-compression", method);
migrate_set_parameter_str(to, "multifd-compression", method);
- migrate_set_capability(from, "multifd", "true");
- migrate_set_capability(to, "multifd", "true");
+ migrate_set_capability(from, "multifd", true);
+ migrate_set_capability(to, "multifd", true);
/* Start incoming migration from the 1st socket */
rsp = wait_command(to, "{ 'execute': 'migrate-incoming',"
@@ -1273,7 +1254,6 @@ static void test_multifd_tcp(const char *method)
wait_for_serial("dest_serial");
wait_for_migration_complete(from);
test_migrate_end(from, to, true);
- g_free(uri);
}
static void test_multifd_tcp_none(void)
@@ -1309,7 +1289,7 @@ static void test_multifd_tcp_cancel(void)
MigrateStart *args = migrate_start_new();
QTestState *from, *to, *to2;
QDict *rsp;
- char *uri;
+ g_autofree char *uri = NULL;
args->hide_stderr = true;
@@ -1330,8 +1310,8 @@ static void test_multifd_tcp_cancel(void)
migrate_set_parameter_int(from, "multifd-channels", 16);
migrate_set_parameter_int(to, "multifd-channels", 16);
- migrate_set_capability(from, "multifd", "true");
- migrate_set_capability(to, "multifd", "true");
+ migrate_set_capability(from, "multifd", true);
+ migrate_set_capability(to, "multifd", true);
/* Start incoming migration from the 1st socket */
rsp = wait_command(to, "{ 'execute': 'migrate-incoming',"
@@ -1358,7 +1338,7 @@ static void test_multifd_tcp_cancel(void)
migrate_set_parameter_int(to2, "multifd-channels", 16);
- migrate_set_capability(to2, "multifd", "true");
+ migrate_set_capability(to2, "multifd", true);
/* Start incoming migration from the 1st socket */
rsp = wait_command(to2, "{ 'execute': 'migrate-incoming',"
@@ -1387,7 +1367,6 @@ static void test_multifd_tcp_cancel(void)
wait_for_serial("dest_serial");
wait_for_migration_complete(from);
test_migrate_end(from, to2, true);
- g_free(uri);
}
int main(int argc, char **argv)
diff --git a/tests/qtest/npcm7xx_pwm-test.c b/tests/qtest/npcm7xx_pwm-test.c
index bd15a1c294..a54fd70d27 100644
--- a/tests/qtest/npcm7xx_pwm-test.c
+++ b/tests/qtest/npcm7xx_pwm-test.c
@@ -201,7 +201,7 @@ static int pwm_module_index(const PWMModule *module)
{
ptrdiff_t diff = module - pwm_module_list;
- g_assert_true(diff >= 0 && diff < ARRAY_SIZE(pwm_module_list));
+ g_assert(diff >= 0 && diff < ARRAY_SIZE(pwm_module_list));
return diff;
}
@@ -211,7 +211,7 @@ static int pwm_index(const PWM *pwm)
{
ptrdiff_t diff = pwm - pwm_list;
- g_assert_true(diff >= 0 && diff < ARRAY_SIZE(pwm_list));
+ g_assert(diff >= 0 && diff < ARRAY_SIZE(pwm_list));
return diff;
}
diff --git a/tests/qtest/rtc-test.c b/tests/qtest/rtc-test.c
index 402ce2c609..8126ab1bdb 100644
--- a/tests/qtest/rtc-test.c
+++ b/tests/qtest/rtc-test.c
@@ -686,7 +686,7 @@ static void periodic_timer(void)
int main(int argc, char **argv)
{
- QTestState *s = NULL;
+ QTestState *s;
int ret;
g_test_init(&argc, &argv, NULL);
@@ -712,9 +712,7 @@ int main(int argc, char **argv)
ret = g_test_run();
- if (s) {
- qtest_quit(s);
- }
+ qtest_quit(s);
return ret;
}
diff --git a/tests/qtest/tpm-util.c b/tests/qtest/tpm-util.c
index b70cc32d60..3a40ff3f96 100644
--- a/tests/qtest/tpm-util.c
+++ b/tests/qtest/tpm-util.c
@@ -289,6 +289,6 @@ void tpm_util_migration_start_qemu(QTestState **src_qemu,
*dst_qemu = qtest_init(dst_qemu_args);
- free(src_qemu_args);
- free(dst_qemu_args);
+ g_free(src_qemu_args);
+ g_free(dst_qemu_args);
}
diff --git a/tests/tcg/README b/tests/tcg/README
index 2a58f9a058..706bb185b4 100644
--- a/tests/tcg/README
+++ b/tests/tcg/README
@@ -7,9 +7,3 @@ CRIS
====
The testsuite for CRIS is in tests/tcg/cris. You can run it
with "make test-cris".
-
-LM32
-====
-The testsuite for LM32 is in tests/tcg/lm32. You can run it
-with "make test-lm32".
-
diff --git a/tests/tcg/configure.sh b/tests/tcg/configure.sh
index fa1a4261a4..8f20ce065d 100755
--- a/tests/tcg/configure.sh
+++ b/tests/tcg/configure.sh
@@ -96,7 +96,7 @@ for target in $target_list; do
xtensa|xtensaeb)
arches=xtensa
;;
- alpha|cris|hexagon|hppa|i386|lm32|microblaze|microblazeel|m68k|openrisc|riscv64|s390x|sh4|sparc64)
+ alpha|cris|hexagon|hppa|i386|microblaze|microblazeel|m68k|openrisc|riscv64|s390x|sh4|sparc64)
arches=$target
;;
*)
diff --git a/tests/tcg/lm32/Makefile b/tests/tcg/lm32/Makefile
deleted file mode 100644
index 57e7363b2c..0000000000
--- a/tests/tcg/lm32/Makefile
+++ /dev/null
@@ -1,106 +0,0 @@
--include ../../../config-host.mak
-
-CROSS=lm32-elf-
-
-SIM = qemu-system-lm32
-SIMFLAGS = -M lm32-evr -nographic -semihosting -net none -kernel
-
-CC = $(CROSS)gcc
-AS = $(CROSS)as
-AS = $(CC) -x assembler
-SIZE = $(CROSS)size
-LD = $(CC)
-OBJCOPY = $(CROSS)objcopy
-
-TSRC_PATH = $(SRC_PATH)/tests/tcg/lm32
-
-LDFLAGS = -T$(TSRC_PATH)/linker.ld
-ASFLAGS += -Wa,-I,$(TSRC_PATH)/
-
-CRT = crt.o
-HELPER = helper.o
-TESTCASES += test_add.tst
-TESTCASES += test_addi.tst
-TESTCASES += test_and.tst
-TESTCASES += test_andhi.tst
-TESTCASES += test_andi.tst
-TESTCASES += test_b.tst
-TESTCASES += test_be.tst
-TESTCASES += test_bg.tst
-TESTCASES += test_bge.tst
-TESTCASES += test_bgeu.tst
-TESTCASES += test_bgu.tst
-TESTCASES += test_bi.tst
-TESTCASES += test_bne.tst
-TESTCASES += test_break.tst
-TESTCASES += test_bret.tst
-TESTCASES += test_call.tst
-TESTCASES += test_calli.tst
-TESTCASES += test_cmpe.tst
-TESTCASES += test_cmpei.tst
-TESTCASES += test_cmpg.tst
-TESTCASES += test_cmpgi.tst
-TESTCASES += test_cmpge.tst
-TESTCASES += test_cmpgei.tst
-TESTCASES += test_cmpgeu.tst
-TESTCASES += test_cmpgeui.tst
-TESTCASES += test_cmpgu.tst
-TESTCASES += test_cmpgui.tst
-TESTCASES += test_cmpne.tst
-TESTCASES += test_cmpnei.tst
-TESTCASES += test_divu.tst
-TESTCASES += test_eret.tst
-TESTCASES += test_lb.tst
-TESTCASES += test_lbu.tst
-TESTCASES += test_lh.tst
-TESTCASES += test_lhu.tst
-TESTCASES += test_lw.tst
-TESTCASES += test_modu.tst
-TESTCASES += test_mul.tst
-TESTCASES += test_muli.tst
-TESTCASES += test_nor.tst
-TESTCASES += test_nori.tst
-TESTCASES += test_or.tst
-TESTCASES += test_ori.tst
-TESTCASES += test_orhi.tst
-#TESTCASES += test_rcsr.tst
-TESTCASES += test_ret.tst
-TESTCASES += test_sb.tst
-TESTCASES += test_scall.tst
-TESTCASES += test_sextb.tst
-TESTCASES += test_sexth.tst
-TESTCASES += test_sh.tst
-TESTCASES += test_sl.tst
-TESTCASES += test_sli.tst
-TESTCASES += test_sr.tst
-TESTCASES += test_sri.tst
-TESTCASES += test_sru.tst
-TESTCASES += test_srui.tst
-TESTCASES += test_sub.tst
-TESTCASES += test_sw.tst
-#TESTCASES += test_wcsr.tst
-TESTCASES += test_xnor.tst
-TESTCASES += test_xnori.tst
-TESTCASES += test_xor.tst
-TESTCASES += test_xori.tst
-
-all: build
-
-%.o: $(TSRC_PATH)/%.c
- $(CC) $(CFLAGS) -c $< -o $@
-
-%.o: $(TSRC_PATH)/%.S
- $(AS) $(ASFLAGS) -c $< -o $@
-
-%.tst: %.o $(TSRC_PATH)/macros.inc $(CRT) $(HELPER)
- $(LD) $(LDFLAGS) $(NOSTDFLAGS) $(CRT) $(HELPER) $< -o $@
-
-build: $(TESTCASES)
-
-check: $(TESTCASES:test_%.tst=check_%)
-
-check_%: test_%.tst
- @$(SIM) $(SIMFLAGS) $<
-
-clean:
- $(RM) -fr $(TESTCASES) $(CRT) $(HELPER)
diff --git a/tests/tcg/lm32/crt.S b/tests/tcg/lm32/crt.S
deleted file mode 100644
index fc437a3de1..0000000000
--- a/tests/tcg/lm32/crt.S
+++ /dev/null
@@ -1,84 +0,0 @@
-.text
-.global _start
-
-_start:
-_reset_handler:
- xor r0, r0, r0
- mvhi r1, hi(_start)
- ori r1, r1, lo(_start)
- wcsr eba, r1
- wcsr deba, r1
- mvhi sp, hi(_fstack)
- ori sp, sp, lo(_fstack)
- bi _main
-
-_breakpoint_handler:
- ori r25, r25, 1
- addi ra, ba, 4
- ret
- nop
- nop
- nop
- nop
- nop
-
-_instruction_bus_error_handler:
- ori r25, r25, 2
- addi ra, ea, 4
- ret
- nop
- nop
- nop
- nop
- nop
-
-_watchpoint_handler:
- ori r25, r25, 4
- addi ra, ba, 4
- ret
- nop
- nop
- nop
- nop
- nop
-
-_data_bus_error_handler:
- ori r25, r25, 8
- addi ra, ea, 4
- ret
- nop
- nop
- nop
- nop
- nop
-
-_divide_by_zero_handler:
- ori r25, r25, 16
- addi ra, ea, 4
- ret
- nop
- nop
- nop
- nop
- nop
-
-_interrupt_handler:
- ori r25, r25, 32
- addi ra, ea, 4
- ret
- nop
- nop
- nop
- nop
- nop
-
-_system_call_handler:
- ori r25, r25, 64
- addi ra, ea, 4
- ret
- nop
- nop
- nop
- nop
- nop
-
diff --git a/tests/tcg/lm32/helper.S b/tests/tcg/lm32/helper.S
deleted file mode 100644
index 3351d41e84..0000000000
--- a/tests/tcg/lm32/helper.S
+++ /dev/null
@@ -1,65 +0,0 @@
-.text
-.global _start, _write, _exit
-.global _tc_fail, _tc_pass
-
-_write:
- addi sp, sp, -4
- sw (sp+4), r8
- mvi r8, 5
- scall
- lw r8, (sp+4)
- addi sp, sp, 4
- ret
-
-_exit:
- mvi r8, 1
- scall
-1:
- bi 1b
-
-_tc_pass:
-.data
-1:
- .ascii "OK\n"
-2:
-.text
- addi sp, sp, -16
- sw (sp+4), ra
- sw (sp+8), r1
- sw (sp+12), r2
- sw (sp+16), r3
- mvi r1, 1
- mvhi r2, hi(1b)
- ori r2, r2, lo(1b)
- mvi r3, (2b - 1b)
- calli _write
- lw r3, (sp+16)
- lw r2, (sp+12)
- lw r1, (sp+8)
- lw ra, (sp+4)
- addi sp, sp, 16
- ret
-
-_tc_fail:
-.data
-1:
- .ascii "FAILED\n"
-2:
-.text
- addi sp, sp, -16
- sw (sp+4), ra
- sw (sp+8), r1
- sw (sp+12), r2
- sw (sp+16), r3
- sw (sp+4), ra
- mvi r1, 1
- mvhi r2, hi(1b)
- ori r2, r2, lo(1b)
- mvi r3, (2b - 1b)
- calli _write
- lw r3, (sp+16)
- lw r2, (sp+12)
- lw r1, (sp+8)
- lw ra, (sp+4)
- addi sp, sp, 16
- ret
diff --git a/tests/tcg/lm32/linker.ld b/tests/tcg/lm32/linker.ld
deleted file mode 100644
index 52d43a4c74..0000000000
--- a/tests/tcg/lm32/linker.ld
+++ /dev/null
@@ -1,55 +0,0 @@
-OUTPUT_FORMAT("elf32-lm32")
-ENTRY(_start)
-
-__DYNAMIC = 0;
-
-MEMORY {
- ram : ORIGIN = 0x08000000, LENGTH = 0x04000000 /* 64M */
-}
-
-SECTIONS
-{
- .text :
- {
- _ftext = .;
- *(.text .stub .text.* .gnu.linkonce.t.*)
- _etext = .;
- } > ram
-
- .rodata :
- {
- . = ALIGN(4);
- _frodata = .;
- *(.rodata .rodata.* .gnu.linkonce.r.*)
- *(.rodata1)
- _erodata = .;
- } > ram
-
- .data :
- {
- . = ALIGN(4);
- _fdata = .;
- *(.data .data.* .gnu.linkonce.d.*)
- *(.data1)
- _gp = ALIGN(16);
- *(.sdata .sdata.* .gnu.linkonce.s.*)
- _edata = .;
- } > ram
-
- .bss :
- {
- . = ALIGN(4);
- _fbss = .;
- *(.dynsbss)
- *(.sbss .sbss.* .gnu.linkonce.sb.*)
- *(.scommon)
- *(.dynbss)
- *(.bss .bss.* .gnu.linkonce.b.*)
- *(COMMON)
- _ebss = .;
- _end = .;
- } > ram
-}
-
-PROVIDE(_fstack = ORIGIN(ram) + LENGTH(ram) - 4);
-
diff --git a/tests/tcg/lm32/macros.inc b/tests/tcg/lm32/macros.inc
deleted file mode 100644
index 360ad53c9f..0000000000
--- a/tests/tcg/lm32/macros.inc
+++ /dev/null
@@ -1,90 +0,0 @@
-
-.equ MAX_TESTNAME_LEN, 32
-.macro test_name name
- .data
-tn_\name:
- .ascii "\name"
- .space MAX_TESTNAME_LEN - (. - tn_\name), ' '
- .text
- .global \name
-\name:
- addi sp, sp, -12
- sw (sp+4), r1
- sw (sp+8), r2
- sw (sp+12), r3
- mvi r1, 1
- mvhi r2, hi(tn_\name)
- ori r2, r2, lo(tn_\name)
- mvi r3, MAX_TESTNAME_LEN
- calli _write
- lw r3, (sp+12)
- lw r2, (sp+8)
- lw r1, (sp+4)
- addi sp, sp, 12
-.endm
-
-.macro load reg val
- mvhi \reg, hi(\val)
- ori \reg, \reg, lo(\val)
-.endm
-
-.macro tc_pass
- calli _tc_pass
-.endm
-
-.macro tc_fail
- addi r12, r12, 1
- calli _tc_fail
-.endm
-
-.macro check_r3 val
- mvhi r13, hi(\val)
- ori r13, r13, lo(\val)
- be r3, r13, 1f
- tc_fail
- bi 2f
-1:
- tc_pass
-2:
-.endm
-
-.macro check_mem adr val
- mvhi r13, hi(\adr)
- ori r13, r13, lo(\adr)
- mvhi r14, hi(\val)
- ori r14, r14, lo(\val)
- lw r13, (r13+0)
- be r13, r14, 1f
- tc_fail
- bi 2f
-1:
- tc_pass
-2:
-.endm
-
-.macro check_excp excp
- andi r13, r25, \excp
- bne r13, r0, 1f
- tc_fail
- bi 2f
-1:
- tc_pass
-2:
-.endm
-
-.macro start
- .global _main
- .text
-_main:
- mvi r12, 0
-.endm
-
-.macro end
- mv r1, r12
- calli _exit
-.endm
-
-# base +
-# 0 ctrl
-# 4 pass/fail
-# 8 ptr to test name
diff --git a/tests/tcg/lm32/test_add.S b/tests/tcg/lm32/test_add.S
deleted file mode 100644
index 030ad197bb..0000000000
--- a/tests/tcg/lm32/test_add.S
+++ /dev/null
@@ -1,75 +0,0 @@
-.include "macros.inc"
-
-start
-
-test_name ADD_1
-mvi r1, 0
-mvi r2, 0
-add r3, r1, r2
-check_r3 0
-
-test_name ADD_2
-mvi r1, 0
-mvi r2, 1
-add r3, r1, r2
-check_r3 1
-
-test_name ADD_3
-mvi r1, 1
-mvi r2, 0
-add r3, r1, r2
-check_r3 1
-
-test_name ADD_4
-mvi r1, 1
-mvi r2, -1
-add r3, r1, r2
-check_r3 0
-
-test_name ADD_5
-mvi r1, -1
-mvi r2, 1
-add r3, r1, r2
-check_r3 0
-
-test_name ADD_6
-mvi r1, -1
-mvi r2, 0
-add r3, r1, r2
-check_r3 -1
-
-test_name ADD_7
-mvi r1, 0
-mvi r2, -1
-add r3, r1, r2
-check_r3 -1
-
-test_name ADD_8
-mvi r3, 2
-add r3, r3, r3
-check_r3 4
-
-test_name ADD_9
-mvi r1, 4
-mvi r3, 2
-add r3, r1, r3
-check_r3 6
-
-test_name ADD_10
-mvi r1, 4
-mvi r3, 2
-add r3, r3, r1
-check_r3 6
-
-test_name ADD_11
-mvi r1, 4
-add r3, r1, r1
-check_r3 8
-
-test_name ADD_12
-load r1 0x12345678
-load r2 0xabcdef97
-add r3, r1, r2
-check_r3 0xbe02460f
-
-end
diff --git a/tests/tcg/lm32/test_addi.S b/tests/tcg/lm32/test_addi.S
deleted file mode 100644
index 68e766d1e5..0000000000
--- a/tests/tcg/lm32/test_addi.S
+++ /dev/null
@@ -1,56 +0,0 @@
-.include "macros.inc"
-
-start
-
-test_name ADDI_1
-mvi r1, 0
-addi r3, r1, 0
-check_r3 0
-
-test_name ADDI_2
-mvi r1, 0
-addi r3, r1, 1
-check_r3 1
-
-test_name ADDI_3
-mvi r1, 1
-addi r3, r1, 0
-check_r3 1
-
-test_name ADDI_4
-mvi r1, 1
-addi r3, r1, -1
-check_r3 0
-
-test_name ADDI_5
-mvi r1, -1
-addi r3, r1, 1
-check_r3 0
-
-test_name ADDI_6
-mvi r1, -1
-addi r3, r1, 0
-check_r3 -1
-
-test_name ADDI_7
-mvi r1, 0
-addi r3, r1, -1
-check_r3 -1
-
-test_name ADDI_8
-mvi r3, 4
-addi r3, r3, 4
-check_r3 8
-
-test_name ADDI_9
-mvi r3, 4
-addi r3, r3, -4
-check_r3 0
-
-test_name ADDI_10
-mvi r3, 4
-addi r3, r3, -5
-check_r3 -1
-
-end
-
diff --git a/tests/tcg/lm32/test_and.S b/tests/tcg/lm32/test_and.S
deleted file mode 100644
index 80962ce7a2..0000000000
--- a/tests/tcg/lm32/test_and.S
+++ /dev/null
@@ -1,45 +0,0 @@
-.include "macros.inc"
-
-start
-
-test_name AND_1
-mvi r1, 0
-mvi r2, 0
-and r3, r1, r2
-check_r3 0
-
-test_name AND_2
-mvi r1, 0
-mvi r2, 1
-and r3, r1, r2
-check_r3 0
-
-test_name AND_3
-mvi r1, 1
-mvi r2, 1
-and r3, r1, r2
-check_r3 1
-
-test_name AND_4
-mvi r3, 7
-and r3, r3, r3
-check_r3 7
-
-test_name AND_5
-mvi r1, 7
-and r3, r1, r1
-check_r3 7
-
-test_name AND_6
-mvi r1, 7
-mvi r3, 0
-and r3, r1, r3
-check_r3 0
-
-test_name AND_7
-load r1 0xaa55aa55
-load r2 0x55aa55aa
-and r3, r1, r2
-check_r3 0
-
-end
diff --git a/tests/tcg/lm32/test_andhi.S b/tests/tcg/lm32/test_andhi.S
deleted file mode 100644
index 4f73af550b..0000000000
--- a/tests/tcg/lm32/test_andhi.S
+++ /dev/null
@@ -1,35 +0,0 @@
-.include "macros.inc"
-
-start
-
-test_name ANDHI_1
-mvi r1, 0
-andhi r3, r1, 0
-check_r3 0
-
-test_name ANDHI_2
-mvi r1, 1
-andhi r3, r1, 1
-check_r3 0
-
-test_name ANDHI_3
-load r1 0x000f0000
-andhi r3, r1, 1
-check_r3 0x00010000
-
-test_name ANDHI_4
-load r1 0xffffffff
-andhi r3, r1, 0xffff
-check_r3 0xffff0000
-
-test_name ANDHI_5
-load r1 0xffffffff
-andhi r3, r1, 0
-check_r3 0
-
-test_name ANDHI_6
-load r3 0x55aaffff
-andhi r3, r3, 0xaaaa
-check_r3 0x00aa0000
-
-end
diff --git a/tests/tcg/lm32/test_andi.S b/tests/tcg/lm32/test_andi.S
deleted file mode 100644
index da1b0a32f7..0000000000
--- a/tests/tcg/lm32/test_andi.S
+++ /dev/null
@@ -1,35 +0,0 @@
-.include "macros.inc"
-
-start
-
-test_name ANDI_1
-mvi r1, 0
-andi r3, r1, 0
-check_r3 0
-
-test_name ANDI_2
-mvi r1, 1
-andi r3, r1, 1
-check_r3 1
-
-test_name ANDI_3
-load r1 0x000f0000
-andi r3, r1, 1
-check_r3 0
-
-test_name ANDI_4
-load r1 0xffffffff
-andi r3, r1, 0xffff
-check_r3 0xffff
-
-test_name ANDI_5
-load r1 0xffffffff
-andi r3, r1, 0
-check_r3 0
-
-test_name ANDI_6
-load r3 0xffff55aa
-andi r3, r3, 0xaaaa
-check_r3 0x000000aa
-
-end
diff --git a/tests/tcg/lm32/test_b.S b/tests/tcg/lm32/test_b.S
deleted file mode 100644
index 98172d8a95..0000000000
--- a/tests/tcg/lm32/test_b.S
+++ /dev/null
@@ -1,13 +0,0 @@
-.include "macros.inc"
-
-start
-
-test_name B_1
-load r1 jump
-b r1
-tc_fail
-end
-
-jump:
-tc_pass
-end
diff --git a/tests/tcg/lm32/test_be.S b/tests/tcg/lm32/test_be.S
deleted file mode 100644
index 635cabacad..0000000000
--- a/tests/tcg/lm32/test_be.S
+++ /dev/null
@@ -1,48 +0,0 @@
-.include "macros.inc"
-
-start
-
-test_name BE_1
-mvi r1, 0
-mvi r2, 0
-be r1, r2, 1f
-tc_fail
-bi 2f
-1:
-tc_pass
-2:
-
-test_name BE_2
-mvi r1, 1
-mvi r2, 0
-be r1, r2, 1f
-tc_pass
-bi 2f
-1:
-tc_fail
-2:
-
-test_name BE_3
-mvi r1, 0
-mvi r2, 1
-be r1, r2, 1f
-tc_pass
-bi 2f
-1:
-tc_fail
-2:
-
-bi 2f
-1:
-tc_pass
-bi 3f
-2:
-test_name BE_4
-mvi r1, 1
-mvi r2, 1
-be r1, r2, 1b
-tc_fail
-3:
-
-end
-
diff --git a/tests/tcg/lm32/test_bg.S b/tests/tcg/lm32/test_bg.S
deleted file mode 100644
index 81823c2304..0000000000
--- a/tests/tcg/lm32/test_bg.S
+++ /dev/null
@@ -1,78 +0,0 @@
-.include "macros.inc"
-
-start
-
-test_name BG_1
-mvi r1, 0
-mvi r2, 0
-bg r1, r2, 1f
-tc_pass
-bi 2f
-1:
-tc_fail
-2:
-
-test_name BG_2
-mvi r1, 1
-mvi r2, 0
-bg r1, r2, 1f
-tc_fail
-bi 2f
-1:
-tc_pass
-2:
-
-test_name BG_3
-mvi r1, 0
-mvi r2, 1
-bg r1, r2, 1f
-tc_pass
-bi 2f
-1:
-tc_fail
-2:
-
-test_name BG_4
-mvi r1, 0
-mvi r2, -1
-bg r1, r2, 1f
-tc_fail
-bi 2f
-1:
-tc_pass
-2:
-
-test_name BG_5
-mvi r1, -1
-mvi r2, 0
-bg r1, r2, 1f
-tc_pass
-bi 2f
-1:
-tc_fail
-2:
-
-test_name BG_6
-mvi r1, -1
-mvi r2, -1
-bg r1, r2, 1f
-tc_pass
-bi 2f
-1:
-tc_fail
-2:
-
-bi 2f
-1:
-tc_pass
-bi 3f
-2:
-test_name BG_7
-mvi r1, 1
-mvi r2, 0
-bg r1, r2, 1b
-tc_fail
-3:
-
-end
-
diff --git a/tests/tcg/lm32/test_bge.S b/tests/tcg/lm32/test_bge.S
deleted file mode 100644
index 6684d15a55..0000000000
--- a/tests/tcg/lm32/test_bge.S
+++ /dev/null
@@ -1,78 +0,0 @@
-.include "macros.inc"
-
-start
-
-test_name BGE_1
-mvi r1, 0
-mvi r2, 0
-bge r1, r2, 1f
-tc_fail
-bi 2f
-1:
-tc_pass
-2:
-
-test_name BGE_2
-mvi r1, 1
-mvi r2, 0
-bge r1, r2, 1f
-tc_fail
-bi 2f
-1:
-tc_pass
-2:
-
-test_name BGE_3
-mvi r1, 0
-mvi r2, 1
-bge r1, r2, 1f
-tc_pass
-bi 2f
-1:
-tc_fail
-2:
-
-test_name BGE_4
-mvi r1, 0
-mvi r2, -1
-bge r1, r2, 1f
-tc_fail
-bi 2f
-1:
-tc_pass
-2:
-
-test_name BGE_5
-mvi r1, -1
-mvi r2, 0
-bge r1, r2, 1f
-tc_pass
-bi 2f
-1:
-tc_fail
-2:
-
-test_name BGE_6
-mvi r1, -1
-mvi r2, -1
-bge r1, r2, 1f
-tc_fail
-bi 2f
-1:
-tc_pass
-2:
-
-bi 2f
-1:
-tc_pass
-bi 3f
-2:
-test_name BGE_7
-mvi r1, 1
-mvi r2, 0
-bge r1, r2, 1b
-tc_fail
-3:
-
-end
-
diff --git a/tests/tcg/lm32/test_bgeu.S b/tests/tcg/lm32/test_bgeu.S
deleted file mode 100644
index be440308fd..0000000000
--- a/tests/tcg/lm32/test_bgeu.S
+++ /dev/null
@@ -1,78 +0,0 @@
-.include "macros.inc"
-
-start
-
-test_name BGEU_1
-mvi r1, 0
-mvi r2, 0
-bgeu r1, r2, 1f
-tc_fail
-bi 2f
-1:
-tc_pass
-2:
-
-test_name BGEU_2
-mvi r1, 1
-mvi r2, 0
-bgeu r1, r2, 1f
-tc_fail
-bi 2f
-1:
-tc_pass
-2:
-
-test_name BGEU_3
-mvi r1, 0
-mvi r2, 1
-bgeu r1, r2, 1f
-tc_pass
-bi 2f
-1:
-tc_fail
-2:
-
-test_name BGEU_4
-mvi r1, 0
-mvi r2, -1
-bgeu r1, r2, 1f
-tc_pass
-bi 2f
-1:
-tc_fail
-2:
-
-test_name BGEU_5
-mvi r1, -1
-mvi r2, 0
-bgeu r1, r2, 1f
-tc_fail
-bi 2f
-1:
-tc_pass
-2:
-
-test_name BGEU_6
-mvi r1, -1
-mvi r2, -1
-bgeu r1, r2, 1f
-tc_fail
-bi 2f
-1:
-tc_pass
-2:
-
-bi 2f
-1:
-tc_pass
-bi 3f
-2:
-test_name BGEU_7
-mvi r1, 1
-mvi r2, 0
-bgeu r1, r2, 1b
-tc_fail
-3:
-
-end
-
diff --git a/tests/tcg/lm32/test_bgu.S b/tests/tcg/lm32/test_bgu.S
deleted file mode 100644
index 8cc695b310..0000000000
--- a/tests/tcg/lm32/test_bgu.S
+++ /dev/null
@@ -1,78 +0,0 @@
-.include "macros.inc"
-
-start
-
-test_name BGU_1
-mvi r1, 0
-mvi r2, 0
-bgu r1, r2, 1f
-tc_pass
-bi 2f
-1:
-tc_fail
-2:
-
-test_name BGU_2
-mvi r1, 1
-mvi r2, 0
-bgu r1, r2, 1f
-tc_fail
-bi 2f
-1:
-tc_pass
-2:
-
-test_name BGU_3
-mvi r1, 0
-mvi r2, 1
-bgu r1, r2, 1f
-tc_pass
-bi 2f
-1:
-tc_fail
-2:
-
-test_name BGU_4
-mvi r1, 0
-mvi r2, -1
-bgu r1, r2, 1f
-tc_pass
-bi 2f
-1:
-tc_fail
-2:
-
-test_name BGU_5
-mvi r1, -1
-mvi r2, 0
-bgu r1, r2, 1f
-tc_fail
-bi 2f
-1:
-tc_pass
-2:
-
-test_name BGU_6
-mvi r1, -1
-mvi r2, -1
-bgu r1, r2, 1f
-tc_pass
-bi 2f
-1:
-tc_fail
-2:
-
-bi 2f
-1:
-tc_pass
-bi 3f
-2:
-test_name BGU_7
-mvi r1, 1
-mvi r2, 0
-bgu r1, r2, 1b
-tc_fail
-3:
-
-end
-
diff --git a/tests/tcg/lm32/test_bi.S b/tests/tcg/lm32/test_bi.S
deleted file mode 100644
index a1fbd6fc07..0000000000
--- a/tests/tcg/lm32/test_bi.S
+++ /dev/null
@@ -1,23 +0,0 @@
-.include "macros.inc"
-
-start
-
-test_name BI_1
-bi jump
-tc_fail
-end
-
-jump_back:
-tc_pass
-end
-
-jump:
-tc_pass
-
-test_name BI_2
-bi jump_back
-tc_fail
-
-end
-
-
diff --git a/tests/tcg/lm32/test_bne.S b/tests/tcg/lm32/test_bne.S
deleted file mode 100644
index 871a006755..0000000000
--- a/tests/tcg/lm32/test_bne.S
+++ /dev/null
@@ -1,48 +0,0 @@
-.include "macros.inc"
-
-start
-
-test_name BNE_1
-mvi r1, 0
-mvi r2, 0
-bne r1, r2, 1f
-tc_pass
-bi 2f
-1:
-tc_fail
-2:
-
-test_name BNE_2
-mvi r1, 1
-mvi r2, 0
-bne r1, r2, 1f
-tc_fail
-bi 2f
-1:
-tc_pass
-2:
-
-test_name BNE_3
-mvi r1, 0
-mvi r2, 1
-bne r1, r2, 1f
-tc_fail
-bi 2f
-1:
-tc_pass
-2:
-
-bi 2f
-1:
-tc_fail
-bi 3f
-2:
-test_name BNE_4
-mvi r1, 1
-mvi r2, 1
-bne r1, r2, 1b
-tc_pass
-3:
-
-end
-
diff --git a/tests/tcg/lm32/test_break.S b/tests/tcg/lm32/test_break.S
deleted file mode 100644
index 0384fc6128..0000000000
--- a/tests/tcg/lm32/test_break.S
+++ /dev/null
@@ -1,20 +0,0 @@
-.include "macros.inc"
-
-start
-
-test_name BREAK_1
-mvi r1, 1
-wcsr IE, r1
-insn:
-break
-check_excp 1
-
-test_name BREAK_2
-mv r3, ba
-check_r3 insn
-
-test_name BREAK_3
-rcsr r3, IE
-check_r3 4
-
-end
diff --git a/tests/tcg/lm32/test_bret.S b/tests/tcg/lm32/test_bret.S
deleted file mode 100644
index 645210e434..0000000000
--- a/tests/tcg/lm32/test_bret.S
+++ /dev/null
@@ -1,38 +0,0 @@
-.include "macros.inc"
-
-start
-
-test_name BRET_1
-mvi r1, 4
-wcsr IE, r1
-load ba mark
-bret
-tc_fail
-bi 1f
-
-mark:
-tc_pass
-
-1:
-test_name BRET_2
-rcsr r3, IE
-check_r3 5
-
-test_name BRET_3
-mvi r1, 0
-wcsr IE, r1
-load ba mark2
-bret
-tc_fail
-bi 1f
-
-mark2:
-tc_pass
-
-1:
-test_name BRET_4
-rcsr r3, IE
-check_r3 0
-
-end
-
diff --git a/tests/tcg/lm32/test_call.S b/tests/tcg/lm32/test_call.S
deleted file mode 100644
index 1b91a5f2be..0000000000
--- a/tests/tcg/lm32/test_call.S
+++ /dev/null
@@ -1,16 +0,0 @@
-.include "macros.inc"
-
-start
-
-test_name CALL_1
-load r1 mark
-call r1
-return:
-
-tc_fail
-end
-
-mark:
-mv r3, ra
-check_r3 return
-end
diff --git a/tests/tcg/lm32/test_calli.S b/tests/tcg/lm32/test_calli.S
deleted file mode 100644
index 1d87ae6e21..0000000000
--- a/tests/tcg/lm32/test_calli.S
+++ /dev/null
@@ -1,15 +0,0 @@
-.include "macros.inc"
-
-start
-
-test_name CALLI_1
-calli mark
-return:
-
-tc_fail
-end
-
-mark:
-mv r3, ra
-check_r3 return
-end
diff --git a/tests/tcg/lm32/test_cmpe.S b/tests/tcg/lm32/test_cmpe.S
deleted file mode 100644
index 60a885500b..0000000000
--- a/tests/tcg/lm32/test_cmpe.S
+++ /dev/null
@@ -1,40 +0,0 @@
-.include "macros.inc"
-
-start
-
-test_name CMPE_1
-mvi r1, 0
-mvi r2, 0
-cmpe r3, r1, r2
-check_r3 1
-
-test_name CMPE_2
-mvi r1, 0
-mvi r2, 1
-cmpe r3, r1, r2
-check_r3 0
-
-test_name CMPE_3
-mvi r1, 1
-mvi r2, 0
-cmpe r3, r1, r2
-check_r3 0
-
-test_name CMPE_4
-mvi r3, 0
-mvi r2, 1
-cmpe r3, r3, r2
-check_r3 0
-
-test_name CMPE_5
-mvi r3, 0
-mvi r2, 0
-cmpe r3, r3, r2
-check_r3 1
-
-test_name CMPE_6
-mvi r3, 0
-cmpe r3, r3, r3
-check_r3 1
-
-end
diff --git a/tests/tcg/lm32/test_cmpei.S b/tests/tcg/lm32/test_cmpei.S
deleted file mode 100644
index c3d3566ad3..0000000000
--- a/tests/tcg/lm32/test_cmpei.S
+++ /dev/null
@@ -1,35 +0,0 @@
-.include "macros.inc"
-
-start
-
-test_name CMPEI_1
-mvi r1, 0
-cmpei r3, r1, 0
-check_r3 1
-
-test_name CMPEI_2
-mvi r1, 0
-cmpei r3, r1, 1
-check_r3 0
-
-test_name CMPEI_3
-mvi r1, 1
-cmpei r3, r1, 0
-check_r3 0
-
-test_name CMPEI_4
-load r1 0xffffffff
-cmpei r3, r1, -1
-check_r3 1
-
-test_name CMPEI_5
-mvi r3, 0
-cmpei r3, r3, 0
-check_r3 1
-
-test_name CMPEI_6
-mvi r3, 0
-cmpei r3, r3, 1
-check_r3 0
-
-end
diff --git a/tests/tcg/lm32/test_cmpg.S b/tests/tcg/lm32/test_cmpg.S
deleted file mode 100644
index 012407874c..0000000000
--- a/tests/tcg/lm32/test_cmpg.S
+++ /dev/null
@@ -1,64 +0,0 @@
-.include "macros.inc"
-
-start
-
-test_name CMPG_1
-mvi r1, 0
-mvi r2, 0
-cmpg r3, r1, r2
-check_r3 0
-
-test_name CMPG_2
-mvi r1, 0
-mvi r2, 1
-cmpg r3, r1, r2
-check_r3 0
-
-test_name CMPG_3
-mvi r1, 1
-mvi r2, 0
-cmpg r3, r1, r2
-check_r3 1
-
-test_name CMPG_4
-mvi r1, 1
-mvi r2, 1
-cmpg r3, r1, r2
-check_r3 0
-
-test_name CMPG_5
-mvi r1, 0
-mvi r2, -1
-cmpg r3, r1, r2
-check_r3 1
-
-test_name CMPG_6
-mvi r1, -1
-mvi r2, 0
-cmpg r3, r1, r2
-check_r3 0
-
-test_name CMPG_7
-mvi r1, -1
-mvi r2, -1
-cmpg r3, r1, r2
-check_r3 0
-
-test_name CMPG_8
-mvi r3, 0
-mvi r2, 1
-cmpg r3, r3, r2
-check_r3 0
-
-test_name CMPG_9
-mvi r3, 1
-mvi r2, 0
-cmpg r3, r3, r2
-check_r3 1
-
-test_name CMPG_10
-mvi r3, 0
-cmpg r3, r3, r3
-check_r3 0
-
-end
diff --git a/tests/tcg/lm32/test_cmpge.S b/tests/tcg/lm32/test_cmpge.S
deleted file mode 100644
index 84620a00e3..0000000000
--- a/tests/tcg/lm32/test_cmpge.S
+++ /dev/null
@@ -1,64 +0,0 @@
-.include "macros.inc"
-
-start
-
-test_name CMPGE_1
-mvi r1, 0
-mvi r2, 0
-cmpge r3, r1, r2
-check_r3 1
-
-test_name CMPGE_2
-mvi r1, 0
-mvi r2, 1
-cmpge r3, r1, r2
-check_r3 0
-
-test_name CMPGE_3
-mvi r1, 1
-mvi r2, 0
-cmpge r3, r1, r2
-check_r3 1
-
-test_name CMPGE_4
-mvi r1, 1
-mvi r2, 1
-cmpge r3, r1, r2
-check_r3 1
-
-test_name CMPGE_5
-mvi r1, 0
-mvi r2, -1
-cmpge r3, r1, r2
-check_r3 1
-
-test_name CMPGE_6
-mvi r1, -1
-mvi r2, 0
-cmpge r3, r1, r2
-check_r3 0
-
-test_name CMPGE_7
-mvi r1, -1
-mvi r2, -1
-cmpge r3, r1, r2
-check_r3 1
-
-test_name CMPGE_8
-mvi r3, 0
-mvi r2, 1
-cmpge r3, r3, r2
-check_r3 0
-
-test_name CMPGE_9
-mvi r3, 1
-mvi r2, 0
-cmpge r3, r3, r2
-check_r3 1
-
-test_name CMPGE_10
-mvi r3, 0
-cmpge r3, r3, r3
-check_r3 1
-
-end
diff --git a/tests/tcg/lm32/test_cmpgei.S b/tests/tcg/lm32/test_cmpgei.S
deleted file mode 100644
index 6e388a2a35..0000000000
--- a/tests/tcg/lm32/test_cmpgei.S
+++ /dev/null
@@ -1,70 +0,0 @@
-.include "macros.inc"
-
-start
-
-test_name CMPGEI_1
-mvi r1, 0
-cmpgei r3, r1, 0
-check_r3 1
-
-test_name CMPGEI_2
-mvi r1, 0
-cmpgei r3, r1, 1
-check_r3 0
-
-test_name CMPGEI_3
-mvi r1, 1
-cmpgei r3, r1, 0
-check_r3 1
-
-test_name CMPGEI_4
-mvi r1, 1
-cmpgei r3, r1, 1
-check_r3 1
-
-test_name CMPGEI_5
-mvi r1, 0
-cmpgei r3, r1, -1
-check_r3 1
-
-test_name CMPGEI_6
-mvi r1, -1
-cmpgei r3, r1, 0
-check_r3 0
-
-test_name CMPGEI_7
-mvi r1, -1
-cmpgei r3, r1, -1
-check_r3 1
-
-test_name CMPGEI_8
-mvi r3, 0
-cmpgei r3, r3, 1
-check_r3 0
-
-test_name CMPGEI_9
-mvi r3, 1
-cmpgei r3, r3, 0
-check_r3 1
-
-test_name CMPGEI_10
-mvi r3, 0
-cmpgei r3, r3, 0
-check_r3 1
-
-test_name CMPGEI_11
-mvi r1, 0
-cmpgei r3, r1, -32768
-check_r3 1
-
-test_name CMPGEI_12
-mvi r1, -1
-cmpgei r3, r1, -32768
-check_r3 1
-
-test_name CMPGEI_13
-mvi r1, -32768
-cmpgei r3, r1, -32768
-check_r3 1
-
-end
diff --git a/tests/tcg/lm32/test_cmpgeu.S b/tests/tcg/lm32/test_cmpgeu.S
deleted file mode 100644
index 2110ccb6b7..0000000000
--- a/tests/tcg/lm32/test_cmpgeu.S
+++ /dev/null
@@ -1,64 +0,0 @@
-.include "macros.inc"
-
-start
-
-test_name CMPGEU_1
-mvi r1, 0
-mvi r2, 0
-cmpgeu r3, r1, r2
-check_r3 1
-
-test_name CMPGEU_2
-mvi r1, 0
-mvi r2, 1
-cmpgeu r3, r1, r2
-check_r3 0
-
-test_name CMPGEU_3
-mvi r1, 1
-mvi r2, 0
-cmpgeu r3, r1, r2
-check_r3 1
-
-test_name CMPGEU_4
-mvi r1, 1
-mvi r2, 1
-cmpgeu r3, r1, r2
-check_r3 1
-
-test_name CMPGEU_5
-mvi r1, 0
-mvi r2, -1
-cmpgeu r3, r1, r2
-check_r3 0
-
-test_name CMPGEU_6
-mvi r1, -1
-mvi r2, 0
-cmpgeu r3, r1, r2
-check_r3 1
-
-test_name CMPGEU_7
-mvi r1, -1
-mvi r2, -1
-cmpgeu r3, r1, r2
-check_r3 1
-
-test_name CMPGEU_8
-mvi r3, 0
-mvi r2, 1
-cmpgeu r3, r3, r2
-check_r3 0
-
-test_name CMPGEU_9
-mvi r3, 1
-mvi r2, 0
-cmpgeu r3, r3, r2
-check_r3 1
-
-test_name CMPGEU_10
-mvi r3, 0
-cmpgeu r3, r3, r3
-check_r3 1
-
-end
diff --git a/tests/tcg/lm32/test_cmpgeui.S b/tests/tcg/lm32/test_cmpgeui.S
deleted file mode 100644
index 3866d96cb7..0000000000
--- a/tests/tcg/lm32/test_cmpgeui.S
+++ /dev/null
@@ -1,70 +0,0 @@
-.include "macros.inc"
-
-start
-
-test_name CMPGEUI_1
-mvi r1, 0
-cmpgeui r3, r1, 0
-check_r3 1
-
-test_name CMPGEUI_2
-mvi r1, 0
-cmpgeui r3, r1, 1
-check_r3 0
-
-test_name CMPGEUI_3
-mvi r1, 1
-cmpgeui r3, r1, 0
-check_r3 1
-
-test_name CMPGEUI_4
-mvi r1, 1
-cmpgeui r3, r1, 1
-check_r3 1
-
-test_name CMPGEUI_5
-mvi r1, 0
-cmpgeui r3, r1, 0xffff
-check_r3 0
-
-test_name CMPGEUI_6
-mvi r1, -1
-cmpgeui r3, r1, 0
-check_r3 1
-
-test_name CMPGEUI_7
-mvi r1, -1
-cmpgeui r3, r1, 0xffff
-check_r3 1
-
-test_name CMPGEUI_8
-mvi r3, 0
-cmpgeui r3, r3, 1
-check_r3 0
-
-test_name CMPGEUI_9
-mvi r3, 1
-cmpgeui r3, r3, 0
-check_r3 1
-
-test_name CMPGEUI_10
-mvi r3, 0
-cmpgeui r3, r3, 0
-check_r3 1
-
-test_name CMPGEUI_11
-mvi r1, 0
-cmpgeui r3, r1, 0x8000
-check_r3 0
-
-test_name CMPGEUI_12
-mvi r1, -1
-cmpgeui r3, r1, 0x8000
-check_r3 1
-
-test_name CMPGEUI_13
-ori r1, r0, 0x8000
-cmpgeui r3, r1, 0x8000
-check_r3 1
-
-end
diff --git a/tests/tcg/lm32/test_cmpgi.S b/tests/tcg/lm32/test_cmpgi.S
deleted file mode 100644
index 21695f97ab..0000000000
--- a/tests/tcg/lm32/test_cmpgi.S
+++ /dev/null
@@ -1,70 +0,0 @@
-.include "macros.inc"
-
-start
-
-test_name CMPGI_1
-mvi r1, 0
-cmpgi r3, r1, 0
-check_r3 0
-
-test_name CMPGI_2
-mvi r1, 0
-cmpgi r3, r1, 1
-check_r3 0
-
-test_name CMPGI_3
-mvi r1, 1
-cmpgi r3, r1, 0
-check_r3 1
-
-test_name CMPGI_4
-mvi r1, 1
-cmpgi r3, r1, 1
-check_r3 0
-
-test_name CMPGI_5
-mvi r1, 0
-cmpgi r3, r1, -1
-check_r3 1
-
-test_name CMPGI_6
-mvi r1, -1
-cmpgi r3, r1, 0
-check_r3 0
-
-test_name CMPGI_7
-mvi r1, -1
-cmpgi r3, r1, -1
-check_r3 0
-
-test_name CMPGI_8
-mvi r3, 0
-cmpgi r3, r3, 1
-check_r3 0
-
-test_name CMPGI_9
-mvi r3, 1
-cmpgi r3, r3, 0
-check_r3 1
-
-test_name CMPGI_10
-mvi r3, 0
-cmpgi r3, r3, 0
-check_r3 0
-
-test_name CMPGI_11
-mvi r1, 0
-cmpgi r3, r1, -32768
-check_r3 1
-
-test_name CMPGI_12
-mvi r1, -1
-cmpgi r3, r1, -32768
-check_r3 1
-
-test_name CMPGI_13
-mvi r1, -32768
-cmpgi r3, r1, -32768
-check_r3 0
-
-end
diff --git a/tests/tcg/lm32/test_cmpgu.S b/tests/tcg/lm32/test_cmpgu.S
deleted file mode 100644
index dd465471ea..0000000000
--- a/tests/tcg/lm32/test_cmpgu.S
+++ /dev/null
@@ -1,64 +0,0 @@
-.include "macros.inc"
-
-start
-
-test_name CMPGU_1
-mvi r1, 0
-mvi r2, 0
-cmpgu r3, r1, r2
-check_r3 0
-
-test_name CMPGU_2
-mvi r1, 0
-mvi r2, 1
-cmpgu r3, r1, r2
-check_r3 0
-
-test_name CMPGU_3
-mvi r1, 1
-mvi r2, 0
-cmpgu r3, r1, r2
-check_r3 1
-
-test_name CMPGU_4
-mvi r1, 1
-mvi r2, 1
-cmpgu r3, r1, r2
-check_r3 0
-
-test_name CMPGU_5
-mvi r1, 0
-mvi r2, -1
-cmpgu r3, r1, r2
-check_r3 0
-
-test_name CMPGU_6
-mvi r1, -1
-mvi r2, 0
-cmpgu r3, r1, r2
-check_r3 1
-
-test_name CMPGU_7
-mvi r1, -1
-mvi r2, -1
-cmpgu r3, r1, r2
-check_r3 0
-
-test_name CMPGU_8
-mvi r3, 0
-mvi r2, 1
-cmpgu r3, r3, r2
-check_r3 0
-
-test_name CMPGU_9
-mvi r3, 1
-mvi r2, 0
-cmpgu r3, r3, r2
-check_r3 1
-
-test_name CMPGU_10
-mvi r3, 0
-cmpgu r3, r3, r3
-check_r3 0
-
-end
diff --git a/tests/tcg/lm32/test_cmpgui.S b/tests/tcg/lm32/test_cmpgui.S
deleted file mode 100644
index dd94001492..0000000000
--- a/tests/tcg/lm32/test_cmpgui.S
+++ /dev/null
@@ -1,70 +0,0 @@
-.include "macros.inc"
-
-start
-
-test_name CMPGUI_1
-mvi r1, 0
-cmpgui r3, r1, 0
-check_r3 0
-
-test_name CMPGUI_2
-mvi r1, 0
-cmpgui r3, r1, 1
-check_r3 0
-
-test_name CMPGUI_3
-mvi r1, 1
-cmpgui r3, r1, 0
-check_r3 1
-
-test_name CMPGUI_4
-mvi r1, 1
-cmpgui r3, r1, 1
-check_r3 0
-
-test_name CMPGUI_5
-mvi r1, 0
-cmpgui r3, r1, 0xffff
-check_r3 0
-
-test_name CMPGUI_6
-mvi r1, -1
-cmpgui r3, r1, 0
-check_r3 1
-
-test_name CMPGUI_7
-mvi r1, -1
-cmpgui r3, r1, 0xffff
-check_r3 1
-
-test_name CMPGUI_8
-mvi r3, 0
-cmpgui r3, r3, 1
-check_r3 0
-
-test_name CMPGUI_9
-mvi r3, 1
-cmpgui r3, r3, 0
-check_r3 1
-
-test_name CMPGUI_10
-mvi r3, 0
-cmpgui r3, r3, 0
-check_r3 0
-
-test_name CMPGUI_11
-mvi r1, 0
-cmpgui r3, r1, 0x8000
-check_r3 0
-
-test_name CMPGUI_12
-mvi r1, -1
-cmpgui r3, r1, 0x8000
-check_r3 1
-
-test_name CMPGUI_13
-ori r1, r0, 0x8000
-cmpgui r3, r1, 0x8000
-check_r3 0
-
-end
diff --git a/tests/tcg/lm32/test_cmpne.S b/tests/tcg/lm32/test_cmpne.S
deleted file mode 100644
index 0f1078114c..0000000000
--- a/tests/tcg/lm32/test_cmpne.S
+++ /dev/null
@@ -1,40 +0,0 @@
-.include "macros.inc"
-
-start
-
-test_name CMPNE_1
-mvi r1, 0
-mvi r2, 0
-cmpne r3, r1, r2
-check_r3 0
-
-test_name CMPNE_2
-mvi r1, 0
-mvi r2, 1
-cmpne r3, r1, r2
-check_r3 1
-
-test_name CMPNE_3
-mvi r1, 1
-mvi r2, 0
-cmpne r3, r1, r2
-check_r3 1
-
-test_name CMPNE_4
-mvi r3, 0
-mvi r2, 1
-cmpne r3, r3, r2
-check_r3 1
-
-test_name CMPNE_5
-mvi r3, 0
-mvi r2, 0
-cmpne r3, r3, r2
-check_r3 0
-
-test_name CMPNE_6
-mvi r3, 0
-cmpne r3, r3, r3
-check_r3 0
-
-end
diff --git a/tests/tcg/lm32/test_cmpnei.S b/tests/tcg/lm32/test_cmpnei.S
deleted file mode 100644
index 060dd9d394..0000000000
--- a/tests/tcg/lm32/test_cmpnei.S
+++ /dev/null
@@ -1,35 +0,0 @@
-.include "macros.inc"
-
-start
-
-test_name CMPNEI_1
-mvi r1, 0
-cmpnei r3, r1, 0
-check_r3 0
-
-test_name CMPNEI_2
-mvi r1, 0
-cmpnei r3, r1, 1
-check_r3 1
-
-test_name CMPNEI_3
-mvi r1, 1
-cmpnei r3, r1, 0
-check_r3 1
-
-test_name CMPNEI_4
-load r1 0xffffffff
-cmpnei r3, r1, -1
-check_r3 0
-
-test_name CMPNEI_5
-mvi r3, 0
-cmpnei r3, r3, 0
-check_r3 0
-
-test_name CMPNEI_6
-mvi r3, 0
-cmpnei r3, r3, 1
-check_r3 1
-
-end
diff --git a/tests/tcg/lm32/test_divu.S b/tests/tcg/lm32/test_divu.S
deleted file mode 100644
index f381d095c5..0000000000
--- a/tests/tcg/lm32/test_divu.S
+++ /dev/null
@@ -1,29 +0,0 @@
-.include "macros.inc"
-
-start
-
-test_name DIVU_1
-mvi r1, 0
-mvi r2, 1
-divu r3, r1, r2
-check_r3 0
-
-test_name DIVU_2
-mvi r1, 1
-mvi r2, 1
-divu r3, r1, r2
-check_r3 1
-
-test_name DIVU_3
-mvi r1, 0
-mvi r2, 0
-divu r3, r1, r2
-check_excp 16
-
-test_name DIVU_4
-load r1 0xabcdef12
-load r2 0x12345
-divu r3, r1, r2
-check_r3 0x9700
-
-end
diff --git a/tests/tcg/lm32/test_eret.S b/tests/tcg/lm32/test_eret.S
deleted file mode 100644
index 6830bd1abf..0000000000
--- a/tests/tcg/lm32/test_eret.S
+++ /dev/null
@@ -1,38 +0,0 @@
-.include "macros.inc"
-
-start
-
-test_name ERET_1
-mvi r1, 2
-wcsr IE, r1
-load ea mark
-eret
-tc_fail
-bi 1f
-
-mark:
-tc_pass
-
-1:
-test_name ERET_2
-rcsr r3, IE
-check_r3 3
-
-test_name ERET_3
-mvi r1, 0
-wcsr IE, r1
-load ea mark2
-eret
-tc_fail
-bi 1f
-
-mark2:
-tc_pass
-
-1:
-test_name ERET_4
-rcsr r3, IE
-check_r3 0
-
-end
-
diff --git a/tests/tcg/lm32/test_lb.S b/tests/tcg/lm32/test_lb.S
deleted file mode 100644
index d677eea4c4..0000000000
--- a/tests/tcg/lm32/test_lb.S
+++ /dev/null
@@ -1,49 +0,0 @@
-.include "macros.inc"
-
-start
-
-test_name LB_1
-load r1 data
-lb r3, (r1+0)
-check_r3 0x7e
-
-test_name LB_2
-load r1 data
-lb r3, (r1+1)
-check_r3 0x7f
-
-test_name LB_3
-load r1 data
-lb r3, (r1+-1)
-check_r3 0x7d
-
-test_name LB_4
-load r1 data_msb
-lb r3, (r1+0)
-check_r3 0xfffffffe
-
-test_name LB_5
-load r1 data_msb
-lb r3, (r1+1)
-check_r3 0xffffffff
-
-test_name LB_6
-load r1 data_msb
-lb r3, (r1+-1)
-check_r3 0xfffffffd
-
-test_name LB_7
-load r3 data
-lb r3, (r3+0)
-check_r3 0x7e
-
-end
-
-.data
- .align 4
- .byte 0x7a, 0x7b, 0x7c, 0x7d
-data:
- .byte 0x7e, 0x7f, 0x70, 0x71
- .byte 0xfa, 0xfb, 0xfc, 0xfd
-data_msb:
- .byte 0xfe, 0xff, 0xf0, 0xf1
diff --git a/tests/tcg/lm32/test_lbu.S b/tests/tcg/lm32/test_lbu.S
deleted file mode 100644
index dc5d5f67d3..0000000000
--- a/tests/tcg/lm32/test_lbu.S
+++ /dev/null
@@ -1,49 +0,0 @@
-.include "macros.inc"
-
-start
-
-test_name LBU_1
-load r1 data
-lbu r3, (r1+0)
-check_r3 0x7e
-
-test_name LBU_2
-load r1 data
-lbu r3, (r1+1)
-check_r3 0x7f
-
-test_name LBU_3
-load r1 data
-lbu r3, (r1+-1)
-check_r3 0x7d
-
-test_name LBU_4
-load r1 data_msb
-lbu r3, (r1+0)
-check_r3 0xfe
-
-test_name LBU_5
-load r1 data_msb
-lbu r3, (r1+1)
-check_r3 0xff
-
-test_name LBU_6
-load r1 data_msb
-lbu r3, (r1+-1)
-check_r3 0xfd
-
-test_name LBU_7
-load r3 data
-lbu r3, (r3+0)
-check_r3 0x7e
-
-end
-
-.data
- .align 4
- .byte 0x7a, 0x7b, 0x7c, 0x7d
-data:
- .byte 0x7e, 0x7f, 0x70, 0x71
- .byte 0xfa, 0xfb, 0xfc, 0xfd
-data_msb:
- .byte 0xfe, 0xff, 0xf0, 0xf1
diff --git a/tests/tcg/lm32/test_lh.S b/tests/tcg/lm32/test_lh.S
deleted file mode 100644
index 397996bddd..0000000000
--- a/tests/tcg/lm32/test_lh.S
+++ /dev/null
@@ -1,49 +0,0 @@
-.include "macros.inc"
-
-start
-
-test_name LH_1
-load r1 data
-lh r3, (r1+0)
-check_r3 0x7e7f
-
-test_name LH_2
-load r1 data
-lh r3, (r1+2)
-check_r3 0x7071
-
-test_name LH_3
-load r1 data
-lh r3, (r1+-2)
-check_r3 0x7c7d
-
-test_name LH_4
-load r1 data_msb
-lh r3, (r1+0)
-check_r3 0xfffffeff
-
-test_name LH_5
-load r1 data_msb
-lh r3, (r1+2)
-check_r3 0xfffff0f1
-
-test_name LH_6
-load r1 data_msb
-lh r3, (r1+-2)
-check_r3 0xfffffcfd
-
-test_name LH_7
-load r3 data
-lh r3, (r3+0)
-check_r3 0x7e7f
-
-end
-
-.data
- .align 4
- .byte 0x7a, 0x7b, 0x7c, 0x7d
-data:
- .byte 0x7e, 0x7f, 0x70, 0x71
- .byte 0xfa, 0xfb, 0xfc, 0xfd
-data_msb:
- .byte 0xfe, 0xff, 0xf0, 0xf1
diff --git a/tests/tcg/lm32/test_lhu.S b/tests/tcg/lm32/test_lhu.S
deleted file mode 100644
index 8de7c52560..0000000000
--- a/tests/tcg/lm32/test_lhu.S
+++ /dev/null
@@ -1,49 +0,0 @@
-.include "macros.inc"
-
-start
-
-test_name LHU_1
-load r1 data
-lhu r3, (r1+0)
-check_r3 0x7e7f
-
-test_name LHU_2
-load r1 data
-lhu r3, (r1+2)
-check_r3 0x7071
-
-test_name LHU_3
-load r1 data
-lhu r3, (r1+-2)
-check_r3 0x7c7d
-
-test_name LHU_4
-load r1 data_msb
-lhu r3, (r1+0)
-check_r3 0xfeff
-
-test_name LHU_5
-load r1 data_msb
-lhu r3, (r1+2)
-check_r3 0xf0f1
-
-test_name LHU_6
-load r1 data_msb
-lhu r3, (r1+-2)
-check_r3 0xfcfd
-
-test_name LHU_7
-load r3 data
-lhu r3, (r3+0)
-check_r3 0x7e7f
-
-end
-
-.data
- .align 4
- .byte 0x7a, 0x7b, 0x7c, 0x7d
-data:
- .byte 0x7e, 0x7f, 0x70, 0x71
- .byte 0xfa, 0xfb, 0xfc, 0xfd
-data_msb:
- .byte 0xfe, 0xff, 0xf0, 0xf1
diff --git a/tests/tcg/lm32/test_lw.S b/tests/tcg/lm32/test_lw.S
deleted file mode 100644
index 996e5f8c88..0000000000
--- a/tests/tcg/lm32/test_lw.S
+++ /dev/null
@@ -1,32 +0,0 @@
-.include "macros.inc"
-
-start
-
-test_name LW_1
-load r1 data
-lw r3, (r1+0)
-check_r3 0x7e7f7071
-
-test_name LW_2
-load r1 data
-lw r3, (r1+4)
-check_r3 0x72737475
-
-test_name LW_3
-load r1 data
-lw r3, (r1+-4)
-check_r3 0x7a7b7c7d
-
-test_name LW_4
-load r3 data
-lw r3, (r3+0)
-check_r3 0x7e7f7071
-
-end
-
-.data
- .align 4
- .byte 0x7a, 0x7b, 0x7c, 0x7d
-data:
- .byte 0x7e, 0x7f, 0x70, 0x71
- .byte 0x72, 0x73, 0x74, 0x75
diff --git a/tests/tcg/lm32/test_modu.S b/tests/tcg/lm32/test_modu.S
deleted file mode 100644
index 42486900b4..0000000000
--- a/tests/tcg/lm32/test_modu.S
+++ /dev/null
@@ -1,35 +0,0 @@
-.include "macros.inc"
-
-start
-
-test_name MODU_1
-mvi r1, 0
-mvi r2, 1
-modu r3, r1, r2
-check_r3 0
-
-test_name MODU_2
-mvi r1, 1
-mvi r2, 1
-modu r3, r1, r2
-check_r3 0
-
-test_name MODU_3
-mvi r1, 3
-mvi r2, 2
-modu r3, r1, r2
-check_r3 1
-
-test_name MODU_4
-mvi r1, 0
-mvi r2, 0
-modu r3, r1, r2
-check_excp 16
-
-test_name MODU_5
-load r1 0xabcdef12
-load r2 0x12345
-modu r3, r1, r2
-check_r3 0x3c12
-
-end
diff --git a/tests/tcg/lm32/test_mul.S b/tests/tcg/lm32/test_mul.S
deleted file mode 100644
index e9b937e648..0000000000
--- a/tests/tcg/lm32/test_mul.S
+++ /dev/null
@@ -1,70 +0,0 @@
-.include "macros.inc"
-
-start
-
-test_name MUL_1
-mvi r1, 0
-mvi r2, 0
-mul r3, r1, r2
-check_r3 0
-
-test_name MUL_2
-mvi r1, 1
-mvi r2, 0
-mul r3, r1, r2
-check_r3 0
-
-test_name MUL_3
-mvi r1, 0
-mvi r2, 1
-mul r3, r1, r2
-check_r3 0
-
-test_name MUL_4
-mvi r1, 1
-mvi r2, 1
-mul r3, r1, r2
-check_r3 1
-
-test_name MUL_5
-mvi r1, 2
-mvi r2, -1
-mul r3, r1, r2
-check_r3 -2
-
-test_name MUL_6
-mvi r1, -2
-mvi r2, -1
-mul r3, r1, r2
-check_r3 2
-
-test_name MUL_7
-mvi r1, 0x1234
-mvi r2, 0x789
-mul r3, r1, r2
-check_r3 0x8929d4
-
-test_name MUL_8
-mvi r3, 4
-mul r3, r3, r3
-check_r3 16
-
-test_name MUL_9
-mvi r2, 2
-mvi r3, 4
-mul r3, r3, r2
-check_r3 8
-
-test_name MUL_10
-load r1 0x12345678
-load r2 0x7bcdef12
-mul r3, r1, r2
-check_r3 0xa801c70
-
-test_name MUL_11
-load r1 0x12345678
-load r2 0xabcdef12
-mul r3, r1, r2
-check_r3 0x8a801c70
-
-end
diff --git a/tests/tcg/lm32/test_muli.S b/tests/tcg/lm32/test_muli.S
deleted file mode 100644
index d6dd4a0f7e..0000000000
--- a/tests/tcg/lm32/test_muli.S
+++ /dev/null
@@ -1,45 +0,0 @@
-.include "macros.inc"
-
-start
-
-test_name MULI_1
-mvi r1, 0
-muli r3, r1, 0
-check_r3 0
-
-test_name MULI_2
-mvi r1, 1
-muli r3, r1, 0
-check_r3 0
-
-test_name MULI_3
-mvi r1, 0
-muli r3, r1, 1
-check_r3 0
-
-test_name MULI_4
-mvi r1, 1
-muli r3, r1, 1
-check_r3 1
-
-test_name MULI_5
-mvi r1, 2
-muli r3, r1, -1
-check_r3 -2
-
-test_name MULI_6
-mvi r1, -2
-muli r3, r1, -1
-check_r3 2
-
-test_name MULI_7
-mvi r1, 0x1234
-muli r3, r1, 0x789
-check_r3 0x8929d4
-
-test_name MULI_8
-mvi r3, 4
-muli r3, r3, 4
-check_r3 16
-
-end
diff --git a/tests/tcg/lm32/test_nor.S b/tests/tcg/lm32/test_nor.S
deleted file mode 100644
index 74d7592565..0000000000
--- a/tests/tcg/lm32/test_nor.S
+++ /dev/null
@@ -1,51 +0,0 @@
-.include "macros.inc"
-
-start
-
-test_name NOR_1
-mvi r1, 0
-mvi r2, 0
-nor r3, r1, r2
-check_r3 0xffffffff
-
-test_name NOR_2
-mvi r1, 0
-mvi r2, 1
-nor r3, r1, r2
-check_r3 0xfffffffe
-
-test_name NOR_3
-mvi r1, 1
-mvi r2, 1
-nor r3, r1, r2
-check_r3 0xfffffffe
-
-test_name NOR_4
-mvi r1, 1
-mvi r2, 0
-nor r3, r1, r2
-check_r3 0xfffffffe
-
-test_name NOR_5
-load r1 0xaa55aa55
-load r2 0x55aa55aa
-nor r3, r1, r2
-check_r3 0
-
-test_name NOR_6
-load r1 0xaa550000
-load r2 0x0000aa55
-nor r3, r1, r2
-check_r3 0x55aa55aa
-
-test_name NOR_7
-load r1 0xaa55aa55
-nor r3, r1, r1
-check_r3 0x55aa55aa
-
-test_name NOR_8
-load r3 0xaa55aa55
-nor r3, r3, r3
-check_r3 0x55aa55aa
-
-end
diff --git a/tests/tcg/lm32/test_nori.S b/tests/tcg/lm32/test_nori.S
deleted file mode 100644
index d00309c73e..0000000000
--- a/tests/tcg/lm32/test_nori.S
+++ /dev/null
@@ -1,35 +0,0 @@
-.include "macros.inc"
-
-start
-
-test_name NORI_1
-mvi r1, 0
-nori r3, r1, 0
-check_r3 0xffffffff
-
-test_name NORI_2
-mvi r1, 0
-nori r3, r1, 1
-check_r3 0xfffffffe
-
-test_name NORI_3
-mvi r1, 1
-nori r3, r1, 1
-check_r3 0xfffffffe
-
-test_name NORI_4
-mvi r1, 1
-nori r3, r1, 0
-check_r3 0xfffffffe
-
-test_name NORI_5
-load r1 0xaa55aa55
-nori r3, r1, 0x55aa
-check_r3 0x55aa0000
-
-test_name NORI_6
-load r3 0xaa55aa55
-nori r3, r3, 0x55aa
-check_r3 0x55aa0000
-
-end
diff --git a/tests/tcg/lm32/test_or.S b/tests/tcg/lm32/test_or.S
deleted file mode 100644
index 4ed292330e..0000000000
--- a/tests/tcg/lm32/test_or.S
+++ /dev/null
@@ -1,51 +0,0 @@
-.include "macros.inc"
-
-start
-
-test_name OR_1
-mvi r1, 0
-mvi r2, 0
-or r3, r1, r2
-check_r3 0
-
-test_name OR_2
-mvi r1, 0
-mvi r2, 1
-or r3, r1, r2
-check_r3 1
-
-test_name OR_3
-mvi r1, 1
-mvi r2, 1
-or r3, r1, r2
-check_r3 1
-
-test_name OR_4
-mvi r1, 1
-mvi r2, 0
-or r3, r1, r2
-check_r3 1
-
-test_name OR_5
-load r1 0xaa55aa55
-load r2 0x55aa55aa
-or r3, r1, r2
-check_r3 0xffffffff
-
-test_name OR_6
-load r1 0xaa550000
-load r2 0x0000aa55
-or r3, r1, r2
-check_r3 0xaa55aa55
-
-test_name OR_7
-load r1 0xaa55aa55
-or r3, r1, r1
-check_r3 0xaa55aa55
-
-test_name OR_8
-load r3 0xaa55aa55
-or r3, r3, r3
-check_r3 0xaa55aa55
-
-end
diff --git a/tests/tcg/lm32/test_orhi.S b/tests/tcg/lm32/test_orhi.S
deleted file mode 100644
index 78b7600e03..0000000000
--- a/tests/tcg/lm32/test_orhi.S
+++ /dev/null
@@ -1,35 +0,0 @@
-.include "macros.inc"
-
-start
-
-test_name ORHI_1
-mvi r1, 0
-orhi r3, r1, 0
-check_r3 0
-
-test_name ORHI_2
-mvi r1, 0
-orhi r3, r1, 1
-check_r3 0x00010000
-
-test_name ORHI_3
-load r1 0x00010000
-orhi r3, r1, 1
-check_r3 0x00010000
-
-test_name ORHI_4
-mvi r1, 1
-orhi r3, r1, 0
-check_r3 1
-
-test_name ORHI_5
-load r1 0xaa55aa55
-orhi r3, r1, 0x55aa
-check_r3 0xffffaa55
-
-test_name ORHI_6
-load r3 0xaa55aa55
-orhi r3, r3, 0x55aa
-check_r3 0xffffaa55
-
-end
diff --git a/tests/tcg/lm32/test_ori.S b/tests/tcg/lm32/test_ori.S
deleted file mode 100644
index 3d576cdb8b..0000000000
--- a/tests/tcg/lm32/test_ori.S
+++ /dev/null
@@ -1,35 +0,0 @@
-.include "macros.inc"
-
-start
-
-test_name ORI_1
-mvi r1, 0
-ori r3, r1, 0
-check_r3 0
-
-test_name ORI_2
-mvi r1, 0
-ori r3, r1, 1
-check_r3 1
-
-test_name ORI_3
-mvi r1, 1
-ori r3, r1, 1
-check_r3 1
-
-test_name ORI_4
-mvi r1, 1
-ori r3, r1, 0
-check_r3 1
-
-test_name ORI_5
-load r1 0xaa55aa55
-ori r3, r1, 0x55aa
-check_r3 0xaa55ffff
-
-test_name ORI_6
-load r3 0xaa55aa55
-ori r3, r3, 0x55aa
-check_r3 0xaa55ffff
-
-end
diff --git a/tests/tcg/lm32/test_ret.S b/tests/tcg/lm32/test_ret.S
deleted file mode 100644
index 320264f148..0000000000
--- a/tests/tcg/lm32/test_ret.S
+++ /dev/null
@@ -1,14 +0,0 @@
-.include "macros.inc"
-
-start
-
-test_name RET_1
-load ra mark
-ret
-
-tc_fail
-end
-
-mark:
-tc_pass
-end
diff --git a/tests/tcg/lm32/test_sb.S b/tests/tcg/lm32/test_sb.S
deleted file mode 100644
index b15a89d342..0000000000
--- a/tests/tcg/lm32/test_sb.S
+++ /dev/null
@@ -1,32 +0,0 @@
-.include "macros.inc"
-
-start
-
-test_name SB_1
-load r1 data
-load r2 0xf0f1f2aa
-sb (r1+0), r2
-check_mem data 0xaa000000
-
-test_name SB_2
-load r1 data
-load r2 0xf0f1f2bb
-sb (r1+1), r2
-check_mem data 0xaabb0000
-
-test_name SB_3
-load r1 data
-load r2 0xf0f1f2cc
-sb (r1+-1), r2
-check_mem data0 0x000000cc
-
-end
-
-.data
- .align 4
-data0:
- .byte 0, 0, 0, 0
-data:
- .byte 0, 0, 0, 0
-data1:
- .byte 0, 0, 0, 0
diff --git a/tests/tcg/lm32/test_scall.S b/tests/tcg/lm32/test_scall.S
deleted file mode 100644
index 46032f841d..0000000000
--- a/tests/tcg/lm32/test_scall.S
+++ /dev/null
@@ -1,24 +0,0 @@
-.include "macros.inc"
-
-start
-
-test_name SCALL_1
-mvi r1, 1
-wcsr IE, r1
-# we are running in a semi hosted environment
-# therefore we have to set r8 to some unused system
-# call
-mvi r8, 0
-insn:
-scall
-check_excp 64
-
-test_name SCALL_2
-mv r3, ea
-check_r3 insn
-
-test_name SCALL_3
-rcsr r3, IE
-check_r3 2
-
-end
diff --git a/tests/tcg/lm32/test_sextb.S b/tests/tcg/lm32/test_sextb.S
deleted file mode 100644
index 58db8ee8b9..0000000000
--- a/tests/tcg/lm32/test_sextb.S
+++ /dev/null
@@ -1,20 +0,0 @@
-.include "macros.inc"
-
-start
-
-test_name SEXTB_1
-mvi r1, 0
-sextb r3, r1
-check_r3 0
-
-test_name SEXTB_2
-mvi r1, 0x7f
-sextb r3, r1
-check_r3 0x0000007f
-
-test_name SEXTB_3
-mvi r1, 0x80
-sextb r3, r1
-check_r3 0xffffff80
-
-end
diff --git a/tests/tcg/lm32/test_sexth.S b/tests/tcg/lm32/test_sexth.S
deleted file mode 100644
index a059ec3ee6..0000000000
--- a/tests/tcg/lm32/test_sexth.S
+++ /dev/null
@@ -1,20 +0,0 @@
-.include "macros.inc"
-
-start
-
-test_name SEXTH_1
-mvi r1, 0
-sexth r3, r1
-check_r3 0
-
-test_name SEXTH_2
-load r1 0x7fff
-sexth r3, r1
-check_r3 0x00007fff
-
-test_name SEXTH_3
-load r1 0x8000
-sexth r3, r1
-check_r3 0xffff8000
-
-end
diff --git a/tests/tcg/lm32/test_sh.S b/tests/tcg/lm32/test_sh.S
deleted file mode 100644
index bba10224f6..0000000000
--- a/tests/tcg/lm32/test_sh.S
+++ /dev/null
@@ -1,32 +0,0 @@
-.include "macros.inc"
-
-start
-
-test_name SH_1
-load r1 data
-load r2 0xf0f1aaaa
-sh (r1+0), r2
-check_mem data 0xaaaa0000
-
-test_name SH_2
-load r1 data
-load r2 0xf0f1bbbb
-sh (r1+2), r2
-check_mem data 0xaaaabbbb
-
-test_name SH_3
-load r1 data
-load r2 0xf0f1cccc
-sh (r1+-2), r2
-check_mem data0 0x0000cccc
-
-end
-
-.data
- .align 4
-data0:
- .byte 0, 0, 0, 0
-data:
- .byte 0, 0, 0, 0
-data1:
- .byte 0, 0, 0, 0
diff --git a/tests/tcg/lm32/test_sl.S b/tests/tcg/lm32/test_sl.S
deleted file mode 100644
index 0aee17fdb8..0000000000
--- a/tests/tcg/lm32/test_sl.S
+++ /dev/null
@@ -1,45 +0,0 @@
-.include "macros.inc"
-
-start
-
-test_name SL_1
-mvi r1, 1
-mvi r2, 0
-sl r3, r1, r2
-check_r3 1
-
-test_name SL_2
-mvi r1, 0
-mvi r2, 1
-sl r3, r1, r2
-check_r3 0
-
-test_name SL_3
-mvi r1, 1
-mvi r2, 31
-sl r3, r1, r2
-check_r3 0x80000000
-
-test_name SL_4
-mvi r1, 16
-mvi r2, 31
-sl r3, r1, r2
-check_r3 0
-
-test_name SL_5
-mvi r1, 1
-mvi r2, 34
-sl r3, r1, r2
-check_r3 4
-
-test_name SL_6
-mvi r1, 2
-sl r3, r1, r1
-check_r3 8
-
-test_name SL_7
-mvi r3, 2
-sl r3, r3, r3
-check_r3 8
-
-end
diff --git a/tests/tcg/lm32/test_sli.S b/tests/tcg/lm32/test_sli.S
deleted file mode 100644
index a421de9014..0000000000
--- a/tests/tcg/lm32/test_sli.S
+++ /dev/null
@@ -1,30 +0,0 @@
-.include "macros.inc"
-
-start
-
-test_name SLI_1
-mvi r1, 1
-sli r3, r1, 0
-check_r3 1
-
-test_name SLI_2
-mvi r1, 0
-sli r3, r1, 1
-check_r3 0
-
-test_name SLI_3
-mvi r1, 1
-sli r3, r1, 31
-check_r3 0x80000000
-
-test_name SLI_4
-mvi r1, 16
-sli r3, r1, 31
-check_r3 0
-
-test_name SLI_7
-mvi r3, 2
-sli r3, r3, 2
-check_r3 8
-
-end
diff --git a/tests/tcg/lm32/test_sr.S b/tests/tcg/lm32/test_sr.S
deleted file mode 100644
index 62431a9864..0000000000
--- a/tests/tcg/lm32/test_sr.S
+++ /dev/null
@@ -1,57 +0,0 @@
-.include "macros.inc"
-
-start
-
-test_name SR_1
-mvi r1, 1
-mvi r2, 0
-sr r3, r1, r2
-check_r3 1
-
-test_name SR_2
-mvi r1, 0
-mvi r2, 1
-sr r3, r1, r2
-check_r3 0
-
-test_name SR_3
-load r1 0x40000000
-mvi r2, 30
-sr r3, r1, r2
-check_r3 1
-
-test_name SR_4
-load r1 0x40000000
-mvi r2, 31
-sr r3, r1, r2
-check_r3 0
-
-test_name SR_5
-mvi r1, 16
-mvi r2, 34
-sr r3, r1, r2
-check_r3 4
-
-test_name SR_6
-mvi r1, 2
-sr r3, r1, r1
-check_r3 0
-
-test_name SR_7
-mvi r3, 2
-sr r3, r3, r3
-check_r3 0
-
-test_name SR_8
-mvi r1, 0xfffffff0
-mvi r2, 2
-sr r3, r1, r2
-check_r3 0xfffffffc
-
-test_name SR_9
-mvi r1, 0xfffffff0
-mvi r2, 4
-sr r3, r1, r2
-check_r3 0xffffffff
-
-end
diff --git a/tests/tcg/lm32/test_sri.S b/tests/tcg/lm32/test_sri.S
deleted file mode 100644
index c1be907b5b..0000000000
--- a/tests/tcg/lm32/test_sri.S
+++ /dev/null
@@ -1,40 +0,0 @@
-.include "macros.inc"
-
-start
-
-test_name SRI_1
-mvi r1, 1
-sri r3, r1, 0
-check_r3 1
-
-test_name SRI_2
-mvi r1, 0
-sri r3, r1, 1
-check_r3 0
-
-test_name SRI_3
-load r1 0x40000000
-sri r3, r1, 30
-check_r3 1
-
-test_name SRI_4
-load r1 0x40000000
-sri r3, r1, 31
-check_r3 0
-
-test_name SRI_5
-mvi r3, 2
-sri r3, r3, 2
-check_r3 0
-
-test_name SRI_6
-mvi r1, 0xfffffff0
-sri r3, r1, 2
-check_r3 0xfffffffc
-
-test_name SRI_7
-mvi r1, 0xfffffff0
-sri r3, r1, 4
-check_r3 0xffffffff
-
-end
diff --git a/tests/tcg/lm32/test_sru.S b/tests/tcg/lm32/test_sru.S
deleted file mode 100644
index 2ab0b54c77..0000000000
--- a/tests/tcg/lm32/test_sru.S
+++ /dev/null
@@ -1,57 +0,0 @@
-.include "macros.inc"
-
-start
-
-test_name SRU_1
-mvi r1, 1
-mvi r2, 0
-sru r3, r1, r2
-check_r3 1
-
-test_name SRU_2
-mvi r1, 0
-mvi r2, 1
-sru r3, r1, r2
-check_r3 0
-
-test_name SRU_3
-load r1 0x40000000
-mvi r2, 30
-sru r3, r1, r2
-check_r3 1
-
-test_name SRU_4
-load r1 0x40000000
-mvi r2, 31
-sru r3, r1, r2
-check_r3 0
-
-test_name SRU_5
-mvi r1, 16
-mvi r2, 34
-sru r3, r1, r2
-check_r3 4
-
-test_name SRU_6
-mvi r1, 2
-sru r3, r1, r1
-check_r3 0
-
-test_name SRU_7
-mvi r3, 2
-sru r3, r3, r3
-check_r3 0
-
-test_name SRU_8
-mvi r1, 0xfffffff0
-mvi r2, 2
-sru r3, r1, r2
-check_r3 0x3ffffffc
-
-test_name SRU_9
-mvi r1, 0xfffffff0
-mvi r2, 4
-sru r3, r1, r2
-check_r3 0x0fffffff
-
-end
diff --git a/tests/tcg/lm32/test_srui.S b/tests/tcg/lm32/test_srui.S
deleted file mode 100644
index 872c374121..0000000000
--- a/tests/tcg/lm32/test_srui.S
+++ /dev/null
@@ -1,40 +0,0 @@
-.include "macros.inc"
-
-start
-
-test_name SRUI_1
-mvi r1, 1
-srui r3, r1, 0
-check_r3 1
-
-test_name SRUI_2
-mvi r1, 0
-srui r3, r1, 1
-check_r3 0
-
-test_name SRUI_3
-load r1 0x40000000
-srui r3, r1, 30
-check_r3 1
-
-test_name SRUI_4
-load r1 0x40000000
-srui r3, r1, 31
-check_r3 0
-
-test_name SRUI_5
-mvi r3, 2
-srui r3, r3, 2
-check_r3 0
-
-test_name SRUI_6
-mvi r1, 0xfffffff0
-srui r3, r1, 2
-check_r3 0x3ffffffc
-
-test_name SRUI_7
-mvi r1, 0xfffffff0
-srui r3, r1, 4
-check_r3 0x0fffffff
-
-end
diff --git a/tests/tcg/lm32/test_sub.S b/tests/tcg/lm32/test_sub.S
deleted file mode 100644
index 44b74a9e10..0000000000
--- a/tests/tcg/lm32/test_sub.S
+++ /dev/null
@@ -1,75 +0,0 @@
-.include "macros.inc"
-
-start
-
-test_name SUB_1
-mvi r1, 0
-mvi r2, 0
-sub r3, r1, r2
-check_r3 0
-
-test_name SUB_2
-mvi r1, 0
-mvi r2, 1
-sub r3, r1, r2
-check_r3 -1
-
-test_name SUB_3
-mvi r1, 1
-mvi r2, 0
-sub r3, r1, r2
-check_r3 1
-
-test_name SUB_4
-mvi r1, 1
-mvi r2, -1
-sub r3, r1, r2
-check_r3 2
-
-test_name SUB_5
-mvi r1, -1
-mvi r2, 1
-sub r3, r1, r2
-check_r3 -2
-
-test_name SUB_6
-mvi r1, -1
-mvi r2, 0
-sub r3, r1, r2
-check_r3 -1
-
-test_name SUB_7
-mvi r1, 0
-mvi r2, -1
-sub r3, r1, r2
-check_r3 1
-
-test_name SUB_8
-mvi r3, 2
-sub r3, r3, r3
-check_r3 0
-
-test_name SUB_9
-mvi r1, 4
-mvi r3, 2
-sub r3, r1, r3
-check_r3 2
-
-test_name SUB_10
-mvi r1, 4
-mvi r3, 2
-sub r3, r3, r1
-check_r3 -2
-
-test_name SUB_11
-mvi r1, 4
-sub r3, r1, r1
-check_r3 0
-
-test_name SUB_12
-load r1 0x12345678
-load r2 0xabcdef97
-sub r3, r1, r2
-check_r3 0x666666e1
-
-end
diff --git a/tests/tcg/lm32/test_sw.S b/tests/tcg/lm32/test_sw.S
deleted file mode 100644
index 2b1c017e7b..0000000000
--- a/tests/tcg/lm32/test_sw.S
+++ /dev/null
@@ -1,38 +0,0 @@
-.include "macros.inc"
-
-start
-
-test_name SW_1
-load r1 data
-load r2 0xaabbccdd
-sw (r1+0), r2
-check_mem data 0xaabbccdd
-
-test_name SW_2
-load r1 data
-load r2 0x00112233
-sw (r1+4), r2
-check_mem data1 0x00112233
-
-test_name SW_3
-load r1 data
-load r2 0x44556677
-sw (r1+-4), r2
-check_mem data0 0x44556677
-
-test_name SW_4
-load r1 data
-sw (r1+0), r1
-lw r3, (r1+0)
-check_r3 data
-
-end
-
-.data
- .align 4
-data0:
- .byte 0, 0, 0, 0
-data:
- .byte 0, 0, 0, 0
-data1:
- .byte 0, 0, 0, 0
diff --git a/tests/tcg/lm32/test_xnor.S b/tests/tcg/lm32/test_xnor.S
deleted file mode 100644
index 14a62075f6..0000000000
--- a/tests/tcg/lm32/test_xnor.S
+++ /dev/null
@@ -1,51 +0,0 @@
-.include "macros.inc"
-
-start
-
-test_name XNOR_1
-mvi r1, 0
-mvi r2, 0
-xnor r3, r1, r2
-check_r3 0xffffffff
-
-test_name XNOR_2
-mvi r1, 0
-mvi r2, 1
-xnor r3, r1, r2
-check_r3 0xfffffffe
-
-test_name XNOR_3
-mvi r1, 1
-mvi r2, 1
-xnor r3, r1, r2
-check_r3 0xffffffff
-
-test_name XNOR_4
-mvi r1, 1
-mvi r2, 0
-xnor r3, r1, r2
-check_r3 0xfffffffe
-
-test_name XNOR_5
-load r1 0xaa55aa55
-load r2 0x55aa55aa
-xnor r3, r1, r2
-check_r3 0
-
-test_name XNOR_6
-load r1 0xaa550000
-load r2 0x0000aa55
-xnor r3, r1, r2
-check_r3 0x55aa55aa
-
-test_name XNOR_7
-load r1 0xaa55aa55
-xnor r3, r1, r1
-check_r3 0xffffffff
-
-test_name XNOR_8
-load r3 0xaa55aa55
-xnor r3, r3, r3
-check_r3 0xffffffff
-
-end
diff --git a/tests/tcg/lm32/test_xnori.S b/tests/tcg/lm32/test_xnori.S
deleted file mode 100644
index 9d9c3c6780..0000000000
--- a/tests/tcg/lm32/test_xnori.S
+++ /dev/null
@@ -1,35 +0,0 @@
-.include "macros.inc"
-
-start
-
-test_name XNORI_1
-mvi r1, 0
-xnori r3, r1, 0
-check_r3 0xffffffff
-
-test_name XNORI_2
-mvi r1, 0
-xnori r3, r1, 1
-check_r3 0xfffffffe
-
-test_name XNORI_3
-mvi r1, 1
-xnori r3, r1, 1
-check_r3 0xffffffff
-
-test_name XNORI_4
-mvi r1, 1
-xnori r3, r1, 0
-check_r3 0xfffffffe
-
-test_name XNORI_5
-load r1 0xaa55aa55
-xnori r3, r1, 0x5555
-check_r3 0x55aa00ff
-
-test_name XNORI_6
-load r3 0xaa55aa55
-xnori r3, r3, 0x5555
-check_r3 0x55aa00ff
-
-end
diff --git a/tests/tcg/lm32/test_xor.S b/tests/tcg/lm32/test_xor.S
deleted file mode 100644
index 6c6e712bae..0000000000
--- a/tests/tcg/lm32/test_xor.S
+++ /dev/null
@@ -1,51 +0,0 @@
-.include "macros.inc"
-
-start
-
-test_name XOR_1
-mvi r1, 0
-mvi r2, 0
-xor r3, r1, r2
-check_r3 0
-
-test_name XOR_2
-mvi r1, 0
-mvi r2, 1
-xor r3, r1, r2
-check_r3 1
-
-test_name XOR_3
-mvi r1, 1
-mvi r2, 1
-xor r3, r1, r2
-check_r3 0
-
-test_name XOR_4
-mvi r1, 1
-mvi r2, 0
-xor r3, r1, r2
-check_r3 1
-
-test_name XOR_5
-load r1 0xaa55aa55
-load r2 0x55aa55aa
-xor r3, r1, r2
-check_r3 0xffffffff
-
-test_name XOR_6
-load r1 0xaa550000
-load r2 0x0000aa55
-xor r3, r1, r2
-check_r3 0xaa55aa55
-
-test_name XOR_7
-load r1 0xaa55aa55
-xor r3, r1, r1
-check_r3 0
-
-test_name XOR_8
-load r3 0xaa55aa55
-xor r3, r3, r3
-check_r3 0
-
-end
diff --git a/tests/tcg/lm32/test_xori.S b/tests/tcg/lm32/test_xori.S
deleted file mode 100644
index 2051699f12..0000000000
--- a/tests/tcg/lm32/test_xori.S
+++ /dev/null
@@ -1,35 +0,0 @@
-.include "macros.inc"
-
-start
-
-test_name XORI_1
-mvi r1, 0
-xori r3, r1, 0
-check_r3 0
-
-test_name XORI_2
-mvi r1, 0
-xori r3, r1, 1
-check_r3 1
-
-test_name XORI_3
-mvi r1, 1
-xori r3, r1, 1
-check_r3 0
-
-test_name XORI_4
-mvi r1, 1
-xori r3, r1, 0
-check_r3 1
-
-test_name XORI_5
-load r1 0xaa55aa55
-xori r3, r1, 0x5555
-check_r3 0xaa55ff00
-
-test_name XORI_6
-load r3 0xaa55aa55
-xori r3, r3, 0x5555
-check_r3 0xaa55ff00
-
-end
diff --git a/tests/unit/test-write-threshold.c b/tests/unit/test-write-threshold.c
index fc1c45a2eb..0158e4637a 100644
--- a/tests/unit/test-write-threshold.c
+++ b/tests/unit/test-write-threshold.c
@@ -7,117 +7,41 @@
*/
#include "qemu/osdep.h"
-#include "qapi/error.h"
#include "block/block_int.h"
#include "block/write-threshold.h"
-static void test_threshold_not_set_on_init(void)
-{
- uint64_t res;
- BlockDriverState bs;
- memset(&bs, 0, sizeof(bs));
-
- g_assert(!bdrv_write_threshold_is_set(&bs));
-
- res = bdrv_write_threshold_get(&bs);
- g_assert_cmpint(res, ==, 0);
-}
-
-static void test_threshold_set_get(void)
-{
- uint64_t threshold = 4 * 1024 * 1024;
- uint64_t res;
- BlockDriverState bs;
- memset(&bs, 0, sizeof(bs));
-
- bdrv_write_threshold_set(&bs, threshold);
-
- g_assert(bdrv_write_threshold_is_set(&bs));
-
- res = bdrv_write_threshold_get(&bs);
- g_assert_cmpint(res, ==, threshold);
-}
-
-static void test_threshold_multi_set_get(void)
-{
- uint64_t threshold1 = 4 * 1024 * 1024;
- uint64_t threshold2 = 15 * 1024 * 1024;
- uint64_t res;
- BlockDriverState bs;
- memset(&bs, 0, sizeof(bs));
-
- bdrv_write_threshold_set(&bs, threshold1);
- bdrv_write_threshold_set(&bs, threshold2);
- res = bdrv_write_threshold_get(&bs);
- g_assert_cmpint(res, ==, threshold2);
-}
-
static void test_threshold_not_trigger(void)
{
- uint64_t amount = 0;
uint64_t threshold = 4 * 1024 * 1024;
BlockDriverState bs;
- BdrvTrackedRequest req;
memset(&bs, 0, sizeof(bs));
- memset(&req, 0, sizeof(req));
- req.offset = 1024;
- req.bytes = 1024;
-
- bdrv_check_request(req.offset, req.bytes, &error_abort);
bdrv_write_threshold_set(&bs, threshold);
- amount = bdrv_write_threshold_exceeded(&bs, &req);
- g_assert_cmpuint(amount, ==, 0);
+ bdrv_write_threshold_check_write(&bs, 1024, 1024);
+ g_assert_cmpuint(bdrv_write_threshold_get(&bs), ==, threshold);
}
static void test_threshold_trigger(void)
{
- uint64_t amount = 0;
uint64_t threshold = 4 * 1024 * 1024;
BlockDriverState bs;
- BdrvTrackedRequest req;
memset(&bs, 0, sizeof(bs));
- memset(&req, 0, sizeof(req));
- req.offset = (4 * 1024 * 1024) - 1024;
- req.bytes = 2 * 1024;
-
- bdrv_check_request(req.offset, req.bytes, &error_abort);
bdrv_write_threshold_set(&bs, threshold);
- amount = bdrv_write_threshold_exceeded(&bs, &req);
- g_assert_cmpuint(amount, >=, 1024);
+ bdrv_write_threshold_check_write(&bs, threshold - 1024, 2 * 1024);
+ g_assert_cmpuint(bdrv_write_threshold_get(&bs), ==, 0);
}
-typedef struct TestStruct {
- const char *name;
- void (*func)(void);
-} TestStruct;
-
int main(int argc, char **argv)
{
- size_t i;
- TestStruct tests[] = {
- { "/write-threshold/not-set-on-init",
- test_threshold_not_set_on_init },
- { "/write-threshold/set-get",
- test_threshold_set_get },
- { "/write-threshold/multi-set-get",
- test_threshold_multi_set_get },
- { "/write-threshold/not-trigger",
- test_threshold_not_trigger },
- { "/write-threshold/trigger",
- test_threshold_trigger },
- { NULL, NULL }
- };
-
g_test_init(&argc, &argv, NULL);
- for (i = 0; tests[i].name != NULL; i++) {
- g_test_add_func(tests[i].name, tests[i].func);
- }
+ g_test_add_func("/write-threshold/not-trigger", test_threshold_not_trigger);
+ g_test_add_func("/write-threshold/trigger", test_threshold_trigger);
+
return g_test_run();
}
diff --git a/util/compatfd.c b/util/compatfd.c
index 174f394533..a8ec525c6c 100644
--- a/util/compatfd.c
+++ b/util/compatfd.c
@@ -72,14 +72,10 @@ static int qemu_signalfd_compat(const sigset_t *mask)
QemuThread thread;
int fds[2];
- info = malloc(sizeof(*info));
- if (info == NULL) {
- errno = ENOMEM;
- return -1;
- }
+ info = g_malloc(sizeof(*info));
if (pipe(fds) == -1) {
- free(info);
+ g_free(info);
return -1;
}
diff --git a/util/vfio-helpers.c b/util/vfio-helpers.c
index 97dfa3fd57..911115b86e 100644
--- a/util/vfio-helpers.c
+++ b/util/vfio-helpers.c
@@ -459,51 +459,38 @@ fail_container:
return ret;
}
-static void qemu_vfio_ram_block_added(RAMBlockNotifier *n,
- void *host, size_t size)
+static void qemu_vfio_ram_block_added(RAMBlockNotifier *n, void *host,
+ size_t size, size_t max_size)
{
QEMUVFIOState *s = container_of(n, QEMUVFIOState, ram_notifier);
- trace_qemu_vfio_ram_block_added(s, host, size);
- qemu_vfio_dma_map(s, host, size, false, NULL);
+ int ret;
+
+ trace_qemu_vfio_ram_block_added(s, host, max_size);
+ ret = qemu_vfio_dma_map(s, host, max_size, false, NULL);
+ if (ret) {
+ error_report("qemu_vfio_dma_map(%p, %zu) failed: %s", host, max_size,
+ strerror(-ret));
+ }
}
-static void qemu_vfio_ram_block_removed(RAMBlockNotifier *n,
- void *host, size_t size)
+static void qemu_vfio_ram_block_removed(RAMBlockNotifier *n, void *host,
+ size_t size, size_t max_size)
{
QEMUVFIOState *s = container_of(n, QEMUVFIOState, ram_notifier);
if (host) {
- trace_qemu_vfio_ram_block_removed(s, host, size);
+ trace_qemu_vfio_ram_block_removed(s, host, max_size);
qemu_vfio_dma_unmap(s, host);
}
}
-static int qemu_vfio_init_ramblock(RAMBlock *rb, void *opaque)
-{
- void *host_addr = qemu_ram_get_host_addr(rb);
- ram_addr_t length = qemu_ram_get_used_length(rb);
- int ret;
- QEMUVFIOState *s = opaque;
-
- if (!host_addr) {
- return 0;
- }
- ret = qemu_vfio_dma_map(s, host_addr, length, false, NULL);
- if (ret) {
- fprintf(stderr, "qemu_vfio_init_ramblock: failed %p %" PRId64 "\n",
- host_addr, (uint64_t)length);
- }
- return 0;
-}
-
static void qemu_vfio_open_common(QEMUVFIOState *s)
{
qemu_mutex_init(&s->lock);
s->ram_notifier.ram_block_added = qemu_vfio_ram_block_added;
s->ram_notifier.ram_block_removed = qemu_vfio_ram_block_removed;
- ram_block_notifier_add(&s->ram_notifier);
s->low_water_mark = QEMU_VFIO_IOVA_MIN;
s->high_water_mark = QEMU_VFIO_IOVA_MAX;
- qemu_ram_foreach_block(qemu_vfio_init_ramblock, s);
+ ram_block_notifier_add(&s->ram_notifier);
}
/**