Merge tag 'for-upstream' of https://repo.or.cz/qemu/kevin into staging Block layer patches - qcow2: Fix data loss on zero write with detect-zeroes=unmap - qemu-img bitmap: add sub-command --remove-all - export/fuse: set FUSE_DIRECT_IO_ALLOW_MMAP flag to fix regression - virtio-blk: add missing VIRTIO_BLK_T_SCSI_CMD size check (CVE-2026-48914) - qed: Don't try to flush during incoming migration - iotests/136: Test stats-intervals with -blockdev/-device # -----BEGIN PGP SIGNATURE----- # # iQJFBAABCgAvFiEE3D3rFZqa+V09dFb+fwmycsiPL9YFAmopOKwRHGt3b2xmQHJl # ZGhhdC5jb20ACgkQfwmycsiPL9Z7ERAAlB6SSRMCjRkYq6z61yQLskLzPXjP5SQW # kC0s67zJO5cGCTolSMYCF8NMCFA/K7z2ZTZqfv59ERJJnQ2I90cJ3PK1cPkIBOPD # hP1w4/OMVKDrzkCyWmBEief4HD265itjr7h6Q4J0NGFBoiHo+R/J6jIDYebFJkyE # 6Fqj6YKMFm/7dlyULGFG9hg5BnCiAWcCw11rH07GDLRGPYBSZeMU/DNUZG6Bzebr # 3VCUKGAB0IfN8I0rUHnBTadtwf9Nj8PYf+UCQph4n4CHkbpgbgnfZbmsPCHYL738 # B4U34gLfAWaD+D2wF9jU6769HBvoqsm5SMdURHrzPbOA/JSKKBsOoG7Q7s6kGkMI # vrtrHJvtXL5kI3aCSXZ9N1MFxDnTIp1ubB6CfVrId+q7ntMnLf4vsT5EqikUGc6o # OLvmPsYD7cX9oz6pDhKgrhq14pdPlEaBFeNl8is963k82C2aM5s0G72gRJ1fpQwP # rbI+z/sGYJHsanzlkmesrOdZ682beCLb6Fzgo6Mi+djrZWfYmI9A1m1s4rCQuFQi # nrzNHE0mBDaL4Nx49qMnLFKBstKoTJa3FAiPuLael5krfZ4C/ALs8xJGXVs4GdcE # Df/fpyVlx06FJDHP6O+/GuR7jaj/fieCaZpFvzQ6HNLdpk2XTJwbVxa2k48x2foR # mviRxIlT198= # =FwVi # -----END PGP SIGNATURE----- # gpg: Signature made Wed 10 Jun 2026 06:13:00 EDT # gpg: using RSA key DC3DEB159A9AF95D3D7456FE7F09B272C88F2FD6 # gpg: issuer "kwolf@redhat.com" # gpg: Good signature from "Kevin Wolf <kwolf@redhat.com>" [full] # Primary key fingerprint: DC3D EB15 9A9A F95D 3D74 56FE 7F09 B272 C88F 2FD6 * tag 'for-upstream' of https://repo.or.cz/qemu/kevin: qed: Don't try to flush during incoming migration iotests: test shared mmap for fuse export block/export/fuse: set FUSE_DIRECT_IO_ALLOW_MMAP flag to fix regression block/export/fuse: use struct fuse_init_in qcow2: Fix data loss on zero write with detect-zeroes=unmap iotests/136: Test stats-intervals with -blockdev/-device qemu-img: add sub-command --remove-all to 'qemu-img bitmap' virtio-blk: add missing VIRTIO_BLK_T_SCSI_CMD size check (CVE-2026-48914) Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
diff --git a/MAINTAINERS b/MAINTAINERS index 748ec77..2b5b581 100644 --- a/MAINTAINERS +++ b/MAINTAINERS
@@ -175,7 +175,6 @@ F: page-vary-common.c F: accel/tcg/ F: accel/stubs/tcg-stub.c -F: util/cacheinfo.c F: util/cacheflush.c F: scripts/decodetree.py F: docs/devel/decodetree.rst @@ -256,7 +255,7 @@ F: linux-user/hexagon/ F: tests/tcg/hexagon/ F: disas/hexagon.c -F: configs/targets/hexagon-linux-user/default.mak +F: configs/targets/hexagon-linux-user.mak F: tests/docker/dockerfiles/debian-hexagon-cross.docker F: gdbstub/gdb-xml/hexagon*.xml T: git https://github.com/qualcomm/qemu.git hex-next @@ -362,8 +361,6 @@ F: hw/intc/riscv* F: include/hw/char/riscv_htif.h F: include/hw/riscv/ -F: linux-user/host/riscv32/ -F: linux-user/host/riscv64/ F: common-user/host/riscv* F: tests/functional/riscv32 F: tests/functional/riscv64 @@ -426,7 +423,6 @@ F: include/hw/sparc/sparc64.h F: disas/sparc.c F: tests/functional/sparc*/meson.build -F: tests/tcg/sparc64/ X86 TCG CPUs M: Paolo Bonzini <pbonzini@redhat.com> @@ -475,7 +471,6 @@ F: */*/kvm* F: accel/kvm/ F: accel/stubs/kvm-stub.c -F: include/hw/kvm/ F: include/system/kvm*.h F: scripts/kvm/kvm_flightrecorder @@ -533,7 +528,7 @@ Guest CPU Cores (other accelerators) ------------------------------------ -Overall +Overall CPUs other accelerators M: Richard Henderson <richard.henderson@linaro.org> R: Paolo Bonzini <pbonzini@redhat.com> R: Philippe Mathieu-Daudé <philmd@mailo.com> @@ -546,8 +541,8 @@ F: include/accel/accel-*.h F: accel/accel-*.? F: accel/dummy-cpus.? -F: accel/Makefile.objs -F: accel/stubs/Makefile.objs +F: accel/meson.build +F: accel/stubs/meson.build F: cpu-common.c F: cpu-target.c F: qapi/accelerator.json @@ -557,7 +552,6 @@ M: Alexander Graf <agraf@csgraf.de> S: Maintained F: target/arm/hvf/ -F: target/arm/hvf-stub.c X86 HVF CPUs M: Roman Bolshakov <rbolshakov@ddn.com> @@ -642,7 +636,6 @@ F: hw/xenpv/ F: hw/i386/xen/ F: hw/pci-host/xen_igd_pt.c -F: include/hw/block/dataplane/xen* F: include/hw/xen/ F: include/system/xen.h F: include/system/xen-mapcache.h @@ -701,7 +694,7 @@ Darwin (macOS, iOS) M: Philippe Mathieu-Daudé <philmd@mailo.com> S: Odd Fixes -F: .gitlab-ci.d/cirrus/macos-* +F: .gitlab-ci.d/macos* F: */*.m F: scripts/entitlement.sh @@ -712,7 +705,7 @@ F: os-wasm.c F: util/coroutine-wasm.c F: configs/meson/emscripten.txt -F: tests/docker/dockerfiles/emsdk-wasm-cross.docker +F: tests/docker/dockerfiles/emsdk-wasm64-cross.docker Alpha Machines -------------- @@ -736,7 +729,7 @@ F: include/hw/*/allwinner* F: hw/arm/cubieboard.c F: docs/system/arm/cubieboard.rst -F: hw/misc/axp209.c +F: hw/misc/axp2xx.c F: tests/functional/arm/test_cubieboard.py Allwinner-h3 @@ -1018,8 +1011,7 @@ R: Philippe Mathieu-Daudé <philmd@mailo.com> L: qemu-arm@nongnu.org S: Odd Fixes -F: hw/arm/raspi.c -F: hw/arm/raspi_platform.h +F: hw/arm/raspi*.c F: hw/*/bcm283* F: include/hw/arm/rasp* F: include/hw/*/bcm283* @@ -1151,7 +1143,6 @@ F: hw/misc/zynq_slcr.c F: hw/adc/zynq-xadc.c F: include/hw/misc/xlnx-zynq-ddrc.h -F: include/hw/misc/zynq_slcr.h F: include/hw/adc/zynq-xadc.h X: hw/ssi/xilinx_* F: docs/system/arm/xlnx-zynq.rst @@ -1575,7 +1566,6 @@ F: docs/system/ppc/powermac.rst F: hw/ppc/mac_newworld.c F: hw/pci-host/uninorth.c -F: hw/pci-bridge/dec.[hc] F: hw/misc/macio/ F: hw/misc/mos6522*.c F: hw/nvram/mac_nvram.c @@ -1642,7 +1632,6 @@ F: include/hw/*/xics* F: include/hw/ppc/fdt.h F: hw/ppc/fdt.c -F: include/hw/ppc/pef.h F: hw/ppc/pef.c F: pc-bios/slof.bin F: docs/system/ppc/pseries.rst @@ -1702,7 +1691,7 @@ F: hw/ide/sii3112.c F: hw/rtc/m41t80.c F: pc-bios/dtb/canyonlands.dt[sb] -F: pc-bios/u-boot-sam460ex.bin +F: pc-bios/u-boot-sam460.bin F: roms/u-boot-sam460ex F: docs/system/ppc/amigang.rst F: tests/functional/ppc/test_sam460ex.py @@ -1782,7 +1771,7 @@ F: docs/system/riscv/sifive_u.rst F: hw/*/*sifive*.c F: include/hw/*/*sifive*.h -F: tests/functional/test_riscv64_sifive_u.py +F: tests/functional/riscv64/test_sifive_u.py AMD Microblaze-V Generic Board M: Sai Pavan Boddu <sai.pavan.boddu@amd.com> @@ -2246,7 +2235,7 @@ M: Mauro Carvalho Chehab <mchehab+huawei@kernel.org> L: linux-edac@vger.kernel.org S: Maintained -F: hw/arm/ghes_cper.c +F: hw/acpi/ghes_cper.c F: hw/acpi/ghes_cper_stub.c F: qapi/acpi-hest.json F: scripts/ghes_inject.py @@ -2308,7 +2297,7 @@ F: hw/block/m25p80* F: include/hw/ssi/ssi.h X: hw/ssi/xilinx_* -F: tests/qtest/m25p80-test.c +F: tests/qtest/aspeed_smc-test.c Xilinx SPI M: Alistair Francis <alistair@alistair23.me> @@ -2410,7 +2399,7 @@ S: Supported F: hw/*/*vhost* F: docs/interop/vhost-user* -F: docs/system/devices/vhost-user* +F: docs/system/devices/virtio/vhost-user* F: contrib/vhost-user-*/ F: backends/*vhost* F: include/system/vhost-user-backend.h @@ -2430,7 +2419,6 @@ M: Michael S. Tsirkin <mst@redhat.com> S: Supported F: hw/*/virtio* -F: hw/virtio/Makefile.objs F: hw/virtio/trace-events F: qapi/virtio.json F: net/vhost-user.c @@ -2501,7 +2489,7 @@ virtio-input M: Gerd Hoffmann <kraxel@redhat.com> S: Odd Fixes -F: docs/system/devices/vhost-user-input.rst +F: docs/system/devices/virtio/vhost-user-contrib.rst F: hw/input/virtio-input*.c F: hw/virtio/vhost-user-input.c F: include/hw/virtio/virtio-input.h @@ -2546,16 +2534,14 @@ M: Alex Bennée <alex.bennee@linaro.org> S: Maintained F: hw/virtio/vhost-user-base.c -F: hw/virtio/vhost-user-device* +F: hw/virtio/vhost-user-test-device* vhost-user-rng M: Mathieu Poirier <mathieu.poirier@linaro.org> S: Supported -F: docs/system/devices/vhost-user-rng.rst F: hw/virtio/vhost-user-rng.c F: hw/virtio/vhost-user-rng-pci.c F: include/hw/virtio/vhost-user-rng.h -F: tools/vhost-user-rng/* vhost-user-gpio M: Alex Bennée <alex.bennee@linaro.org> @@ -2625,7 +2611,7 @@ F: hw/audio/virtio-snd.c F: hw/audio/virtio-snd-pci.c F: include/hw/audio/virtio-snd.h -F: docs/system/devices/virtio-snd.rst +F: docs/system/devices/virtio/virtio-snd.rst nvme M: Keith Busch <kbusch@kernel.org> @@ -2729,7 +2715,7 @@ pcf8574 S: Orphan F: hw/gpio/pcf8574.c -F: include/gpio/pcf8574.h +F: include/hw/gpio/pcf8574.h Generic Loader M: Alistair Francis <alistair@alistair23.me> @@ -2814,7 +2800,7 @@ F: hw/display/virtio-gpu* F: hw/display/virtio-vga.* F: include/hw/virtio/virtio-gpu.h -F: docs/system/devices/virtio-gpu.rst +F: docs/system/devices/virtio/virtio-gpu.rst F: tests/functional/aarch64/test_virt_gpu.py F: tests/functional/x86_64/test_virtio_gpu.py @@ -2839,7 +2825,7 @@ F: contrib/vhost-user-gpu F: hw/display/vhost-user-* -qemu-vnc: +qemu-vnc M: Marc-André Lureau <marcandre.lureau@redhat.com> S: Maintained F: tools/qemu-vnc @@ -3152,7 +3138,6 @@ F: include/qemu/aio-wait.h F: include/qemu/defer-call.h F: scripts/qemugdb/aio.py -F: tests/unit/test-fdmon-epoll.c T: git https://github.com/stefanha/qemu.git block Block SCSI subsystem @@ -3259,7 +3244,7 @@ Coverity model M: Markus Armbruster <armbru@redhat.com> S: Supported -F: scripts/coverity-model.c +F: scripts/coverity-scan/model.c Coverity Scan integration M: Peter Maydell <peter.maydell@linaro.org> @@ -3280,7 +3265,7 @@ F: dump/ F: hw/misc/vmcoreinfo.c F: include/hw/misc/vmcoreinfo.h -F: include/qemu/win_dump_defs +F: include/qemu/win_dump_defs.h F: include/system/dump-arch.h F: include/system/dump.h F: qapi/dump.json @@ -3431,7 +3416,6 @@ F: monitor/monitor-internal.h F: monitor/monitor.c F: monitor/hmp* -F: hmp.h F: hmp-commands*.hx F: include/monitor/hmp.h F: include/monitor/hmp-completion.h @@ -3589,7 +3573,7 @@ F: hw/core/qdev* F: hw/core/bus.c F: hw/core/sysbus.c -F: include/hw/qdev* +F: include/hw/core/qdev* F: include/monitor/qdev.h F: qapi/qdev.json F: system/qdev-monitor.c @@ -3605,12 +3589,11 @@ S: Supported F: monitor/monitor-internal.h F: monitor/qmp* -F: monitor/misc.c F: monitor/monitor.c F: qapi/control.json F: qapi/error.json F: qapi/introspect.json -F: docs/devel/*qmp-* +F: docs/devel/writing-monitor-commands.rst F: docs/interop/*qmp-* F: scripts/qmp/ F: tests/qtest/qmp-test.c @@ -3980,7 +3963,7 @@ R: Nabih Estefan <nabihestefan@google.com> S: Maintained F: hw/i3c/*.c -F: hw/i3c/.h +F: hw/i3c/*.h F: hw/i3c/Kconfig F: hw/i3c/meson.build F: hw/i3c/trace-events @@ -4020,7 +4003,6 @@ F: hw/i386/*ovmf* F: pc-bios/descriptors/??-edk2-*.json F: pc-bios/edk2-* -F: roms/Makefile.edk2 F: roms/edk2 F: roms/edk2-* F: tests/data/uefi-boot-images/ @@ -4184,7 +4166,6 @@ S: Maintained F: tcg/tci/ F: tcg/tci.c -F: disas/tci.c Block drivers ------------- @@ -4351,7 +4332,6 @@ L: qemu-block@nongnu.org S: Maintained F: block/io_uring.c -F: stubs/io_uring.c qcow2 M: Kevin Wolf <kwolf@redhat.com> @@ -4463,7 +4443,7 @@ F: tests/functional/multiprocess.py F: tests/functional/*/*multiprocess.py -VFIO-USER: +VFIO-USER M: John Levon <john.levon@nutanix.com> M: Thanos Makatos <thanos.makatos@nutanix.com> M: Cédric Le Goater <clg@redhat.com> @@ -4471,14 +4451,12 @@ F: docs/interop/vfio-user.rst F: docs/system/devices/vfio-user.rst F: hw/vfio-user/* -F: include/hw/vfio-user/* -F: subprojects/libvfio-user +F: subprojects/libvfio-user.wrap F: tests/functional/x86_64/test_vfio_user_client.py -EBPF: +EBPF M: Jason Wang <jasowang@redhat.com> -R: Andrew Melnychenko <andrew@daynix.com> -R: Yuri Benditovich <yuri.benditovich@daynix.com> +R: Yuri Benditovich <ybendito@redhat.com> S: Maintained F: docs/devel/ebpf_rss.rst F: ebpf/* @@ -4495,7 +4473,7 @@ F: .gitlab-ci.yml F: .gitlab-ci.d/ F: .travis.yml -F: docs/devel/ci* +F: docs/devel/testing/ci* F: scripts/ci/ F: tests/docker/ F: tests/vm/ @@ -4616,13 +4594,11 @@ M: Mauro Carvalho Chehab <mchehab+huawei@kernel.org> S: Maintained F: docs/conf.py -F: docs/*/conf.py F: docs/requirements.txt F: docs/sphinx/ F: docs/_templates/ F: docs/devel/docs.rst F: docs/devel/qapi-domain.rst -F: scripts/kernel-doc F: scripts/lib/kdoc/ Rust build system integration @@ -4633,7 +4609,7 @@ F: rust/.gitignore F: rust/Kconfig F: rust/meson.build -F: rust/wrapper.h +F: rust/bindings/*/wrapper.h Miscellaneous -------------
diff --git a/hw/intc/loongarch_dintc.c b/hw/intc/loongarch_dintc.c index c42a919..c877a80 100644 --- a/hw/intc/loongarch_dintc.c +++ b/hw/intc/loongarch_dintc.c
@@ -35,10 +35,12 @@ { int irq = data.host_int; CPULoongArchState *env; + CPUSysState *sys; env = &LOONGARCH_CPU(cs)->env; + sys = env_sys(env); cpu_synchronize_state(cs); - set_bit(irq, (unsigned long *)&env->CSR_MSGIS); + set_bit(irq, (unsigned long *)&sys->CSR_MSGIS); } static void loongarch_dintc_mem_write(void *opaque, hwaddr addr,
diff --git a/linux-user/loongarch64/cpu_loop.c b/linux-user/loongarch64/cpu_loop.c index 603fcc3..27d6eef 100644 --- a/linux-user/loongarch64/cpu_loop.c +++ b/linux-user/loongarch64/cpu_loop.c
@@ -19,6 +19,7 @@ void cpu_loop(CPULoongArchState *env) { + CPUSysState *sys = env_sys(env); CPUState *cs = env_cpu(env); int trapnr, si_code; abi_long ret; @@ -103,10 +104,10 @@ * choose the layout of any signal frame. */ case EXCCODE_SXD: - env->CSR_EUEN |= R_CSR_EUEN_SXE_MASK; + sys->CSR_EUEN |= R_CSR_EUEN_SXE_MASK; break; case EXCCODE_ASXD: - env->CSR_EUEN |= R_CSR_EUEN_ASXE_MASK; + sys->CSR_EUEN |= R_CSR_EUEN_ASXE_MASK; break; case EXCP_ATOMIC:
diff --git a/linux-user/loongarch64/elfload.c b/linux-user/loongarch64/elfload.c index ce3bd0c..e53957e 100644 --- a/linux-user/loongarch64/elfload.c +++ b/linux-user/loongarch64/elfload.c
@@ -67,6 +67,8 @@ void elf_core_copy_regs(target_elf_gregset_t *r, const CPULoongArchState *env) { + CPUSysState *sys = env_sys((CPULoongArchState *)env); + r->pt.regs[0] = 0; for (int i = 1; i < ARRAY_SIZE(env->gpr); i++) { @@ -74,5 +76,5 @@ } r->pt.csr_era = tswapreg(env->pc); - r->pt.csr_badv = tswapreg(env->CSR_BADV); + r->pt.csr_badv = tswapreg(sys->CSR_BADV); }
diff --git a/linux-user/loongarch64/signal.c b/linux-user/loongarch64/signal.c index 1a322f9..eff75bc 100644 --- a/linux-user/loongarch64/signal.c +++ b/linux-user/loongarch64/signal.c
@@ -126,6 +126,8 @@ static abi_ptr setup_extcontext(CPULoongArchState *env, struct extctx_layout *extctx, abi_ptr sp) { + CPUSysState *sys = env_sys(env); + memset(extctx, 0, sizeof(struct extctx_layout)); /* Grow down, alloc "end" context info first. */ @@ -134,10 +136,10 @@ /* For qemu, there is no lazy fp context switch, so fp always present. */ extctx->flags = SC_USED_FP; - if (FIELD_EX64(env->CSR_EUEN, CSR_EUEN, ASXE)) { + if (FIELD_EX64(sys->CSR_EUEN, CSR_EUEN, ASXE)) { sp = extframe_alloc(extctx, &extctx->lasx, sizeof(struct target_lasx_context), LASX_CTX_ALIGN, sp); - } else if (FIELD_EX64(env->CSR_EUEN, CSR_EUEN, SXE)) { + } else if (FIELD_EX64(sys->CSR_EUEN, CSR_EUEN, SXE)) { sp = extframe_alloc(extctx, &extctx->lsx, sizeof(struct target_lsx_context), LSX_CTX_ALIGN, sp); } else { @@ -152,6 +154,7 @@ struct target_sigcontext *sc, struct extctx_layout *extctx) { + CPUSysState *sys = env_sys(env); struct target_sctx_info *info; int i; @@ -166,7 +169,7 @@ * Set extension context */ - if (FIELD_EX64(env->CSR_EUEN, CSR_EUEN, ASXE)) { + if (FIELD_EX64(sys->CSR_EUEN, CSR_EUEN, ASXE)) { struct target_lasx_context *lasx_ctx; info = extctx->lasx.haddr; @@ -183,7 +186,7 @@ } __put_user(read_fcc(env), &lasx_ctx->fcc); __put_user(env->fcsr0, &lasx_ctx->fcsr); - } else if (FIELD_EX64(env->CSR_EUEN, CSR_EUEN, SXE)) { + } else if (FIELD_EX64(sys->CSR_EUEN, CSR_EUEN, SXE)) { struct target_lsx_context *lsx_ctx; info = extctx->lsx.haddr; @@ -350,6 +353,7 @@ target_siginfo_t *info, target_sigset_t *set, CPULoongArchState *env) { + CPUSysState *sys = env_sys(env); struct target_rt_sigframe *frame; struct extctx_layout extctx; abi_ptr frame_addr; @@ -365,10 +369,10 @@ return; } - if (FIELD_EX64(env->CSR_EUEN, CSR_EUEN, ASXE)) { + if (FIELD_EX64(sys->CSR_EUEN, CSR_EUEN, ASXE)) { extctx.lasx.haddr = (void *)frame + (extctx.lasx.gaddr - frame_addr); extctx.end.haddr = (void *)frame + (extctx.end.gaddr - frame_addr); - } else if (FIELD_EX64(env->CSR_EUEN, CSR_EUEN, SXE)) { + } else if (FIELD_EX64(sys->CSR_EUEN, CSR_EUEN, SXE)) { extctx.lsx.haddr = (void *)frame + (extctx.lsx.gaddr - frame_addr); extctx.end.haddr = (void *)frame + (extctx.end.gaddr - frame_addr); } else {
diff --git a/target/loongarch/arch_dump.c b/target/loongarch/arch_dump.c index 2b0955a..9d84fae 100644 --- a/target/loongarch/arch_dump.c +++ b/target/loongarch/arch_dump.c
@@ -116,6 +116,7 @@ { struct loongarch_note note; CPULoongArchState *env = &LOONGARCH_CPU(cs)->env; + CPUSysState *sys = env_sys(env); int ret, i; loongarch_note_init(¬e, s, "CORE", 5, NT_PRSTATUS, @@ -126,8 +127,8 @@ for (i = 0; i < 32; ++i) { note.prstatus.pr_reg.gpr[i] = cpu_to_dump64(s, env->gpr[i]); } - note.prstatus.pr_reg.csr_era = cpu_to_dump64(s, env->CSR_ERA); - note.prstatus.pr_reg.csr_badv = cpu_to_dump64(s, env->CSR_BADV); + note.prstatus.pr_reg.csr_era = cpu_to_dump64(s, sys->CSR_ERA); + note.prstatus.pr_reg.csr_badv = cpu_to_dump64(s, sys->CSR_BADV); ret = f(¬e, LOONGARCH_PRSTATUS_NOTE_SIZE, s); if (ret < 0) { return -1;
diff --git a/target/loongarch/cpu-mmu.h b/target/loongarch/cpu-mmu.h index 2d7ebb2..54fb732 100644 --- a/target/loongarch/cpu-mmu.h +++ b/target/loongarch/cpu-mmu.h
@@ -32,7 +32,9 @@ static inline bool cpu_has_ptw(CPULoongArchState *env) { - return !!FIELD_EX64(env->CSR_PWCH, CSR_PWCH, HPTW_EN); + CPUSysState *sys = env_sys(env); + + return !!FIELD_EX64(sys->CSR_PWCH, CSR_PWCH, HPTW_EN); } static inline bool pte_present(CPULoongArchState *env, uint64_t entry)
diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c index 8f277f7..fb03424 100644 --- a/target/loongarch/cpu.c +++ b/target/loongarch/cpu.c
@@ -62,6 +62,7 @@ LoongArchCPU *cpu = opaque; CPULoongArchState *env = &cpu->env; CPUState *cs = CPU(cpu); + CPUSysState *sys = env_sys(env); if (irq < 0 || irq >= N_IRQS) { return; @@ -70,8 +71,8 @@ if (kvm_enabled()) { kvm_loongarch_set_interrupt(cpu, irq, level); } else if (tcg_enabled()) { - env->CSR_ESTAT = deposit64(env->CSR_ESTAT, irq, 1, level != 0); - if (FIELD_EX64(env->CSR_ESTAT, CSR_ESTAT, IS)) { + sys->CSR_ESTAT = deposit64(sys->CSR_ESTAT, irq, 1, level != 0); + if (FIELD_EX64(sys->CSR_ESTAT, CSR_ESTAT, IS)) { cpu_interrupt(cs, CPU_INTERRUPT_HARD); } else { cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD); @@ -84,9 +85,10 @@ { uint32_t pending; uint32_t status; + CPUSysState *sys = env_sys(env); - pending = FIELD_EX64(env->CSR_ESTAT, CSR_ESTAT, IS); - status = FIELD_EX64(env->CSR_ECFG, CSR_ECFG, LIE); + pending = FIELD_EX64(sys->CSR_ESTAT, CSR_ESTAT, IS); + status = FIELD_EX64(sys->CSR_ECFG, CSR_ECFG, LIE); return (pending & status) != 0; } @@ -112,11 +114,12 @@ static bool initialized; LoongArchCPU *cpu = LOONGARCH_CPU(dev); CPULoongArchState *env = &cpu->env; + CPUSysState *sys = env_sys(env); int i, num; if (!initialized) { initialized = true; - num = FIELD_EX64(env->CSR_PRCFG1, CSR_PRCFG1, SAVE_NUM); + num = FIELD_EX64(sys->CSR_PRCFG1, CSR_PRCFG1, SAVE_NUM); for (i = num; i < 16; i++) { set_csr_flag(LOONGARCH_CSR_SAVE(i), CSRFL_UNUSED); } @@ -275,9 +278,11 @@ { LoongArchCPU *cpu = LOONGARCH_CPU(obj); CPULoongArchState *env = &cpu->env; + CPUSysState *sys; uint32_t data = 0, field; int i; + set_sys_state(env, &env->sys_states[0]); for (i = 0; i < 21; i++) { env->cpucfg[i] = 0x0; } @@ -381,18 +386,19 @@ data = FIELD_DP32(data, CPUCFG20, L3IU_SIZE, 6); env->cpucfg[20] = data; - env->CSR_ASID = FIELD_DP64(0, CSR_ASID, ASIDBITS, 0xa); + sys = env_sys(env); + sys->CSR_ASID = FIELD_DP64(0, CSR_ASID, ASIDBITS, 0xa); - env->CSR_PRCFG1 = FIELD_DP64(env->CSR_PRCFG1, CSR_PRCFG1, SAVE_NUM, 8); - env->CSR_PRCFG1 = FIELD_DP64(env->CSR_PRCFG1, CSR_PRCFG1, TIMER_BITS, 0x2f); - env->CSR_PRCFG1 = FIELD_DP64(env->CSR_PRCFG1, CSR_PRCFG1, VSMAX, 7); + sys->CSR_PRCFG1 = FIELD_DP64(sys->CSR_PRCFG1, CSR_PRCFG1, SAVE_NUM, 8); + sys->CSR_PRCFG1 = FIELD_DP64(sys->CSR_PRCFG1, CSR_PRCFG1, TIMER_BITS, 0x2f); + sys->CSR_PRCFG1 = FIELD_DP64(sys->CSR_PRCFG1, CSR_PRCFG1, VSMAX, 7); - env->CSR_PRCFG2 = 0x3ffff000; + sys->CSR_PRCFG2 = 0x3ffff000; - env->CSR_PRCFG3 = FIELD_DP64(env->CSR_PRCFG3, CSR_PRCFG3, TLB_TYPE, 2); - env->CSR_PRCFG3 = FIELD_DP64(env->CSR_PRCFG3, CSR_PRCFG3, MTLB_ENTRY, 63); - env->CSR_PRCFG3 = FIELD_DP64(env->CSR_PRCFG3, CSR_PRCFG3, STLB_WAYS, 7); - env->CSR_PRCFG3 = FIELD_DP64(env->CSR_PRCFG3, CSR_PRCFG3, STLB_SETS, 8); + sys->CSR_PRCFG3 = FIELD_DP64(sys->CSR_PRCFG3, CSR_PRCFG3, TLB_TYPE, 2); + sys->CSR_PRCFG3 = FIELD_DP64(sys->CSR_PRCFG3, CSR_PRCFG3, MTLB_ENTRY, 63); + sys->CSR_PRCFG3 = FIELD_DP64(sys->CSR_PRCFG3, CSR_PRCFG3, STLB_WAYS, 7); + sys->CSR_PRCFG3 = FIELD_DP64(sys->CSR_PRCFG3, CSR_PRCFG3, STLB_SETS, 8); cpu->msgint = ON_OFF_AUTO_OFF; cpu->ptw = ON_OFF_AUTO_OFF; @@ -406,6 +412,7 @@ uint32_t data = 0; int i; + set_sys_state(env, &env->sys_states[0]); for (i = 0; i < 21; i++) { env->cpucfg[i] = 0x0; } @@ -593,6 +600,7 @@ CPUState *cs = CPU(obj); LoongArchCPUClass *lacc = LOONGARCH_CPU_GET_CLASS(obj); CPULoongArchState *env = cpu_env(cs); + CPUSysState *sys = env_sys(env); if (lacc->parent_phases.hold) { lacc->parent_phases.hold(obj, type); @@ -616,55 +624,55 @@ int n; /* Set csr registers value after reset, see the manual 6.4. */ - env->CSR_CRMD = FIELD_DP64(env->CSR_CRMD, CSR_CRMD, PLV, 0); - env->CSR_CRMD = FIELD_DP64(env->CSR_CRMD, CSR_CRMD, IE, 0); - env->CSR_CRMD = FIELD_DP64(env->CSR_CRMD, CSR_CRMD, DA, 1); - env->CSR_CRMD = FIELD_DP64(env->CSR_CRMD, CSR_CRMD, PG, 0); - env->CSR_CRMD = FIELD_DP64(env->CSR_CRMD, CSR_CRMD, DATF, 0); - env->CSR_CRMD = FIELD_DP64(env->CSR_CRMD, CSR_CRMD, DATM, 0); + sys->CSR_CRMD = FIELD_DP64(sys->CSR_CRMD, CSR_CRMD, PLV, 0); + sys->CSR_CRMD = FIELD_DP64(sys->CSR_CRMD, CSR_CRMD, IE, 0); + sys->CSR_CRMD = FIELD_DP64(sys->CSR_CRMD, CSR_CRMD, DA, 1); + sys->CSR_CRMD = FIELD_DP64(sys->CSR_CRMD, CSR_CRMD, PG, 0); + sys->CSR_CRMD = FIELD_DP64(sys->CSR_CRMD, CSR_CRMD, DATF, 0); + sys->CSR_CRMD = FIELD_DP64(sys->CSR_CRMD, CSR_CRMD, DATM, 0); - env->CSR_EUEN = FIELD_DP64(env->CSR_EUEN, CSR_EUEN, FPE, 0); - env->CSR_EUEN = FIELD_DP64(env->CSR_EUEN, CSR_EUEN, SXE, 0); - env->CSR_EUEN = FIELD_DP64(env->CSR_EUEN, CSR_EUEN, ASXE, 0); - env->CSR_EUEN = FIELD_DP64(env->CSR_EUEN, CSR_EUEN, BTE, 0); + sys->CSR_EUEN = FIELD_DP64(sys->CSR_EUEN, CSR_EUEN, FPE, 0); + sys->CSR_EUEN = FIELD_DP64(sys->CSR_EUEN, CSR_EUEN, SXE, 0); + sys->CSR_EUEN = FIELD_DP64(sys->CSR_EUEN, CSR_EUEN, ASXE, 0); + sys->CSR_EUEN = FIELD_DP64(sys->CSR_EUEN, CSR_EUEN, BTE, 0); - env->CSR_MISC = 0; + sys->CSR_MISC = 0; - env->CSR_ECFG = FIELD_DP64(env->CSR_ECFG, CSR_ECFG, VS, 0); - env->CSR_ECFG = FIELD_DP64(env->CSR_ECFG, CSR_ECFG, LIE, 0); + sys->CSR_ECFG = FIELD_DP64(sys->CSR_ECFG, CSR_ECFG, VS, 0); + sys->CSR_ECFG = FIELD_DP64(sys->CSR_ECFG, CSR_ECFG, LIE, 0); - env->CSR_ESTAT = env->CSR_ESTAT & (~MAKE_64BIT_MASK(0, 2)); - env->CSR_RVACFG = FIELD_DP64(env->CSR_RVACFG, CSR_RVACFG, RBITS, 0); - env->CSR_CPUID = cs->cpu_index; - env->CSR_TCFG = FIELD_DP64(env->CSR_TCFG, CSR_TCFG, EN, 0); - env->CSR_LLBCTL = FIELD_DP64(env->CSR_LLBCTL, CSR_LLBCTL, KLO, 0); - env->CSR_TLBRERA = FIELD_DP64(env->CSR_TLBRERA, CSR_TLBRERA, ISTLBR, 0); - env->CSR_MERRCTL = FIELD_DP64(env->CSR_MERRCTL, CSR_MERRCTL, ISMERR, 0); - env->CSR_TID = cs->cpu_index; + sys->CSR_ESTAT = sys->CSR_ESTAT & (~MAKE_64BIT_MASK(0, 2)); + sys->CSR_RVACFG = FIELD_DP64(sys->CSR_RVACFG, CSR_RVACFG, RBITS, 0); + sys->CSR_CPUID = cs->cpu_index; + sys->CSR_TCFG = FIELD_DP64(sys->CSR_TCFG, CSR_TCFG, EN, 0); + sys->CSR_LLBCTL = FIELD_DP64(sys->CSR_LLBCTL, CSR_LLBCTL, KLO, 0); + sys->CSR_TLBRERA = FIELD_DP64(sys->CSR_TLBRERA, CSR_TLBRERA, ISTLBR, 0); + sys->CSR_MERRCTL = FIELD_DP64(sys->CSR_MERRCTL, CSR_MERRCTL, ISMERR, 0); + sys->CSR_TID = cs->cpu_index; /* * Workaround for edk2-stable202408, CSR PGD register is set only if * its value is equal to zero for boot cpu, it causes reboot issue. * * Here clear CSR registers relative with TLB. */ - env->CSR_PGDH = 0; - env->CSR_PGDL = 0; - env->CSR_PWCH = 0; - env->CSR_EENTRY = 0; - env->CSR_TLBRENTRY = 0; - env->CSR_MERRENTRY = 0; + sys->CSR_PGDH = 0; + sys->CSR_PGDL = 0; + sys->CSR_PWCH = 0; + sys->CSR_EENTRY = 0; + sys->CSR_TLBRENTRY = 0; + sys->CSR_MERRENTRY = 0; /* set CSR_PWCL.PTBASE and CSR_STLBPS.PS bits from CSR_PRCFG2 */ - if (env->CSR_PRCFG2 == 0) { - env->CSR_PRCFG2 = 0x3fffff000; + if (sys->CSR_PRCFG2 == 0) { + sys->CSR_PRCFG2 = 0x3fffff000; } - tlb_ps = ctz32(env->CSR_PRCFG2); - env->CSR_STLBPS = FIELD_DP64(env->CSR_STLBPS, CSR_STLBPS, PS, tlb_ps); - env->CSR_PWCL = FIELD_DP64(env->CSR_PWCL, CSR_PWCL, PTBASE, tlb_ps); + tlb_ps = ctz32(sys->CSR_PRCFG2); + sys->CSR_STLBPS = FIELD_DP64(sys->CSR_STLBPS, CSR_STLBPS, PS, tlb_ps); + sys->CSR_PWCL = FIELD_DP64(sys->CSR_PWCL, CSR_PWCL, PTBASE, tlb_ps); for (n = 0; n < 4; n++) { - env->CSR_DMW[n] = FIELD_DP64(env->CSR_DMW[n], CSR_DMW, PLV0, 0); - env->CSR_DMW[n] = FIELD_DP64(env->CSR_DMW[n], CSR_DMW, PLV1, 0); - env->CSR_DMW[n] = FIELD_DP64(env->CSR_DMW[n], CSR_DMW, PLV2, 0); - env->CSR_DMW[n] = FIELD_DP64(env->CSR_DMW[n], CSR_DMW, PLV3, 0); + sys->CSR_DMW[n] = FIELD_DP64(sys->CSR_DMW[n], CSR_DMW, PLV0, 0); + sys->CSR_DMW[n] = FIELD_DP64(sys->CSR_DMW[n], CSR_DMW, PLV1, 0); + sys->CSR_DMW[n] = FIELD_DP64(sys->CSR_DMW[n], CSR_DMW, PLV2, 0); + sys->CSR_DMW[n] = FIELD_DP64(sys->CSR_DMW[n], CSR_DMW, PLV3, 0); } #ifndef CONFIG_USER_ONLY @@ -753,7 +761,7 @@ { #ifndef CONFIG_USER_ONLY CPULoongArchState *env = cpu_env(cs); - CSRInfo *csr_info; + const CSRInfo *csr_info; int64_t *addr; int i, j, len, col = 0; @@ -775,7 +783,7 @@ qemu_fprintf(f, " CSR%03d:", col); } - addr = (void *)env + csr_info->offset; + addr = (void *)env + get_csr_offset(csr_info, 0); qemu_fprintf(f, " %s ", csr_info->name); len = strlen(csr_info->name); for (; len < 6; len++) {
diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h index 096d778..ad30c73 100644 --- a/target/loongarch/cpu.h +++ b/target/loongarch/cpu.h
@@ -317,21 +317,7 @@ #define CPU_VENDOR_LOONGSON "Loongson" #define CPU_MODEL_3A5000 "3A5000" #define CPU_MODEL_1C101 "1C101" - -typedef struct CPUArchState { - uint64_t gpr[32]; - uint64_t pc; - - fpr_t fpr[32]; - bool cf[8]; - uint32_t fcsr0; - lbt_t lbt; - - uint32_t cpucfg[21]; - uint32_t pv_features; - uint64_t vendor_id; - uint64_t cpu_id; - +typedef struct CPUSysState { /* LoongArch CSRs */ uint64_t CSR_CRMD; uint64_t CSR_PRMD; @@ -393,6 +379,23 @@ uint64_t CSR_MSGIS[N_MSGIS]; uint64_t CSR_MSGIR; uint64_t CSR_MSGIE; +} CPUSysState; + +typedef struct CPUArchState { + uint64_t gpr[32]; + uint64_t pc; + + fpr_t fpr[32]; + bool cf[8]; + uint32_t fcsr0; + lbt_t lbt; + + uint32_t cpucfg[21]; + uint32_t pv_features; + uint64_t vendor_id; + uint64_t cpu_id; + CPUSysState sys_states[1]; + struct { uint64_t guest_addr; } stealtime; @@ -415,6 +418,7 @@ AddressSpace *address_space_iocsr; uint32_t mp_state; #endif + CPUSysState *sys_state; } CPULoongArchState; typedef struct LoongArchCPUTopo { @@ -481,6 +485,16 @@ #define MMU_USER_IDX MMU_PLV_USER #define MMU_DA_IDX 4 +static inline CPUSysState *env_sys(CPULoongArchState *env) +{ + return env->sys_state; +} + +static inline void set_sys_state(CPULoongArchState *env, CPUSysState *sys) +{ + env->sys_state = sys; +} + static inline bool is_la64(CPULoongArchState *env) { return FIELD_EX32(env->cpucfg[1], CPUCFG1, ARCH) == CPUCFG1_ARCH_LA64; @@ -490,8 +504,9 @@ { /* VA32 if !LA64 or VA32L[1-3] */ bool va32 = !is_la64(env); - uint64_t plv = FIELD_EX64(env->CSR_CRMD, CSR_CRMD, PLV); - if (plv >= 1 && (FIELD_EX64(env->CSR_MISC, CSR_MISC, VA32) & (1 << plv))) { + CPUSysState *sys = env_sys(env); + uint64_t plv = FIELD_EX64(sys->CSR_CRMD, CSR_CRMD, PLV); + if (plv >= 1 && (FIELD_EX64(sys->CSR_MISC, CSR_MISC, VA32) & (1 << plv))) { va32 = true; } return va32;
diff --git a/target/loongarch/cpu_helper.c b/target/loongarch/cpu_helper.c index eb9684a..7f0e64a 100644 --- a/target/loongarch/cpu_helper.c +++ b/target/loongarch/cpu_helper.c
@@ -20,27 +20,29 @@ void get_dir_base_width(CPULoongArchState *env, uint64_t *dir_base, uint64_t *dir_width, unsigned int level) { + CPUSysState *sys = env_sys(env); + switch (level) { case 1: - *dir_base = FIELD_EX64(env->CSR_PWCL, CSR_PWCL, DIR1_BASE); - *dir_width = FIELD_EX64(env->CSR_PWCL, CSR_PWCL, DIR1_WIDTH); + *dir_base = FIELD_EX64(sys->CSR_PWCL, CSR_PWCL, DIR1_BASE); + *dir_width = FIELD_EX64(sys->CSR_PWCL, CSR_PWCL, DIR1_WIDTH); break; case 2: - *dir_base = FIELD_EX64(env->CSR_PWCL, CSR_PWCL, DIR2_BASE); - *dir_width = FIELD_EX64(env->CSR_PWCL, CSR_PWCL, DIR2_WIDTH); + *dir_base = FIELD_EX64(sys->CSR_PWCL, CSR_PWCL, DIR2_BASE); + *dir_width = FIELD_EX64(sys->CSR_PWCL, CSR_PWCL, DIR2_WIDTH); break; case 3: - *dir_base = FIELD_EX64(env->CSR_PWCH, CSR_PWCH, DIR3_BASE); - *dir_width = FIELD_EX64(env->CSR_PWCH, CSR_PWCH, DIR3_WIDTH); + *dir_base = FIELD_EX64(sys->CSR_PWCH, CSR_PWCH, DIR3_BASE); + *dir_width = FIELD_EX64(sys->CSR_PWCH, CSR_PWCH, DIR3_WIDTH); break; case 4: - *dir_base = FIELD_EX64(env->CSR_PWCH, CSR_PWCH, DIR4_BASE); - *dir_width = FIELD_EX64(env->CSR_PWCH, CSR_PWCH, DIR4_WIDTH); + *dir_base = FIELD_EX64(sys->CSR_PWCH, CSR_PWCH, DIR4_BASE); + *dir_width = FIELD_EX64(sys->CSR_PWCH, CSR_PWCH, DIR4_WIDTH); break; default: /* level may be zero for ldpte */ - *dir_base = FIELD_EX64(env->CSR_PWCL, CSR_PWCL, PTBASE); - *dir_width = FIELD_EX64(env->CSR_PWCL, CSR_PWCL, PTWIDTH); + *dir_base = FIELD_EX64(sys->CSR_PWCL, CSR_PWCL, PTBASE); + *dir_width = FIELD_EX64(sys->CSR_PWCL, CSR_PWCL, PTWIDTH); break; } } @@ -156,13 +158,13 @@ vaddr address; TLBRet ret; MemTxResult ret1; - + CPUSysState *sys = env_sys(env); address = context->addr; if ((address >> 63) & 0x1) { - base = env->CSR_PGDH; + base = sys->CSR_PGDH; } else { - base = env->CSR_PGDL; + base = sys->CSR_PGDL; } base &= palen_mask; @@ -315,8 +317,9 @@ int kernel_mode = mmu_idx == MMU_KERNEL_IDX; uint32_t plv, base_c, base_v; int64_t addr_high; - uint8_t da = FIELD_EX64(env->CSR_CRMD, CSR_CRMD, DA); - uint8_t pg = FIELD_EX64(env->CSR_CRMD, CSR_CRMD, PG); + CPUSysState *sys = env_sys(env); + uint8_t da = FIELD_EX64(sys->CSR_CRMD, CSR_CRMD, DA); + uint8_t pg = FIELD_EX64(sys->CSR_CRMD, CSR_CRMD, PG); vaddr address; /* Check PG and DA */ @@ -337,12 +340,12 @@ /* Check direct map window */ for (int i = 0; i < 4; i++) { if (is_la64(env)) { - base_c = FIELD_EX64(env->CSR_DMW[i], CSR_DMW_64, VSEG); + base_c = FIELD_EX64(sys->CSR_DMW[i], CSR_DMW_64, VSEG); } else { - base_c = FIELD_EX64(env->CSR_DMW[i], CSR_DMW_32, VSEG); + base_c = FIELD_EX64(sys->CSR_DMW[i], CSR_DMW_32, VSEG); } - if ((plv & env->CSR_DMW[i]) && (base_c == base_v)) { - context->physical = dmw_va2pa(env, address, env->CSR_DMW[i]); + if ((plv & sys->CSR_DMW[i]) && (base_c == base_v)) { + context->physical = dmw_va2pa(env, address, sys->CSR_DMW[i]); context->prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC; context->mmu_index = MMU_DA_IDX; return TLBRET_MATCH;
diff --git a/target/loongarch/csr.c b/target/loongarch/csr.c index fff2312..309b826 100644 --- a/target/loongarch/csr.c +++ b/target/loongarch/csr.c
@@ -9,19 +9,19 @@ #define CSR_OFF_FUNCS(NAME, FL, RD, WR) \ [LOONGARCH_CSR_##NAME] = { \ .name = (stringify(NAME)), \ - .offset = offsetof(CPULoongArchState, CSR_##NAME), \ + .offset = CSR_OFFSET(CSR_##NAME), \ .flags = FL, .readfn = RD, .writefn = WR \ } #define CSR_OFF_ARRAY(NAME, N) \ [LOONGARCH_CSR_##NAME(N)] = { \ .name = (stringify(NAME##N)), \ - .offset = offsetof(CPULoongArchState, CSR_##NAME[N]), \ - .flags = 0, .readfn = NULL, .writefn = NULL \ + .offset = CSR_OFFSET(CSR_##NAME[N]), \ + .flags = CSRFL_BASIC, .readfn = NULL, .writefn = NULL \ } #define CSR_OFF_FLAGS(NAME, FL) CSR_OFF_FUNCS(NAME, FL, NULL, NULL) -#define CSR_OFF(NAME) CSR_OFF_FLAGS(NAME, 0) +#define CSR_OFF(NAME) CSR_OFF_FLAGS(NAME, CSRFL_BASIC) static CSRInfo csr_info[] = { CSR_OFF_FLAGS(CRMD, CSRFL_EXITTB), @@ -144,7 +144,7 @@ } csr = &csr_info[csr_num]; - if (csr->offset == 0) { + if (csr->flags == 0) { return NULL; }
diff --git a/target/loongarch/csr.h b/target/loongarch/csr.h index 81a656b..c2b6b88 100644 --- a/target/loongarch/csr.h +++ b/target/loongarch/csr.h
@@ -8,12 +8,18 @@ #include "cpu-csr.h" +#define CSR_OFFSET(id) offsetof(CPUSysState, id) +#define CPU_CSR_OFFSET(id, vm_level) \ + (offsetof(CPULoongArchState, sys_states[vm_level]) \ + + CSR_OFFSET(id)) + typedef void (*GenCSRFunc)(void); enum { CSRFL_READONLY = (1 << 0), CSRFL_EXITTB = (1 << 1), CSRFL_IO = (1 << 2), CSRFL_UNUSED = (1 << 3), + CSRFL_BASIC = (1 << 4), }; typedef struct { @@ -26,4 +32,8 @@ CSRInfo *get_csr(unsigned int csr_num); bool set_csr_flag(unsigned int csr_num, int flag); +static inline unsigned int get_csr_offset(const CSRInfo *csr, int vm_level) +{ + return csr->offset + offsetof(CPULoongArchState, sys_states[vm_level]); +} #endif /* TARGET_LOONGARCH_CSR_H */
diff --git a/target/loongarch/gdbstub.c b/target/loongarch/gdbstub.c index 3e9bdfa..e02354c 100644 --- a/target/loongarch/gdbstub.c +++ b/target/loongarch/gdbstub.c
@@ -34,6 +34,7 @@ int loongarch_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n) { CPULoongArchState *env = cpu_env(cs); + CPUSysState *sys = env_sys(env); if (0 <= n && n <= 34) { uint64_t val; @@ -46,7 +47,7 @@ } else if (n == 33) { val = env->pc; } else /* if (n == 34) */ { - val = env->CSR_BADV; + val = sys->CSR_BADV; } if (is_la64(env)) {
diff --git a/target/loongarch/kvm/kvm.c b/target/loongarch/kvm/kvm.c index 4af4ab2..d6539c1 100644 --- a/target/loongarch/kvm/kvm.c +++ b/target/loongarch/kvm/kvm.c
@@ -161,6 +161,7 @@ int i, ret = 0; CPULoongArchState *env = cpu_env(cs); LoongArchCPU *cpu = LOONGARCH_CPU(cs); + CPUSysState *sys = env_sys(env); if (cpu->pmu != ON_OFF_AUTO_ON) { return 0; @@ -168,9 +169,9 @@ for (i = 0; i < env->perf_event_num; i++) { ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PERFCTRL(i)), - &env->CSR_PERFCTRL[i]); + &sys->CSR_PERFCTRL[i]); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PERFCNTR(i)), - &env->CSR_PERFCNTR[i]); + &sys->CSR_PERFCNTR[i]); } return ret; @@ -181,6 +182,7 @@ int i, ret = 0; CPULoongArchState *env = cpu_env(cs); LoongArchCPU *cpu = LOONGARCH_CPU(cs); + CPUSysState *sys = env_sys(env); if (cpu->pmu != ON_OFF_AUTO_ON) { return 0; @@ -188,9 +190,9 @@ for (i = 0; i < env->perf_event_num; i++) { ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PERFCTRL(i)), - &env->CSR_PERFCTRL[i]); + &sys->CSR_PERFCTRL[i]); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PERFCNTR(i)), - &env->CSR_PERFCNTR[i]); + &sys->CSR_PERFCNTR[i]); } return ret; @@ -200,170 +202,171 @@ { int ret = 0; CPULoongArchState *env = cpu_env(cs); + CPUSysState *sys = env_sys(env); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_CRMD), - &env->CSR_CRMD); + &sys->CSR_CRMD); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PRMD), - &env->CSR_PRMD); + &sys->CSR_PRMD); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_EUEN), - &env->CSR_EUEN); + &sys->CSR_EUEN); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_MISC), - &env->CSR_MISC); + &sys->CSR_MISC); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_ECFG), - &env->CSR_ECFG); + &sys->CSR_ECFG); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_ESTAT), - &env->CSR_ESTAT); + &sys->CSR_ESTAT); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_ERA), - &env->CSR_ERA); + &sys->CSR_ERA); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_BADV), - &env->CSR_BADV); + &sys->CSR_BADV); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_BADI), - &env->CSR_BADI); + &sys->CSR_BADI); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_EENTRY), - &env->CSR_EENTRY); + &sys->CSR_EENTRY); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBIDX), - &env->CSR_TLBIDX); + &sys->CSR_TLBIDX); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBEHI), - &env->CSR_TLBEHI); + &sys->CSR_TLBEHI); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBELO0), - &env->CSR_TLBELO0); + &sys->CSR_TLBELO0); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBELO1), - &env->CSR_TLBELO1); + &sys->CSR_TLBELO1); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_ASID), - &env->CSR_ASID); + &sys->CSR_ASID); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PGDL), - &env->CSR_PGDL); + &sys->CSR_PGDL); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PGDH), - &env->CSR_PGDH); + &sys->CSR_PGDH); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PGD), - &env->CSR_PGD); + &sys->CSR_PGD); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PWCL), - &env->CSR_PWCL); + &sys->CSR_PWCL); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PWCH), - &env->CSR_PWCH); + &sys->CSR_PWCH); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_STLBPS), - &env->CSR_STLBPS); + &sys->CSR_STLBPS); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_RVACFG), - &env->CSR_RVACFG); + &sys->CSR_RVACFG); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_CPUID), - &env->CSR_CPUID); + &sys->CSR_CPUID); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PRCFG1), - &env->CSR_PRCFG1); + &sys->CSR_PRCFG1); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PRCFG2), - &env->CSR_PRCFG2); + &sys->CSR_PRCFG2); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PRCFG3), - &env->CSR_PRCFG3); + &sys->CSR_PRCFG3); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(0)), - &env->CSR_SAVE[0]); + &sys->CSR_SAVE[0]); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(1)), - &env->CSR_SAVE[1]); + &sys->CSR_SAVE[1]); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(2)), - &env->CSR_SAVE[2]); + &sys->CSR_SAVE[2]); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(3)), - &env->CSR_SAVE[3]); + &sys->CSR_SAVE[3]); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(4)), - &env->CSR_SAVE[4]); + &sys->CSR_SAVE[4]); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(5)), - &env->CSR_SAVE[5]); + &sys->CSR_SAVE[5]); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(6)), - &env->CSR_SAVE[6]); + &sys->CSR_SAVE[6]); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(7)), - &env->CSR_SAVE[7]); + &sys->CSR_SAVE[7]); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TID), - &env->CSR_TID); + &sys->CSR_TID); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_CNTC), - &env->CSR_CNTC); + &sys->CSR_CNTC); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TICLR), - &env->CSR_TICLR); + &sys->CSR_TICLR); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_LLBCTL), - &env->CSR_LLBCTL); + &sys->CSR_LLBCTL); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_IMPCTL1), - &env->CSR_IMPCTL1); + &sys->CSR_IMPCTL1); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_IMPCTL2), - &env->CSR_IMPCTL2); + &sys->CSR_IMPCTL2); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBRENTRY), - &env->CSR_TLBRENTRY); + &sys->CSR_TLBRENTRY); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBRBADV), - &env->CSR_TLBRBADV); + &sys->CSR_TLBRBADV); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBRERA), - &env->CSR_TLBRERA); + &sys->CSR_TLBRERA); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBRSAVE), - &env->CSR_TLBRSAVE); + &sys->CSR_TLBRSAVE); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBRELO0), - &env->CSR_TLBRELO0); + &sys->CSR_TLBRELO0); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBRELO1), - &env->CSR_TLBRELO1); + &sys->CSR_TLBRELO1); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBREHI), - &env->CSR_TLBREHI); + &sys->CSR_TLBREHI); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBRPRMD), - &env->CSR_TLBRPRMD); + &sys->CSR_TLBRPRMD); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_DMW(0)), - &env->CSR_DMW[0]); + &sys->CSR_DMW[0]); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_DMW(1)), - &env->CSR_DMW[1]); + &sys->CSR_DMW[1]); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_DMW(2)), - &env->CSR_DMW[2]); + &sys->CSR_DMW[2]); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_DMW(3)), - &env->CSR_DMW[3]); + &sys->CSR_DMW[3]); ret |= kvm_loongarch_get_pmu(cs); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TVAL), - &env->CSR_TVAL); + &sys->CSR_TVAL); ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TCFG), - &env->CSR_TCFG); + &sys->CSR_TCFG); return ret; } @@ -372,165 +375,166 @@ { int ret = 0; CPULoongArchState *env = cpu_env(cs); + CPUSysState *sys = env_sys(env); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_CRMD), - &env->CSR_CRMD); + &sys->CSR_CRMD); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PRMD), - &env->CSR_PRMD); + &sys->CSR_PRMD); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_EUEN), - &env->CSR_EUEN); + &sys->CSR_EUEN); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_MISC), - &env->CSR_MISC); + &sys->CSR_MISC); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_ECFG), - &env->CSR_ECFG); + &sys->CSR_ECFG); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_ESTAT), - &env->CSR_ESTAT); + &sys->CSR_ESTAT); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_ERA), - &env->CSR_ERA); + &sys->CSR_ERA); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_BADV), - &env->CSR_BADV); + &sys->CSR_BADV); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_BADI), - &env->CSR_BADI); + &sys->CSR_BADI); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_EENTRY), - &env->CSR_EENTRY); + &sys->CSR_EENTRY); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBIDX), - &env->CSR_TLBIDX); + &sys->CSR_TLBIDX); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBEHI), - &env->CSR_TLBEHI); + &sys->CSR_TLBEHI); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBELO0), - &env->CSR_TLBELO0); + &sys->CSR_TLBELO0); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBELO1), - &env->CSR_TLBELO1); + &sys->CSR_TLBELO1); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_ASID), - &env->CSR_ASID); + &sys->CSR_ASID); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PGDL), - &env->CSR_PGDL); + &sys->CSR_PGDL); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PGDH), - &env->CSR_PGDH); + &sys->CSR_PGDH); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PGD), - &env->CSR_PGD); + &sys->CSR_PGD); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PWCL), - &env->CSR_PWCL); + &sys->CSR_PWCL); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PWCH), - &env->CSR_PWCH); + &sys->CSR_PWCH); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_STLBPS), - &env->CSR_STLBPS); + &sys->CSR_STLBPS); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_RVACFG), - &env->CSR_RVACFG); + &sys->CSR_RVACFG); /* CPUID is constant after poweron, it should be set only once */ if (level >= KVM_PUT_FULL_STATE) { ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_CPUID), - &env->CSR_CPUID); + &sys->CSR_CPUID); } ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PRCFG1), - &env->CSR_PRCFG1); + &sys->CSR_PRCFG1); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PRCFG2), - &env->CSR_PRCFG2); + &sys->CSR_PRCFG2); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PRCFG3), - &env->CSR_PRCFG3); + &sys->CSR_PRCFG3); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(0)), - &env->CSR_SAVE[0]); + &sys->CSR_SAVE[0]); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(1)), - &env->CSR_SAVE[1]); + &sys->CSR_SAVE[1]); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(2)), - &env->CSR_SAVE[2]); + &sys->CSR_SAVE[2]); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(3)), - &env->CSR_SAVE[3]); + &sys->CSR_SAVE[3]); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(4)), - &env->CSR_SAVE[4]); + &sys->CSR_SAVE[4]); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(5)), - &env->CSR_SAVE[5]); + &sys->CSR_SAVE[5]); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(6)), - &env->CSR_SAVE[6]); + &sys->CSR_SAVE[6]); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(7)), - &env->CSR_SAVE[7]); + &sys->CSR_SAVE[7]); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TID), - &env->CSR_TID); + &sys->CSR_TID); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_CNTC), - &env->CSR_CNTC); + &sys->CSR_CNTC); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TICLR), - &env->CSR_TICLR); + &sys->CSR_TICLR); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_LLBCTL), - &env->CSR_LLBCTL); + &sys->CSR_LLBCTL); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_IMPCTL1), - &env->CSR_IMPCTL1); + &sys->CSR_IMPCTL1); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_IMPCTL2), - &env->CSR_IMPCTL2); + &sys->CSR_IMPCTL2); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBRENTRY), - &env->CSR_TLBRENTRY); + &sys->CSR_TLBRENTRY); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBRBADV), - &env->CSR_TLBRBADV); + &sys->CSR_TLBRBADV); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBRERA), - &env->CSR_TLBRERA); + &sys->CSR_TLBRERA); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBRSAVE), - &env->CSR_TLBRSAVE); + &sys->CSR_TLBRSAVE); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBRELO0), - &env->CSR_TLBRELO0); + &sys->CSR_TLBRELO0); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBRELO1), - &env->CSR_TLBRELO1); + &sys->CSR_TLBRELO1); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBREHI), - &env->CSR_TLBREHI); + &sys->CSR_TLBREHI); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBRPRMD), - &env->CSR_TLBRPRMD); + &sys->CSR_TLBRPRMD); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_DMW(0)), - &env->CSR_DMW[0]); + &sys->CSR_DMW[0]); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_DMW(1)), - &env->CSR_DMW[1]); + &sys->CSR_DMW[1]); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_DMW(2)), - &env->CSR_DMW[2]); + &sys->CSR_DMW[2]); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_DMW(3)), - &env->CSR_DMW[3]); + &sys->CSR_DMW[3]); ret |= kvm_loongarch_put_pmu(cs); @@ -539,10 +543,10 @@ * guest timer */ ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TVAL), - &env->CSR_TVAL); + &sys->CSR_TVAL); ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TCFG), - &env->CSR_TCFG); + &sys->CSR_TCFG); return ret; }
diff --git a/target/loongarch/machine.c b/target/loongarch/machine.c index 4db53fe..931a5ca 100644 --- a/target/loongarch/machine.c +++ b/target/loongarch/machine.c
@@ -58,9 +58,9 @@ .minimum_version_id = 1, .needed = msgint_needed, .fields = (const VMStateField[]) { - VMSTATE_UINT64_ARRAY(env.CSR_MSGIS, LoongArchCPU, N_MSGIS), - VMSTATE_UINT64(env.CSR_MSGIR, LoongArchCPU), - VMSTATE_UINT64(env.CSR_MSGIE, LoongArchCPU), + VMSTATE_UINT64_ARRAY(env.sys_states[0].CSR_MSGIS, LoongArchCPU, N_MSGIS), + VMSTATE_UINT64(env.sys_states[0].CSR_MSGIR, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_MSGIE, LoongArchCPU), VMSTATE_END_OF_LIST() }, }; @@ -167,8 +167,10 @@ .needed = pmu_needed, .fields = (const VMStateField[]) { VMSTATE_UINT32(env.perf_event_num, LoongArchCPU), - VMSTATE_UINT64_ARRAY(env.CSR_PERFCTRL, LoongArchCPU, MAX_PERF_EVENTS), - VMSTATE_UINT64_ARRAY(env.CSR_PERFCNTR, LoongArchCPU, MAX_PERF_EVENTS), + VMSTATE_UINT64_ARRAY(env.sys_states[0].CSR_PERFCTRL, LoongArchCPU,\ + MAX_PERF_EVENTS), + VMSTATE_UINT64_ARRAY(env.sys_states[0].CSR_PERFCNTR, LoongArchCPU, \ + MAX_PERF_EVENTS), VMSTATE_END_OF_LIST() }, }; @@ -215,61 +217,61 @@ VMSTATE_UINT64(env.pc, LoongArchCPU), /* Remaining CSRs */ - VMSTATE_UINT64(env.CSR_CRMD, LoongArchCPU), - VMSTATE_UINT64(env.CSR_PRMD, LoongArchCPU), - VMSTATE_UINT64(env.CSR_EUEN, LoongArchCPU), - VMSTATE_UINT64(env.CSR_MISC, LoongArchCPU), - VMSTATE_UINT64(env.CSR_ECFG, LoongArchCPU), - VMSTATE_UINT64(env.CSR_ESTAT, LoongArchCPU), - VMSTATE_UINT64(env.CSR_ERA, LoongArchCPU), - VMSTATE_UINT64(env.CSR_BADV, LoongArchCPU), - VMSTATE_UINT64(env.CSR_BADI, LoongArchCPU), - VMSTATE_UINT64(env.CSR_EENTRY, LoongArchCPU), - VMSTATE_UINT64(env.CSR_TLBIDX, LoongArchCPU), - VMSTATE_UINT64(env.CSR_TLBEHI, LoongArchCPU), - VMSTATE_UINT64(env.CSR_TLBELO0, LoongArchCPU), - VMSTATE_UINT64(env.CSR_TLBELO1, LoongArchCPU), - VMSTATE_UINT64(env.CSR_ASID, LoongArchCPU), - VMSTATE_UINT64(env.CSR_PGDL, LoongArchCPU), - VMSTATE_UINT64(env.CSR_PGDH, LoongArchCPU), - VMSTATE_UINT64(env.CSR_PGD, LoongArchCPU), - VMSTATE_UINT64(env.CSR_PWCL, LoongArchCPU), - VMSTATE_UINT64(env.CSR_PWCH, LoongArchCPU), - VMSTATE_UINT64(env.CSR_STLBPS, LoongArchCPU), - VMSTATE_UINT64(env.CSR_RVACFG, LoongArchCPU), - VMSTATE_UINT64(env.CSR_PRCFG1, LoongArchCPU), - VMSTATE_UINT64(env.CSR_PRCFG2, LoongArchCPU), - VMSTATE_UINT64(env.CSR_PRCFG3, LoongArchCPU), - VMSTATE_UINT64_ARRAY(env.CSR_SAVE, LoongArchCPU, 16), - VMSTATE_UINT64(env.CSR_TID, LoongArchCPU), - VMSTATE_UINT64(env.CSR_TCFG, LoongArchCPU), - VMSTATE_UINT64(env.CSR_TVAL, LoongArchCPU), - VMSTATE_UINT64(env.CSR_CNTC, LoongArchCPU), - VMSTATE_UINT64(env.CSR_TICLR, LoongArchCPU), - VMSTATE_UINT64(env.CSR_LLBCTL, LoongArchCPU), - VMSTATE_UINT64(env.CSR_IMPCTL1, LoongArchCPU), - VMSTATE_UINT64(env.CSR_IMPCTL2, LoongArchCPU), - VMSTATE_UINT64(env.CSR_TLBRENTRY, LoongArchCPU), - VMSTATE_UINT64(env.CSR_TLBRBADV, LoongArchCPU), - VMSTATE_UINT64(env.CSR_TLBRERA, LoongArchCPU), - VMSTATE_UINT64(env.CSR_TLBRSAVE, LoongArchCPU), - VMSTATE_UINT64(env.CSR_TLBRELO0, LoongArchCPU), - VMSTATE_UINT64(env.CSR_TLBRELO1, LoongArchCPU), - VMSTATE_UINT64(env.CSR_TLBREHI, LoongArchCPU), - VMSTATE_UINT64(env.CSR_TLBRPRMD, LoongArchCPU), - VMSTATE_UINT64(env.CSR_MERRCTL, LoongArchCPU), - VMSTATE_UINT64(env.CSR_MERRINFO1, LoongArchCPU), - VMSTATE_UINT64(env.CSR_MERRINFO2, LoongArchCPU), - VMSTATE_UINT64(env.CSR_MERRENTRY, LoongArchCPU), - VMSTATE_UINT64(env.CSR_MERRERA, LoongArchCPU), - VMSTATE_UINT64(env.CSR_MERRSAVE, LoongArchCPU), - VMSTATE_UINT64(env.CSR_CTAG, LoongArchCPU), - VMSTATE_UINT64_ARRAY(env.CSR_DMW, LoongArchCPU, 4), + VMSTATE_UINT64(env.sys_states[0].CSR_CRMD, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_PRMD, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_EUEN, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_MISC, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_ECFG, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_ESTAT, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_ERA, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_BADV, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_BADI, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_EENTRY, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_TLBIDX, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_TLBEHI, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_TLBELO0, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_TLBELO1, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_ASID, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_PGDL, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_PGDH, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_PGD, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_PWCL, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_PWCH, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_STLBPS, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_RVACFG, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_PRCFG1, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_PRCFG2, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_PRCFG3, LoongArchCPU), + VMSTATE_UINT64_ARRAY(env.sys_states[0].CSR_SAVE, LoongArchCPU, 16), + VMSTATE_UINT64(env.sys_states[0].CSR_TID, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_TCFG, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_TVAL, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_CNTC, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_TICLR, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_LLBCTL, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_IMPCTL1, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_IMPCTL2, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_TLBRENTRY, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_TLBRBADV, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_TLBRERA, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_TLBRSAVE, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_TLBRELO0, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_TLBRELO1, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_TLBREHI, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_TLBRPRMD, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_MERRCTL, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_MERRINFO1, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_MERRINFO2, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_MERRENTRY, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_MERRERA, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_MERRSAVE, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_CTAG, LoongArchCPU), + VMSTATE_UINT64_ARRAY(env.sys_states[0].CSR_DMW, LoongArchCPU, 4), /* Debug CSRs */ - VMSTATE_UINT64(env.CSR_DBG, LoongArchCPU), - VMSTATE_UINT64(env.CSR_DERA, LoongArchCPU), - VMSTATE_UINT64(env.CSR_DSAVE, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_DBG, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_DERA, LoongArchCPU), + VMSTATE_UINT64(env.sys_states[0].CSR_DSAVE, LoongArchCPU), VMSTATE_UINT64(kvm_state_counter, LoongArchCPU), /* PV steal time */
diff --git a/target/loongarch/tcg/constant_timer.c b/target/loongarch/tcg/constant_timer.c index 1851f53..f56e76d 100644 --- a/target/loongarch/tcg/constant_timer.c +++ b/target/loongarch/tcg/constant_timer.c
@@ -34,9 +34,10 @@ uint64_t value) { CPULoongArchState *env = &cpu->env; + CPUSysState *sys = env_sys(env); uint64_t now, next; - env->CSR_TCFG = value; + sys->CSR_TCFG = value; if (value & CONSTANT_TIMER_ENABLE) { now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); next = now + (value & CONSTANT_TIMER_TICK_MASK) * TIMER_PERIOD; @@ -50,14 +51,15 @@ { LoongArchCPU *cpu = opaque; CPULoongArchState *env = &cpu->env; + CPUSysState *sys = env_sys(env); uint64_t now, next; - if (FIELD_EX64(env->CSR_TCFG, CSR_TCFG, PERIODIC)) { + if (FIELD_EX64(sys->CSR_TCFG, CSR_TCFG, PERIODIC)) { now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); - next = now + (env->CSR_TCFG & CONSTANT_TIMER_TICK_MASK) * TIMER_PERIOD; + next = now + (sys->CSR_TCFG & CONSTANT_TIMER_TICK_MASK) * TIMER_PERIOD; timer_mod(&cpu->timer, next); } else { - env->CSR_TCFG = FIELD_DP64(env->CSR_TCFG, CSR_TCFG, EN, 0); + sys->CSR_TCFG = FIELD_DP64(sys->CSR_TCFG, CSR_TCFG, EN, 0); } loongarch_cpu_set_irq(opaque, IRQ_TIMER, 1);
diff --git a/target/loongarch/tcg/csr_helper.c b/target/loongarch/tcg/csr_helper.c index cd35ca9..7dc33bc 100644 --- a/target/loongarch/tcg/csr_helper.c +++ b/target/loongarch/tcg/csr_helper.c
@@ -20,7 +20,8 @@ target_ulong helper_csrwr_stlbps(CPULoongArchState *env, target_ulong val) { - int64_t old_v = env->CSR_STLBPS; + CPUSysState *sys = env_sys(env); + int64_t old_v = sys->CSR_STLBPS; /* * The real hardware only supports the min tlb_ps is 12 @@ -33,7 +34,7 @@ } else { /* Only update PS field, reserved bit keeps zero */ val = FIELD_DP64(val, CSR_STLBPS, RESERVE, 0); - env->CSR_STLBPS = val; + sys->CSR_STLBPS = val; } return old_v; @@ -42,17 +43,18 @@ target_ulong helper_csrrd_pgd(CPULoongArchState *env) { int64_t v; + CPUSysState *sys = env_sys(env); - if (env->CSR_TLBRERA & 0x1) { - v = env->CSR_TLBRBADV; + if (sys->CSR_TLBRERA & 0x1) { + v = sys->CSR_TLBRBADV; } else { - v = env->CSR_BADV; + v = sys->CSR_BADV; } if ((v >> 63) & 0x1) { - v = env->CSR_PGDH; + v = sys->CSR_PGDH; } else { - v = env->CSR_PGDL; + v = sys->CSR_PGDL; } return v; @@ -61,10 +63,11 @@ target_ulong helper_csrrd_cpuid(CPULoongArchState *env) { LoongArchCPU *lac = env_archcpu(env); + CPUSysState *sys = env_sys(env); - env->CSR_CPUID = CPU(lac)->cpu_index; + sys->CSR_CPUID = CPU(lac)->cpu_index; - return env->CSR_CPUID; + return sys->CSR_CPUID; } target_ulong helper_csrrd_tval(CPULoongArchState *env) @@ -77,16 +80,17 @@ target_ulong helper_csrrd_msgir(CPULoongArchState *env) { int irq, new; + CPUSysState *sys = env_sys(env); - irq = find_first_bit((unsigned long *)env->CSR_MSGIS, 256); + irq = find_first_bit((unsigned long *)sys->CSR_MSGIS, 256); if (irq < 256) { - clear_bit(irq, (unsigned long *)env->CSR_MSGIS); - new = find_first_bit((unsigned long *)env->CSR_MSGIS, 256); + clear_bit(irq, (unsigned long *)sys->CSR_MSGIS); + new = find_first_bit((unsigned long *)sys->CSR_MSGIS, 256); if (new < 256) { return irq; } - env->CSR_ESTAT = FIELD_DP64(env->CSR_ESTAT, CSR_ESTAT, MSGINT, 0); + sys->CSR_ESTAT = FIELD_DP64(sys->CSR_ESTAT, CSR_ESTAT, MSGINT, 0); } else { /* bit 31 set 1 for no invalid irq */ irq = BIT(31); @@ -97,21 +101,23 @@ target_ulong helper_csrwr_estat(CPULoongArchState *env, target_ulong val) { - int64_t old_v = env->CSR_ESTAT; + CPUSysState *sys = env_sys(env); + int64_t old_v = sys->CSR_ESTAT; /* Only IS[1:0] can be written */ - env->CSR_ESTAT = deposit64(env->CSR_ESTAT, 0, 2, val); + sys->CSR_ESTAT = deposit64(sys->CSR_ESTAT, 0, 2, val); return old_v; } target_ulong helper_csrwr_asid(CPULoongArchState *env, target_ulong val) { - int64_t old_v = env->CSR_ASID; + CPUSysState *sys = env_sys(env); + int64_t old_v = sys->CSR_ASID; /* Only ASID filed of CSR_ASID can be written */ - env->CSR_ASID = deposit64(env->CSR_ASID, 0, 10, val); - if (old_v != env->CSR_ASID) { + sys->CSR_ASID = deposit64(sys->CSR_ASID, 0, 10, val); + if (old_v != sys->CSR_ASID) { tlb_flush(env_cpu(env)); } return old_v; @@ -120,7 +126,8 @@ target_ulong helper_csrwr_tcfg(CPULoongArchState *env, target_ulong val) { LoongArchCPU *cpu = env_archcpu(env); - int64_t old_v = env->CSR_TCFG; + CPUSysState *sys = env_sys(env); + int64_t old_v = sys->CSR_TCFG; cpu_loongarch_store_constant_timer_config(cpu, val); @@ -143,7 +150,8 @@ target_ulong helper_csrwr_pwcl(CPULoongArchState *env, target_ulong val) { uint8_t shift, ptbase; - int64_t old_v = env->CSR_PWCL; + CPUSysState *sys = env_sys(env); + int64_t old_v = sys->CSR_PWCL; /* * The real hardware only supports 64bit PTE width now, 128bit or others @@ -160,14 +168,15 @@ qemu_log_mask(LOG_GUEST_ERROR, "Attempted set ptbase 2^%d\n", ptbase); } - env->CSR_PWCL = val; + sys->CSR_PWCL = val; return old_v; } target_ulong helper_csrwr_pwch(CPULoongArchState *env, target_ulong val) { uint8_t has_ptw; - int64_t old_v = env->CSR_PWCH; + CPUSysState *sys = env_sys(env); + int64_t old_v = sys->CSR_PWCH; val = FIELD_DP64(val, CSR_PWCH, RESERVE, 0); has_ptw = FIELD_EX32(env->cpucfg[2], CPUCFG2, HPTW); @@ -175,6 +184,6 @@ val = FIELD_DP64(val, CSR_PWCH, HPTW_EN, 0); } - env->CSR_PWCH = val; + sys->CSR_PWCH = val; return old_v; }
diff --git a/target/loongarch/tcg/insn_trans/trans_extra.c.inc b/target/loongarch/tcg/insn_trans/trans_extra.c.inc index 298a80c..655dce3 100644 --- a/target/loongarch/tcg/insn_trans/trans_extra.c.inc +++ b/target/loongarch/tcg/insn_trans/trans_extra.c.inc
@@ -3,6 +3,7 @@ * Copyright (c) 2021 Loongson Technology Corporation Limited */ +#include "csr.h" static bool trans_break(DisasContext *ctx, arg_break *a) { generate_exception(ctx, EXCCODE_BRK); @@ -46,13 +47,16 @@ { TCGv dst1 = gpr_dst(ctx, a->rd, EXT_NONE); TCGv dst2 = gpr_dst(ctx, a->rj, EXT_NONE); + tcg_target_long offset; translator_io_start(&ctx->base); gen_helper_rdtime_d(dst1, tcg_env); if (word) { tcg_gen_sextract_tl(dst1, dst1, high ? 32 : 0, 32); } - tcg_gen_ld_i64(dst2, tcg_env, offsetof(CPULoongArchState, CSR_TID)); + + offset = CPU_CSR_OFFSET(CSR_TID, 0); + tcg_gen_ld_i64(dst2, tcg_env, offset); return true; }
diff --git a/target/loongarch/tcg/insn_trans/trans_privileged.c.inc b/target/loongarch/tcg/insn_trans/trans_privileged.c.inc index 2094d18..6728ce5 100644 --- a/target/loongarch/tcg/insn_trans/trans_privileged.c.inc +++ b/target/loongarch/tcg/insn_trans/trans_privileged.c.inc
@@ -106,6 +106,7 @@ TCGv dest; const CSRInfo *csr; GenCSRRead readfn; + tcg_target_long offset; if (check_plv(ctx)) { return false; @@ -121,7 +122,8 @@ if (readfn) { readfn(dest, tcg_env); } else { - tcg_gen_ld_tl(dest, tcg_env, csr->offset); + offset = get_csr_offset(csr, 0); + tcg_gen_ld_tl(dest, tcg_env, offset); } } gen_set_gpr(a->rd, dest, EXT_NONE); @@ -133,6 +135,7 @@ TCGv dest, src1; const CSRInfo *csr; GenCSRWrite writefn; + tcg_target_long offset; if (check_plv(ctx)) { return false; @@ -154,8 +157,9 @@ writefn(dest, tcg_env, src1); } else { dest = tcg_temp_new(); - tcg_gen_ld_tl(dest, tcg_env, csr->offset); - tcg_gen_st_tl(src1, tcg_env, csr->offset); + offset = get_csr_offset(csr, 0); + tcg_gen_ld_tl(dest, tcg_env, offset); + tcg_gen_st_tl(src1, tcg_env, offset); } gen_set_gpr(a->rd, dest, EXT_NONE); return true; @@ -166,6 +170,7 @@ TCGv src1, mask, oldv, newv, temp; const CSRInfo *csr; GenCSRWrite writefn; + tcg_target_long offset; if (check_plv(ctx)) { return false; @@ -191,7 +196,8 @@ newv = tcg_temp_new(); temp = tcg_temp_new(); - tcg_gen_ld_tl(oldv, tcg_env, csr->offset); + offset = get_csr_offset(csr, 0); + tcg_gen_ld_tl(oldv, tcg_env, offset); tcg_gen_and_tl(newv, src1, mask); tcg_gen_andc_tl(temp, oldv, mask); tcg_gen_or_tl(newv, newv, temp); @@ -200,7 +206,7 @@ if (writefn) { writefn(oldv, tcg_env, newv); } else { - tcg_gen_st_tl(newv, tcg_env, csr->offset); + tcg_gen_st_tl(newv, tcg_env, offset); } gen_set_gpr(a->rd, oldv, EXT_NONE); return true;
diff --git a/target/loongarch/tcg/op_helper.c b/target/loongarch/tcg/op_helper.c index 16ac0d4..e63ac66 100644 --- a/target/loongarch/tcg/op_helper.c +++ b/target/loongarch/tcg/op_helper.c
@@ -46,16 +46,20 @@ /* loongarch assert op */ void helper_asrtle_d(CPULoongArchState *env, target_ulong rj, target_ulong rk) { + CPUSysState *sys = env_sys(env); + if (rj > rk) { - env->CSR_BADV = rj; + sys->CSR_BADV = rj; do_raise_exception(env, EXCCODE_BCE, GETPC()); } } void helper_asrtgt_d(CPULoongArchState *env, target_ulong rj, target_ulong rk) { + CPUSysState *sys = env_sys(env); + if (rj <= rk) { - env->CSR_BADV = rj; + sys->CSR_BADV = rj; do_raise_exception(env, EXCCODE_BCE, GETPC()); } } @@ -91,9 +95,10 @@ #else uint64_t plv; LoongArchCPU *cpu = env_archcpu(env); + CPUSysState *sys = env_sys(env); - plv = FIELD_EX64(env->CSR_CRMD, CSR_CRMD, PLV); - if (extract64(env->CSR_MISC, R_CSR_MISC_DRDTL_SHIFT + plv, 1)) { + plv = FIELD_EX64(sys->CSR_CRMD, CSR_CRMD, PLV); + if (extract64(sys->CSR_MISC, R_CSR_MISC_DRDTL_SHIFT + plv, 1)) { do_raise_exception(env, EXCCODE_IPE, GETPC()); } @@ -105,26 +110,28 @@ void helper_ertn(CPULoongArchState *env) { uint64_t csr_pplv, csr_pie; - if (FIELD_EX64(env->CSR_TLBRERA, CSR_TLBRERA, ISTLBR)) { - csr_pplv = FIELD_EX64(env->CSR_TLBRPRMD, CSR_TLBRPRMD, PPLV); - csr_pie = FIELD_EX64(env->CSR_TLBRPRMD, CSR_TLBRPRMD, PIE); + CPUSysState *sys = env_sys(env); - env->CSR_TLBRERA = FIELD_DP64(env->CSR_TLBRERA, CSR_TLBRERA, ISTLBR, 0); - env->CSR_CRMD = FIELD_DP64(env->CSR_CRMD, CSR_CRMD, DA, 0); - env->CSR_CRMD = FIELD_DP64(env->CSR_CRMD, CSR_CRMD, PG, 1); - set_pc(env, env->CSR_TLBRERA); + if (FIELD_EX64(sys->CSR_TLBRERA, CSR_TLBRERA, ISTLBR)) { + csr_pplv = FIELD_EX64(sys->CSR_TLBRPRMD, CSR_TLBRPRMD, PPLV); + csr_pie = FIELD_EX64(sys->CSR_TLBRPRMD, CSR_TLBRPRMD, PIE); + + sys->CSR_TLBRERA = FIELD_DP64(sys->CSR_TLBRERA, CSR_TLBRERA, ISTLBR, 0); + sys->CSR_CRMD = FIELD_DP64(sys->CSR_CRMD, CSR_CRMD, DA, 0); + sys->CSR_CRMD = FIELD_DP64(sys->CSR_CRMD, CSR_CRMD, PG, 1); + set_pc(env, sys->CSR_TLBRERA); qemu_log_mask(CPU_LOG_INT, "%s: TLBRERA " TARGET_FMT_lx "\n", - __func__, env->CSR_TLBRERA); + __func__, sys->CSR_TLBRERA); } else { - csr_pplv = FIELD_EX64(env->CSR_PRMD, CSR_PRMD, PPLV); - csr_pie = FIELD_EX64(env->CSR_PRMD, CSR_PRMD, PIE); + csr_pplv = FIELD_EX64(sys->CSR_PRMD, CSR_PRMD, PPLV); + csr_pie = FIELD_EX64(sys->CSR_PRMD, CSR_PRMD, PIE); - set_pc(env, env->CSR_ERA); + set_pc(env, sys->CSR_ERA); qemu_log_mask(CPU_LOG_INT, "%s: ERA " TARGET_FMT_lx "\n", - __func__, env->CSR_ERA); + __func__, sys->CSR_ERA); } - env->CSR_CRMD = FIELD_DP64(env->CSR_CRMD, CSR_CRMD, PLV, csr_pplv); - env->CSR_CRMD = FIELD_DP64(env->CSR_CRMD, CSR_CRMD, IE, csr_pie); + sys->CSR_CRMD = FIELD_DP64(sys->CSR_CRMD, CSR_CRMD, PLV, csr_pplv); + sys->CSR_CRMD = FIELD_DP64(sys->CSR_CRMD, CSR_CRMD, IE, csr_pie); env->lladdr = 1; }
diff --git a/target/loongarch/tcg/tcg_cpu.c b/target/loongarch/tcg/tcg_cpu.c index 31d3db6..66b3f45 100644 --- a/target/loongarch/tcg/tcg_cpu.c +++ b/target/loongarch/tcg/tcg_cpu.c
@@ -77,34 +77,35 @@ static void loongarch_cpu_do_interrupt(CPUState *cs) { CPULoongArchState *env = cpu_env(cs); + CPUSysState *sys = env_sys(env); bool update_badinstr = 1; int cause = -1; - bool tlbfill = FIELD_EX64(env->CSR_TLBRERA, CSR_TLBRERA, ISTLBR); - uint32_t vec_size = FIELD_EX64(env->CSR_ECFG, CSR_ECFG, VS); + bool tlbfill = FIELD_EX64(sys->CSR_TLBRERA, CSR_TLBRERA, ISTLBR); + uint32_t vec_size = FIELD_EX64(sys->CSR_ECFG, CSR_ECFG, VS); uint64_t last_pc = env->pc; if (cs->exception_index != EXCCODE_INT) { qemu_log_mask(CPU_LOG_INT, "%s enter: pc " TARGET_FMT_lx " ERA " TARGET_FMT_lx " TLBRERA " TARGET_FMT_lx " exception: %d (%s)\n", - __func__, env->pc, env->CSR_ERA, env->CSR_TLBRERA, + __func__, env->pc, sys->CSR_ERA, sys->CSR_TLBRERA, cs->exception_index, loongarch_exception_name(cs->exception_index)); } switch (cs->exception_index) { case EXCCODE_DBP: - env->CSR_DBG = FIELD_DP64(env->CSR_DBG, CSR_DBG, DCL, 1); - env->CSR_DBG = FIELD_DP64(env->CSR_DBG, CSR_DBG, ECODE, 0xC); + sys->CSR_DBG = FIELD_DP64(sys->CSR_DBG, CSR_DBG, DCL, 1); + sys->CSR_DBG = FIELD_DP64(sys->CSR_DBG, CSR_DBG, ECODE, 0xC); goto set_DERA; set_DERA: - env->CSR_DERA = env->pc; - env->CSR_DBG = FIELD_DP64(env->CSR_DBG, CSR_DBG, DST, 1); - set_pc(env, env->CSR_EENTRY + 0x480); + sys->CSR_DERA = env->pc; + sys->CSR_DBG = FIELD_DP64(sys->CSR_DBG, CSR_DBG, DST, 1); + set_pc(env, sys->CSR_EENTRY + 0x480); break; case EXCCODE_INT: - if (FIELD_EX64(env->CSR_DBG, CSR_DBG, DST)) { - env->CSR_DBG = FIELD_DP64(env->CSR_DBG, CSR_DBG, DEI, 1); + if (FIELD_EX64(sys->CSR_DBG, CSR_DBG, DST)) { + sys->CSR_DBG = FIELD_DP64(sys->CSR_DBG, CSR_DBG, DEI, 1); goto set_DERA; } QEMU_FALLTHROUGH; @@ -115,7 +116,7 @@ update_badinstr = 0; break; case EXCCODE_BCE: - env->CSR_BADV = env->pc; + sys->CSR_BADV = env->pc; QEMU_FALLTHROUGH; case EXCCODE_SYS: case EXCCODE_BRK: @@ -142,35 +143,35 @@ if (update_badinstr) { MemOpIdx oi = make_memop_idx(MO_LEUL, cpu_mmu_index(cs, true)); - env->CSR_BADI = cpu_ldl_code_mmu(env, env->pc, oi, 0); + sys->CSR_BADI = cpu_ldl_code_mmu(env, env->pc, oi, 0); } /* Save PLV and IE */ if (tlbfill) { - env->CSR_TLBRPRMD = FIELD_DP64(env->CSR_TLBRPRMD, CSR_TLBRPRMD, PPLV, - FIELD_EX64(env->CSR_CRMD, + sys->CSR_TLBRPRMD = FIELD_DP64(sys->CSR_TLBRPRMD, CSR_TLBRPRMD, PPLV, + FIELD_EX64(sys->CSR_CRMD, CSR_CRMD, PLV)); - env->CSR_TLBRPRMD = FIELD_DP64(env->CSR_TLBRPRMD, CSR_TLBRPRMD, PIE, - FIELD_EX64(env->CSR_CRMD, CSR_CRMD, IE)); + sys->CSR_TLBRPRMD = FIELD_DP64(sys->CSR_TLBRPRMD, CSR_TLBRPRMD, PIE, + FIELD_EX64(sys->CSR_CRMD, CSR_CRMD, IE)); /* set the DA mode */ - env->CSR_CRMD = FIELD_DP64(env->CSR_CRMD, CSR_CRMD, DA, 1); - env->CSR_CRMD = FIELD_DP64(env->CSR_CRMD, CSR_CRMD, PG, 0); - env->CSR_TLBRERA = FIELD_DP64(env->CSR_TLBRERA, CSR_TLBRERA, + sys->CSR_CRMD = FIELD_DP64(sys->CSR_CRMD, CSR_CRMD, DA, 1); + sys->CSR_CRMD = FIELD_DP64(sys->CSR_CRMD, CSR_CRMD, PG, 0); + sys->CSR_TLBRERA = FIELD_DP64(sys->CSR_TLBRERA, CSR_TLBRERA, PC, (env->pc >> 2)); } else { - env->CSR_ESTAT = FIELD_DP64(env->CSR_ESTAT, CSR_ESTAT, ECODE, + sys->CSR_ESTAT = FIELD_DP64(sys->CSR_ESTAT, CSR_ESTAT, ECODE, EXCODE_MCODE(cause)); - env->CSR_ESTAT = FIELD_DP64(env->CSR_ESTAT, CSR_ESTAT, ESUBCODE, + sys->CSR_ESTAT = FIELD_DP64(sys->CSR_ESTAT, CSR_ESTAT, ESUBCODE, EXCODE_SUBCODE(cause)); - env->CSR_PRMD = FIELD_DP64(env->CSR_PRMD, CSR_PRMD, PPLV, - FIELD_EX64(env->CSR_CRMD, CSR_CRMD, PLV)); - env->CSR_PRMD = FIELD_DP64(env->CSR_PRMD, CSR_PRMD, PIE, - FIELD_EX64(env->CSR_CRMD, CSR_CRMD, IE)); - env->CSR_ERA = env->pc; + sys->CSR_PRMD = FIELD_DP64(sys->CSR_PRMD, CSR_PRMD, PPLV, + FIELD_EX64(sys->CSR_CRMD, CSR_CRMD, PLV)); + sys->CSR_PRMD = FIELD_DP64(sys->CSR_PRMD, CSR_PRMD, PIE, + FIELD_EX64(sys->CSR_CRMD, CSR_CRMD, IE)); + sys->CSR_ERA = env->pc; } - env->CSR_CRMD = FIELD_DP64(env->CSR_CRMD, CSR_CRMD, PLV, 0); - env->CSR_CRMD = FIELD_DP64(env->CSR_CRMD, CSR_CRMD, IE, 0); + sys->CSR_CRMD = FIELD_DP64(sys->CSR_CRMD, CSR_CRMD, PLV, 0); + sys->CSR_CRMD = FIELD_DP64(sys->CSR_CRMD, CSR_CRMD, IE, 0); if (vec_size) { vec_size = (1 << vec_size) * 4; @@ -179,27 +180,27 @@ if (cs->exception_index == EXCCODE_INT) { /* Interrupt */ uint32_t vector = 0; - uint32_t pending = FIELD_EX64(env->CSR_ESTAT, CSR_ESTAT, IS); - pending &= FIELD_EX64(env->CSR_ECFG, CSR_ECFG, LIE); + uint32_t pending = FIELD_EX64(sys->CSR_ESTAT, CSR_ESTAT, IS); + pending &= FIELD_EX64(sys->CSR_ECFG, CSR_ECFG, LIE); /* Find the highest-priority interrupt. */ vector = 31 - clz32(pending); - set_pc(env, env->CSR_EENTRY + \ + set_pc(env, sys->CSR_EENTRY + \ (EXCCODE_EXTERNAL_INT + vector) * vec_size); qemu_log_mask(CPU_LOG_INT, "%s: PC " TARGET_FMT_lx " ERA " TARGET_FMT_lx " cause %d\n" " A " TARGET_FMT_lx " D " TARGET_FMT_lx " vector = %d ExC " TARGET_FMT_lx "ExS" TARGET_FMT_lx "\n", - __func__, env->pc, env->CSR_ERA, - cause, env->CSR_BADV, env->CSR_DERA, vector, - env->CSR_ECFG, env->CSR_ESTAT); + __func__, env->pc, sys->CSR_ERA, + cause, sys->CSR_BADV, sys->CSR_DERA, vector, + sys->CSR_ECFG, sys->CSR_ESTAT); qemu_plugin_vcpu_interrupt_cb(cs, last_pc); } else { if (tlbfill) { - set_pc(env, env->CSR_TLBRENTRY); + set_pc(env, sys->CSR_TLBRENTRY); } else { - set_pc(env, env->CSR_EENTRY + EXCODE_MCODE(cause) * vec_size); + set_pc(env, sys->CSR_EENTRY + EXCODE_MCODE(cause) * vec_size); } qemu_log_mask(CPU_LOG_INT, "%s: PC " TARGET_FMT_lx " ERA " TARGET_FMT_lx @@ -207,12 +208,12 @@ " EXCFG " TARGET_FMT_lx " BADVA " TARGET_FMT_lx "BADI " TARGET_FMT_lx " SYS_NUM " TARGET_FMT_lu " cpu %d asid " TARGET_FMT_lx "\n", __func__, env->pc, - tlbfill ? env->CSR_TLBRERA : env->CSR_ERA, - cause, tlbfill ? "(refill)" : "", env->CSR_ESTAT, - env->CSR_ECFG, - tlbfill ? env->CSR_TLBRBADV : env->CSR_BADV, - env->CSR_BADI, env->gpr[11], cs->cpu_index, - env->CSR_ASID); + tlbfill ? sys->CSR_TLBRERA : sys->CSR_ERA, + cause, tlbfill ? "(refill)" : "", sys->CSR_ESTAT, + sys->CSR_ECFG, + tlbfill ? sys->CSR_TLBRBADV : sys->CSR_BADV, + sys->CSR_BADI, env->gpr[11], cs->cpu_index, + sys->CSR_ASID); qemu_plugin_vcpu_exception_cb(cs, last_pc); } cs->exception_index = -1; @@ -226,8 +227,9 @@ uintptr_t retaddr) { CPULoongArchState *env = cpu_env(cs); + CPUSysState *sys = env_sys(env); - env->CSR_BADV = addr; + sys->CSR_BADV = addr; if (access_type == MMU_INST_FETCH) { do_raise_exception(env, EXCCODE_ADEF, retaddr); } else { @@ -238,9 +240,10 @@ static inline bool cpu_loongarch_hw_interrupts_enabled(CPULoongArchState *env) { bool ret = 0; + CPUSysState *sys = env_sys(env); - ret = (FIELD_EX64(env->CSR_CRMD, CSR_CRMD, IE) && - !(FIELD_EX64(env->CSR_DBG, CSR_DBG, DST))); + ret = (FIELD_EX64(sys->CSR_CRMD, CSR_CRMD, IE) && + !(FIELD_EX64(sys->CSR_DBG, CSR_DBG, DST))); return ret; } @@ -271,12 +274,13 @@ static TCGTBCPUState loongarch_get_tb_cpu_state(CPUState *cs) { CPULoongArchState *env = cpu_env(cs); + CPUSysState *sys = env_sys(env); uint32_t flags; - flags = env->CSR_CRMD & (R_CSR_CRMD_PLV_MASK | R_CSR_CRMD_PG_MASK); - flags |= FIELD_EX64(env->CSR_EUEN, CSR_EUEN, FPE) * HW_FLAGS_EUEN_FPE; - flags |= FIELD_EX64(env->CSR_EUEN, CSR_EUEN, SXE) * HW_FLAGS_EUEN_SXE; - flags |= FIELD_EX64(env->CSR_EUEN, CSR_EUEN, ASXE) * HW_FLAGS_EUEN_ASXE; + flags = sys->CSR_CRMD & (R_CSR_CRMD_PLV_MASK | R_CSR_CRMD_PG_MASK); + flags |= FIELD_EX64(sys->CSR_EUEN, CSR_EUEN, FPE) * HW_FLAGS_EUEN_FPE; + flags |= FIELD_EX64(sys->CSR_EUEN, CSR_EUEN, SXE) * HW_FLAGS_EUEN_SXE; + flags |= FIELD_EX64(sys->CSR_EUEN, CSR_EUEN, ASXE) * HW_FLAGS_EUEN_ASXE; flags |= is_va32(env) * HW_FLAGS_VA32; return (TCGTBCPUState){ .pc = env->pc, .flags = flags }; @@ -299,9 +303,10 @@ static int loongarch_cpu_mmu_index(CPUState *cs, bool ifetch) { CPULoongArchState *env = cpu_env(cs); + CPUSysState *sys = env_sys(env); - if (FIELD_EX64(env->CSR_CRMD, CSR_CRMD, PG)) { - return FIELD_EX64(env->CSR_CRMD, CSR_CRMD, PLV); + if (FIELD_EX64(sys->CSR_CRMD, CSR_CRMD, PG)) { + return FIELD_EX64(sys->CSR_CRMD, CSR_CRMD, PLV); } return MMU_DA_IDX; }
diff --git a/target/loongarch/tcg/tlb_helper.c b/target/loongarch/tcg/tlb_helper.c index 892e0eb..7623f4f 100644 --- a/target/loongarch/tcg/tlb_helper.c +++ b/target/loongarch/tcg/tlb_helper.c
@@ -36,16 +36,19 @@ bool check_ps(CPULoongArchState *env, uint8_t tlb_ps) { + CPUSysState *sys = env_sys(env); + if (tlb_ps >= 64) { return false; } - return BIT_ULL(tlb_ps) & (env->CSR_PRCFG2); + return BIT_ULL(tlb_ps) & (sys->CSR_PRCFG2); } static void raise_mmu_exception(CPULoongArchState *env, vaddr address, MMUAccessType access_type, TLBRet tlb_error) { CPUState *cs = env_cpu(env); + CPUSysState *sys = env_sys(env); switch (tlb_error) { default: @@ -62,7 +65,7 @@ } else if (access_type == MMU_INST_FETCH) { cs->exception_index = EXCCODE_PIF; } - env->CSR_TLBRERA = FIELD_DP64(env->CSR_TLBRERA, CSR_TLBRERA, ISTLBR, 1); + sys->CSR_TLBRERA = FIELD_DP64(sys->CSR_TLBRERA, CSR_TLBRERA, ISTLBR, 1); break; case TLBRET_INVALID: /* TLB match with no valid bit */ @@ -93,19 +96,19 @@ } if (tlb_error == TLBRET_NOMATCH) { - env->CSR_TLBRBADV = address; + sys->CSR_TLBRBADV = address; if (is_la64(env)) { - env->CSR_TLBREHI = FIELD_DP64(env->CSR_TLBREHI, CSR_TLBREHI_64, + sys->CSR_TLBREHI = FIELD_DP64(sys->CSR_TLBREHI, CSR_TLBREHI_64, VPPN, extract64(address, 13, 35)); } else { - env->CSR_TLBREHI = FIELD_DP64(env->CSR_TLBREHI, CSR_TLBREHI_32, + sys->CSR_TLBREHI = FIELD_DP64(sys->CSR_TLBREHI, CSR_TLBREHI_32, VPPN, extract64(address, 13, 19)); } } else { - if (!FIELD_EX64(env->CSR_DBG, CSR_DBG, DST)) { - env->CSR_BADV = address; + if (!FIELD_EX64(sys->CSR_DBG, CSR_DBG, DST)) { + sys->CSR_BADV = address; } - env->CSR_TLBEHI = address & (TARGET_PAGE_MASK << 1); + sys->CSR_TLBEHI = address & (TARGET_PAGE_MASK << 1); } } @@ -142,8 +145,9 @@ LoongArchTLB *tlb; uint16_t csr_asid, tlb_asid, tlb_g; uint8_t tlb_e; + CPUSysState *sys = env_sys(env); - csr_asid = FIELD_EX64(env->CSR_ASID, CSR_ASID, ASID); + csr_asid = FIELD_EX64(sys->CSR_ASID, CSR_ASID, ASID); tlb = &env->tlb[index]; tlb_e = FIELD_EX64(tlb->tlb_misc, TLB_MISC, E); if (!tlb_e) { @@ -165,25 +169,26 @@ { uint64_t lo0, lo1, csr_vppn; uint8_t csr_ps; + CPUSysState *sys = env_sys(env); - if (FIELD_EX64(env->CSR_TLBRERA, CSR_TLBRERA, ISTLBR)) { - csr_ps = FIELD_EX64(env->CSR_TLBREHI, CSR_TLBREHI, PS); + if (FIELD_EX64(sys->CSR_TLBRERA, CSR_TLBRERA, ISTLBR)) { + csr_ps = FIELD_EX64(sys->CSR_TLBREHI, CSR_TLBREHI, PS); if (is_la64(env)) { - csr_vppn = FIELD_EX64(env->CSR_TLBREHI, CSR_TLBREHI_64, VPPN); + csr_vppn = FIELD_EX64(sys->CSR_TLBREHI, CSR_TLBREHI_64, VPPN); } else { - csr_vppn = FIELD_EX64(env->CSR_TLBREHI, CSR_TLBREHI_32, VPPN); + csr_vppn = FIELD_EX64(sys->CSR_TLBREHI, CSR_TLBREHI_32, VPPN); } - lo0 = env->CSR_TLBRELO0; - lo1 = env->CSR_TLBRELO1; + lo0 = sys->CSR_TLBRELO0; + lo1 = sys->CSR_TLBRELO1; } else { - csr_ps = FIELD_EX64(env->CSR_TLBIDX, CSR_TLBIDX, PS); + csr_ps = FIELD_EX64(sys->CSR_TLBIDX, CSR_TLBIDX, PS); if (is_la64(env)) { - csr_vppn = FIELD_EX64(env->CSR_TLBEHI, CSR_TLBEHI_64, VPPN); + csr_vppn = FIELD_EX64(sys->CSR_TLBEHI, CSR_TLBEHI_64, VPPN); } else { - csr_vppn = FIELD_EX64(env->CSR_TLBEHI, CSR_TLBEHI_32, VPPN); + csr_vppn = FIELD_EX64(sys->CSR_TLBEHI, CSR_TLBEHI_32, VPPN); } - lo0 = env->CSR_TLBELO0; - lo1 = env->CSR_TLBELO1; + lo0 = sys->CSR_TLBELO0; + lo1 = sys->CSR_TLBELO1; } context->ps = csr_ps; @@ -198,6 +203,7 @@ uint64_t lo0, lo1, csr_vppn; uint16_t csr_asid; uint8_t csr_ps; + CPUSysState *sys = env_sys(env); csr_vppn = context->addr >> R_TLB_MISC_VPPN_SHIFT; csr_ps = context->ps; @@ -208,7 +214,7 @@ tlb->tlb_misc = FIELD_DP64(tlb->tlb_misc, TLB_MISC, PS, csr_ps); tlb->tlb_misc = FIELD_DP64(tlb->tlb_misc, TLB_MISC, VPPN, csr_vppn); tlb->tlb_misc = FIELD_DP64(tlb->tlb_misc, TLB_MISC, E, 1); - csr_asid = FIELD_EX64(env->CSR_ASID, CSR_ASID, ASID); + csr_asid = FIELD_EX64(sys->CSR_ASID, CSR_ASID, ASID); tlb->tlb_misc = FIELD_DP64(tlb->tlb_misc, TLB_MISC, ASID, csr_asid); tlb->tlb_entry0 = lo0; @@ -241,8 +247,9 @@ bool tlb_g; int i, compare_shift; uint64_t vpn, tlb_vppn; + CPUSysState *sys = env_sys(env); - stlb_ps = FIELD_EX64(env->CSR_STLBPS, CSR_STLBPS, PS); + stlb_ps = FIELD_EX64(sys->CSR_STLBPS, CSR_STLBPS, PS); vpn = (vaddr & TARGET_VIRT_MASK) >> (stlb_ps + 1); stlb_idx = vpn & 0xff; /* VA[25:15] <==> TLBIDX.index for 16KiB Page */ compare_shift = stlb_ps + 1 - R_TLB_MISC_VPPN_SHIFT; @@ -289,9 +296,10 @@ int csr_asid; tlb_match func; LoongArchTLB *tlb; + CPUSysState *sys = env_sys(env); func = tlb_match_any; - csr_asid = FIELD_EX64(env->CSR_ASID, CSR_ASID, ASID); + csr_asid = FIELD_EX64(sys->CSR_ASID, CSR_ASID, ASID); tlb = loongarch_tlb_search_cb(env, vaddr, csr_asid, func); if (tlb) { *index = tlb - env->tlb; @@ -304,20 +312,21 @@ void helper_tlbsrch(CPULoongArchState *env) { int index, match; + CPUSysState *sys = env_sys(env); - if (FIELD_EX64(env->CSR_TLBRERA, CSR_TLBRERA, ISTLBR)) { - match = loongarch_tlb_search(env, env->CSR_TLBREHI, &index); + if (FIELD_EX64(sys->CSR_TLBRERA, CSR_TLBRERA, ISTLBR)) { + match = loongarch_tlb_search(env, sys->CSR_TLBREHI, &index); } else { - match = loongarch_tlb_search(env, env->CSR_TLBEHI, &index); + match = loongarch_tlb_search(env, sys->CSR_TLBEHI, &index); } if (match) { - env->CSR_TLBIDX = FIELD_DP64(env->CSR_TLBIDX, CSR_TLBIDX, INDEX, index); - env->CSR_TLBIDX = FIELD_DP64(env->CSR_TLBIDX, CSR_TLBIDX, NE, 0); + sys->CSR_TLBIDX = FIELD_DP64(sys->CSR_TLBIDX, CSR_TLBIDX, INDEX, index); + sys->CSR_TLBIDX = FIELD_DP64(sys->CSR_TLBIDX, CSR_TLBIDX, NE, 0); return; } - env->CSR_TLBIDX = FIELD_DP64(env->CSR_TLBIDX, CSR_TLBIDX, NE, 1); + sys->CSR_TLBIDX = FIELD_DP64(sys->CSR_TLBIDX, CSR_TLBIDX, NE, 1); } void helper_tlbrd(CPULoongArchState *env) @@ -325,29 +334,30 @@ LoongArchTLB *tlb; int index; uint8_t tlb_ps, tlb_e; + CPUSysState *sys = env_sys(env); - index = FIELD_EX64(env->CSR_TLBIDX, CSR_TLBIDX, INDEX); + index = FIELD_EX64(sys->CSR_TLBIDX, CSR_TLBIDX, INDEX); tlb = &env->tlb[index]; tlb_ps = FIELD_EX64(tlb->tlb_misc, TLB_MISC, PS); tlb_e = FIELD_EX64(tlb->tlb_misc, TLB_MISC, E); if (!tlb_e) { /* Invalid TLB entry */ - env->CSR_TLBIDX = FIELD_DP64(env->CSR_TLBIDX, CSR_TLBIDX, NE, 1); - env->CSR_ASID = FIELD_DP64(env->CSR_ASID, CSR_ASID, ASID, 0); - env->CSR_TLBEHI = 0; - env->CSR_TLBELO0 = 0; - env->CSR_TLBELO1 = 0; - env->CSR_TLBIDX = FIELD_DP64(env->CSR_TLBIDX, CSR_TLBIDX, PS, 0); + sys->CSR_TLBIDX = FIELD_DP64(sys->CSR_TLBIDX, CSR_TLBIDX, NE, 1); + sys->CSR_ASID = FIELD_DP64(sys->CSR_ASID, CSR_ASID, ASID, 0); + sys->CSR_TLBEHI = 0; + sys->CSR_TLBELO0 = 0; + sys->CSR_TLBELO1 = 0; + sys->CSR_TLBIDX = FIELD_DP64(sys->CSR_TLBIDX, CSR_TLBIDX, PS, 0); } else { /* Valid TLB entry */ - env->CSR_TLBIDX = FIELD_DP64(env->CSR_TLBIDX, CSR_TLBIDX, NE, 0); - env->CSR_TLBIDX = FIELD_DP64(env->CSR_TLBIDX, CSR_TLBIDX, + sys->CSR_TLBIDX = FIELD_DP64(sys->CSR_TLBIDX, CSR_TLBIDX, NE, 0); + sys->CSR_TLBIDX = FIELD_DP64(sys->CSR_TLBIDX, CSR_TLBIDX, PS, (tlb_ps & 0x3f)); - env->CSR_TLBEHI = FIELD_EX64(tlb->tlb_misc, TLB_MISC, VPPN) << + sys->CSR_TLBEHI = FIELD_EX64(tlb->tlb_misc, TLB_MISC, VPPN) << R_TLB_MISC_VPPN_SHIFT; - env->CSR_TLBELO0 = tlb->tlb_entry0; - env->CSR_TLBELO1 = tlb->tlb_entry1; + sys->CSR_TLBELO0 = tlb->tlb_entry0; + sys->CSR_TLBELO1 = tlb->tlb_entry1; } } @@ -380,10 +390,11 @@ void helper_tlbwr(CPULoongArchState *env) { - int index = FIELD_EX64(env->CSR_TLBIDX, CSR_TLBIDX, INDEX); + CPUSysState *sys = env_sys(env); + int index = FIELD_EX64(sys->CSR_TLBIDX, CSR_TLBIDX, INDEX); MMUContext context; - if (FIELD_EX64(env->CSR_TLBIDX, CSR_TLBIDX, NE)) { + if (FIELD_EX64(sys->CSR_TLBIDX, CSR_TLBIDX, NE)) { invalidate_tlb(env, index); return; } @@ -400,10 +411,11 @@ uint16_t asid, tlb_asid, stlb_ps; LoongArchTLB *tlb; uint8_t tlb_e, tlb_g; + CPUSysState *sys = env_sys(env); /* Validity of stlb_ps is checked in helper_csrwr_stlbps() */ - stlb_ps = FIELD_EX64(env->CSR_STLBPS, CSR_STLBPS, PS); - asid = FIELD_EX64(env->CSR_ASID, CSR_ASID, ASID); + stlb_ps = FIELD_EX64(sys->CSR_STLBPS, CSR_STLBPS, PS); + asid = FIELD_EX64(sys->CSR_ASID, CSR_ASID, ASID); if (pagesize == stlb_ps) { /* Only write into STLB bits [47:13] */ address = addr & ~MAKE_64BIT_MASK(0, R_CSR_TLBEHI_64_VPPN_SHIFT); @@ -461,15 +473,16 @@ vaddr entryhi; int index, pagesize; MMUContext context; + CPUSysState *sys = env_sys(env); - if (FIELD_EX64(env->CSR_TLBRERA, CSR_TLBRERA, ISTLBR)) { - entryhi = env->CSR_TLBREHI; + if (FIELD_EX64(sys->CSR_TLBRERA, CSR_TLBRERA, ISTLBR)) { + entryhi = sys->CSR_TLBREHI; /* Validity of pagesize is checked in helper_ldpte() */ - pagesize = FIELD_EX64(env->CSR_TLBREHI, CSR_TLBREHI, PS); + pagesize = FIELD_EX64(sys->CSR_TLBREHI, CSR_TLBREHI, PS); } else { - entryhi = env->CSR_TLBEHI; + entryhi = sys->CSR_TLBEHI; /* Validity of pagesize is checked in helper_tlbrd() */ - pagesize = FIELD_EX64(env->CSR_TLBIDX, CSR_TLBIDX, PS); + pagesize = FIELD_EX64(sys->CSR_TLBIDX, CSR_TLBIDX, PS); } sptw_prepare_context(env, &context); @@ -483,9 +496,10 @@ LoongArchTLB *tlb; int i, index; uint16_t csr_asid, tlb_asid, tlb_g; + CPUSysState *sys = env_sys(env); - csr_asid = FIELD_EX64(env->CSR_ASID, CSR_ASID, ASID); - index = FIELD_EX64(env->CSR_TLBIDX, CSR_TLBIDX, INDEX); + csr_asid = FIELD_EX64(sys->CSR_ASID, CSR_ASID, ASID); + index = FIELD_EX64(sys->CSR_TLBIDX, CSR_TLBIDX, INDEX); if (index < LOONGARCH_STLB) { /* STLB. One line per operation */ @@ -515,8 +529,9 @@ void helper_tlbflush(CPULoongArchState *env) { int i, index; + CPUSysState *sys = env_sys(env); - index = FIELD_EX64(env->CSR_TLBIDX, CSR_TLBIDX, INDEX); + index = FIELD_EX64(sys->CSR_TLBIDX, CSR_TLBIDX, INDEX); if (index < LOONGARCH_STLB) { /* STLB. One line per operation */ @@ -711,6 +726,7 @@ uint64_t palen_mask = loongarch_palen_mask(env); uint64_t dir_base, dir_width; uint64_t val; + CPUSysState *sys = env_sys(env); if (unlikely((level == 0) || (level > 4))) { qemu_log_mask(LOG_GUEST_ERROR, @@ -732,7 +748,7 @@ } } - badvaddr = env->CSR_TLBRBADV; + badvaddr = sys->CSR_TLBRBADV; base = base & palen_mask; get_dir_base_width(env, &dir_base, &dir_width, level); index = (badvaddr >> dir_base) & ((1 << dir_width) - 1); @@ -747,10 +763,11 @@ { CPUState *cs = env_cpu(env); hwaddr phys, tmp0, ptindex, ptoffset0, ptoffset1; + CPUSysState *sys = env_sys(env); uint64_t pte_raw; uint64_t badv; - uint64_t ptbase = FIELD_EX64(env->CSR_PWCL, CSR_PWCL, PTBASE); - uint64_t ptwidth = FIELD_EX64(env->CSR_PWCL, CSR_PWCL, PTWIDTH); + uint64_t ptbase = FIELD_EX64(sys->CSR_PWCL, CSR_PWCL, PTBASE); + uint64_t ptwidth = FIELD_EX64(sys->CSR_PWCL, CSR_PWCL, PTWIDTH); uint64_t palen_mask = loongarch_palen_mask(env); uint64_t dir_base, dir_width; uint8_t ps; @@ -796,7 +813,7 @@ return; } } else { - badv = env->CSR_TLBRBADV; + badv = sys->CSR_TLBRBADV; base = base & palen_mask; @@ -812,11 +829,11 @@ } if (odd) { - env->CSR_TLBRELO1 = tmp0; + sys->CSR_TLBRELO1 = tmp0; } else { - env->CSR_TLBRELO0 = tmp0; + sys->CSR_TLBRELO0 = tmp0; } - env->CSR_TLBREHI = FIELD_DP64(env->CSR_TLBREHI, CSR_TLBREHI, PS, ps); + sys->CSR_TLBREHI = FIELD_DP64(sys->CSR_TLBREHI, CSR_TLBREHI, PS, ps); } static TLBRet loongarch_map_tlb_entry(CPULoongArchState *env,